Prechádzať zdrojové kódy

[fix] 修改page_heap

lvzeyue 1 rok pred
rodič
commit
9fafe123b9

+ 2 - 2
Project4/Project4.vcxproj

@@ -20,7 +20,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="main.cpp" />
-    <ClCompile Include="page.cc" />
+    <ClCompile Include="page_heap.cc" />
     <ClCompile Include="shm.cc" />
     <ClCompile Include="shm_helper.cc" />
     <ClCompile Include="shm_manager.cc" />
@@ -30,7 +30,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="catch.hpp" />
-    <ClInclude Include="page.h" />
+    <ClInclude Include="page_heap.h" />
     <ClInclude Include="shm.h" />
     <ClInclude Include="shm_config.h" />
     <ClInclude Include="shm_helper.h" />

+ 2 - 2
Project4/Project4.vcxproj.filters

@@ -36,7 +36,7 @@
     <ClCompile Include="size_map.cc">
       <Filter>源文件</Filter>
     </ClCompile>
-    <ClCompile Include="page.cc">
+    <ClCompile Include="page_heap.cc">
       <Filter>源文件</Filter>
     </ClCompile>
     <ClCompile Include="main.cpp">
@@ -62,7 +62,7 @@
     <ClInclude Include="size_map.h">
       <Filter>头文件</Filter>
     </ClInclude>
-    <ClInclude Include="page.h">
+    <ClInclude Include="page_heap.h">
       <Filter>头文件</Filter>
     </ClInclude>
     <ClInclude Include="type_helper.h">

+ 1 - 1
Project4/main.cpp

@@ -57,4 +57,4 @@ int main(int argc, char** argv)
     bg::detail::ShmObjectDelete(addr, real_size, path);
 
     return 0;
-}
+}

+ 0 - 863
Project4/page.cc

@@ -1,863 +0,0 @@
-#include "page.h"
-#include "shm_helper.h"
-#include "size_map.h"
-#include "shm_config.h"
-namespace bg
-{
-    namespace detail
-    {
-        PageHeap::PageHeap()
-        {
-        }
-
-        void PageHeap::DeallocateSpan(bg::detail::Span* s)
-        {
-            size_t m_start_page; // r12
-            size_t m_page_count; // r14
-            bg::detail::RadixTree<10ul, 10ul, 15ul>::NodeV1* v6; // rax
-            bg::detail::RadixTree<10ul, 10ul, 15ul>::NodeV2* v7; // rax
-            void** v8; // rdx
-            size_t v9; // rax
-            size_t v10; // rcx
-            uintptr_t* v11; // rdi
-            void* v12; // r8
-            unsigned __int64 v13; // r12
-            bg::detail::RadixTree<10ul, 10ul, 15ul>::NodeV1* v14; // rcx
-            bg::detail::RadixTree<10ul, 10ul, 15ul>::NodeV2* v15; // rdx
-            void** v16; // rdx
-            size_t v17; // rax
-            uintptr_t* v18; // rcx
-            void* v19; // rsi
-            size_t v20; // rax
-            bg::detail::Span* p_m_large_list; // rdx
-            bg::detail::Span* m_next; // rax
-
-            m_start_page = s->m_start_page;
-            s->m_in_use = 0;
-            m_page_count = s->m_page_count;
-            if(!m_start_page)
-                goto LABEL_9;
-            if(m_start_page - 1 > 0x7FFFFFFFFLL)
-            {
-                goto LABEL_24;
-            }
-            v6 = this->m_span_map.lv0[(m_start_page - 1) >> 25];
-            if(!v6 || (v7 = v6->lv1[((m_start_page - 1) >> 15) & 0x3FF]) == 0LL)
-            {
-LABEL_9:
-                v9 = s->m_page_count;
-                goto LABEL_10;
-            }
-            v8 = (void**)v7->lv2[((int64_t)m_start_page - 1) & 0x7FFF];
-            v9 = s->m_page_count;
-            if(v8 && *(char*)v8 != 1)
-            {
-                v10 = m_start_page - (size_t)v8[3];
-                v11 = (uintptr_t*)v8[4];
-                v12 = v8[5];
-                s->m_start_page = v10;
-                v9 = (size_t)v8[3] + m_page_count;
-                s->m_page_count = v9;
-                v11[5] = (uintptr_t)v12;
-                *((uintptr_t*)v8[5] + 4) = (uintptr_t)v11;
-                v8[4] = 0LL;
-                v8[5] = 0LL;
-                *v8 = this->m_span_allocator.m_free_list;
-                this->m_span_allocator.m_free_list = v8;
-                if(v10 <= 0x7FFFFFFFFLL)
-                {
-                    this->m_span_map.lv0[v10 >> 25]->lv1[(v10 >> 15) & 0x3FF]->lv2[v10 & 0x7FFF] = s;
-                    goto LABEL_10;
-                }
-
-LABEL_24:
-                v9 = s->m_page_count;
-            }
-LABEL_10:
-            v13 = m_page_count + m_start_page;
-            if(v13 <= 0x7FFFFFFFFLL)
-            {
-                v14 = this->m_span_map.lv0[v13 >> 25];
-                if(v14)
-                {
-                    v15 = v14->lv1[(v13 >> 15) & 0x3FF];
-                    if(v15)
-                    {
-                        v16 = (void**)v15->lv2[v13 & 0x7FFF];
-                        if(v16)
-                        {
-                            if(*(char*)v16 != 1)
-                            {
-                                v17 = (size_t)v16[3] + v9;
-                                v18 = (uintptr_t*)v16[4];
-                                v19 = v16[5];
-                                s->m_page_count = v17;
-                                v18[5] = (uintptr_t)v19;
-                                *((uintptr_t*)v16[5] + 4) = (uintptr_t)v18;
-                                v16[4] = 0LL;
-                                v16[5] = 0LL;
-                                *v16 = this->m_span_allocator.m_free_list;
-                                this->m_span_allocator.m_free_list = v16;
-                                if(v17)
-                                {
-                                    v20 = v17 + s->m_start_page - 1;
-                                }
-                                else
-                                {
-                                    SHM_ASSERT(m_page_count > 0);
-                                    v20 = s->m_start_page;
-                                }
-                                if(v20 > 0x7FFFFFFFFLL)
-                                {
-                                }
-                                else
-                                    this->m_span_map.lv0[v20 >> 25]->lv1[(v20 >> 15) & 0x3FF]->lv2[v20 & 0x7FFF] = s;
-                                v9 = s->m_page_count;
-                            }
-                        }
-                    }
-                }
-            }
-            p_m_large_list = &this->m_large_list;
-            if(v9 <= 0x7F)
-                p_m_large_list = &this->m_free_lists[v9];
-            m_next = p_m_large_list->m_next;
-            s->m_prev = p_m_large_list;
-            s->m_next = m_next;
-            p_m_large_list->m_next->m_prev = s;
-            p_m_large_list->m_next = s;
-        }
-
-        void PageHeap::RegisterSpan(bg::detail::Span* s)
-        {
-            int64_t v2; // rbx
-            size_t v3; // r13
-            size_t v4; // rax
-
-            v2 = 1LL;
-            v3 = s->m_page_count - 1;
-            if(v3 > 1)
-            {
-                do
-                {
-                    while(1)
-                    {
-                        v4 = s->m_start_page + v2;
-                        if(v4 > 0x7FFFFFFFFLL)
-                            break;
-                        ++v2;
-                        this->m_span_map.lv0[v4 >> 25]->lv1[(v4 >> 15) & 0x3FF]->lv2[v4 & 0x7FFF] = s;
-                        if(v3 == v2)
-                            return;
-                    }
-                    ++v2;
-
-                } while(v3 != v2);
-            }
-        }
-
-        bool PageHeap::GrowHeap(size_t page_count)
-        {
-            __int64 result; // rax
-            unsigned __int64 v3; // rdx
-            const char* RawMemory; // r9
-            size_t m_page_count; // rbx
-            size_t v8; // r14
-            unsigned __int64* v9; // r11
-            unsigned __int64 v10; // r12
-            __int16 v11; // r10
-            unsigned __int64 v12; // rdx
-            __int64 v13; // r10
-            uintptr_t* v14; // rax
-            void* v15; // rax
-            bg::detail::Span* m_free_list; // r12
-            unsigned __int64 v17; // rax
-            size_t m_free_left; // rax
-            bg::detail::Span* v19; // rax
-            __int64 v20; // rcx
-            __int64 v21; // [rsp-20h] [rbp-68h]
-            __int64 v22; // [rsp-20h] [rbp-68h]
-            unsigned __int64* v23; // [rsp-18h] [rbp-60h]
-            unsigned __int64* v24; // [rsp-18h] [rbp-60h]
-            const char* v25; // [rsp-10h] [rbp-58h]
-            const char* v26; // [rsp-10h] [rbp-58h]
-            const char* v27; // [rsp-8h] [rbp-50h]
-            size_t real_bytes; // [rsp+0h] [rbp-48h] BYREF
-            size_t v29; // [rsp+8h] [rbp-40h] BYREF
-
-            size_t page{};
-            result = 0LL;
-            if(page_count > 0x800000000LL)
-                return false;
-            if(page_count > 0x7F)
-            {
-                real_bytes = PAGES_TO_BYTES(page_count);
-                RawMemory = (const char*)bg::detail::ShmAllocateRawMemory(
-                                            (size_t*)&real_bytes,
-                                            0x2000);
-                if(!RawMemory)
-                    return false;
-            }
-            else
-            {
-                real_bytes = 0x100000LL;
-                RawMemory = (const char*)bg::detail::ShmAllocateRawMemory(
-                                        &real_bytes, 0x2000);
-                if(!RawMemory)
-                {
-                    real_bytes = PAGES_TO_BYTES(page_count);
-                    RawMemory = (const char*)bg::detail::ShmAllocateRawMemory(
-                                                &real_bytes, 0x2000);
-                    if(!RawMemory)
-                    {
-                        return false;
-                    }
-                }
-            }
-            page = (unsigned __int64)RawMemory >> 13;
-            m_page_count = BYTES_TO_PAGES(real_bytes);
-            v8 = ((unsigned __int64)RawMemory >> 13) + (real_bytes >> 13);
-            if(page >= v8)
-            {
-LABEL_23:
-                m_free_list = (bg::detail::Span*)this->m_span_allocator.m_free_list;
-                if(m_free_list)
-                {
-LABEL_25:
-                    new (m_free_list) bg::detail::Span();
-                    m_free_list->m_page_count = m_page_count;
-                    m_free_list->m_start_page = page;
-
-                    if(page > ShmConfig::MAX_PAGE_COUNT)
-                    {
-                        SHM_ASSERT(page < ShmConfig::MAX_PAGE_COUNT);
-                        m_page_count = m_free_list->m_page_count;
-
-                    }
-                    else
-                    {
-                        this->m_span_map.lv0[PTR_TO_LV0(page)]->lv1[PTR_TO_LV1(page)]->lv2[PTR_TO_LV0(page)] = m_free_list;
-                    }
-                    if(m_page_count > 1)
-                    {
-                        page = m_page_count + m_free_list->m_start_page - 1;
-                        if(page > ShmConfig::MAX_PAGE_COUNT)
-                        {
-                            SHM_ASSERT(page < ShmConfig::MAX_PAGE_COUNT);
-                        }
-                        else
-                        {
-                            this->m_span_map.lv0[PTR_TO_LV0(page)]->lv1[PTR_TO_LV1(page)]->lv2[PTR_TO_LV0(page)] = m_free_list;
-                        }
-                    }
-                    m_free_list->m_in_use = 1;
-                    this->DeallocateSpan(m_free_list);
-                    return true;
-                }
-                m_free_left = this->m_span_allocator.m_free_left;
-                if(m_free_left <= 0x37)
-                {
-                    v27 = RawMemory;
-                    v29 = 0x20000LL;
-                    v19 = (bg::detail::Span*)bg::detail::ShmAllocateRawMemory(
-                                                &v29,
-                                                0x20000LL);
-
-                    if(v19)
-                    {
-                        v20 = v29;
-                        m_free_list = v19;
-                        this->m_span_allocator.m_free_area = (char*)&v19[1];
-                        this->m_span_allocator.m_free_left = v20 - 56;
-                        goto LABEL_25;
-                    }
-                }
-                else
-                {
-                    m_free_list = (bg::detail::Span*)this->m_span_allocator.m_free_area;
-                    this->m_span_allocator.m_free_left = m_free_left - 56;
-                    this->m_span_allocator.m_free_area = (char*)&m_free_list[1];
-                    if(m_free_list)
-                        goto LABEL_25;
-                }
-
-                return false;
-            }
-            if((unsigned __int64)RawMemory >> 48)
-            {
-                goto FAIL;
-            }
-            v3 = (unsigned __int64)RawMemory >> 13;
-            do
-            {
-                v9 = (unsigned __int64*)&this->m_span_map.lv0[v3 >> 25];
-                v10 = v3 >> 15;
-                v11 = v3 >> 15;
-                v12 = *v9;
-                v13 = v11 & 0x3FF;
-                if(m_span_map.lv0[v3 >> 25])
-                {
-                    if(m_span_map.lv0[v3 >> 25]->lv1[v13])
-                    {
-                        goto LABEL_9;
-                    }
-                }
-                else
-                {
-                    v21 = v13;
-                    v23 = v9;
-                    v25 = RawMemory;
-                    v29 = sizeof(RadixTree::NodeV1);
-                    v14 = (uintptr_t*)bg::detail::ShmAllocateRawMemory(
-                                      &v29, sizeof(RadixTree::NodeV1));
-                    RawMemory = v25;
-                    v9 = v23;
-                    v13 = v21;
-                    if(!v14)
-                        break;
-                    m_span_map.lv0[v3 >> 25] = (RadixTree::NodeV1*)v14;
-
-                    new (v14) RadixTree();
-
-                    v12 = *v23;
-                    if(m_span_map.lv0[v3 >> 25]->lv1[v21])
-                        goto LABEL_9;
-                }
-                v22 = v13;
-                v24 = v9;
-                v26 = RawMemory;
-                v29 = sizeof(RadixTree::NodeV2);
-                v15 = (void*)bg::detail::ShmAllocateRawMemory(&v29, sizeof(RadixTree::NodeV2));
-                if(!v15)
-                    break;
-                m_span_map.lv0[v3 >> 25]->lv1[v22] = (RadixTree::NodeV2*)v15;
-                new (v15) RadixTree::NodeV2();
-
-LABEL_9:
-                v3 = (v10 + 1) << 15;
-                if(v3 >= v8)
-                    goto LABEL_23;
-            } while(!(v3 >> 35));
-FAIL:
-            SHM_ERROR("annot allocate enough space in span map, memory(%p, %#lx) leaked.", RawMemory, real_bytes);
-            return false;
-        }
-
-        bg::detail::Span* PageHeap::AllocateSpan(size_t page_count)
-        {
-            bg::detail::Span* p_m_large_list; // r12
-            bg::detail::Span* v4; // rdx
-            bg::detail::Span* v5; // rax
-            bg::detail::Span* v6; // rax
-            bg::detail::Span* v7; // r15
-            bg::detail::Span* v8; // rbx
-            size_t v9; // rdx
-            bg::detail::Span* v10; // rax
-            size_t v11; // rcx
-            unsigned __int64 v12; // rcx
-            bg::detail::Span* m_next; // rbx
-            bg::detail::Span* m_prev; // rax
-            size_t m_page_count; // r12
-            unsigned __int64 v17; // r12
-            bg::detail::Span* v18; // rdx
-            bg::detail::Span* v19; // rax
-            bg::detail::Span* v20; // rax
-            bg::detail::Span* v21; // rax
-            size_t v22; // r12
-            unsigned __int64 v23; // r12
-            bg::detail::Span* m_free_area; // r10
-            unsigned __int64 v25; // rdx
-            unsigned __int64 v26; // rax
-            bg::detail::Span* v27; // rax
-            size_t v28; // rax
-            bg::detail::Span* v29; // rax
-            size_t v30; // r12
-            unsigned __int64 v31; // r12
-            bg::detail::Span* m_free_list; // r15
-            unsigned __int64 m_start_page; // rdx
-            unsigned __int64 v34; // rax
-            bg::detail::Span* v35; // rax
-            bg::detail::Span* v36; // rdx
-            size_t v37; // rax
-            bg::detail::Span* v38; // r12
-            unsigned __int64 v39; // rdx
-            unsigned __int64 v40; // rax
-            bg::detail::Span* v41; // rax
-            size_t v42; // rax
-            unsigned __int64 v43; // rdx
-            unsigned __int64 v44; // rax
-            size_t v45; // rax
-            size_t m_free_left; // rax
-            size_t v47; // rax
-            size_t v48; // rax
-            bg::detail::Span* RawMemory; // rax
-            __int64 v50; // rsi
-            bg::detail::Span* v51; // rax
-            bg::detail::Span* v52; // rax
-            __int64 v53; // rsi
-            bg::detail::Span* v54; // rax
-            __int64 v55; // rsi
-            unsigned __int64 v56; // [rsp+0h] [rbp-50h]
-            bg::detail::Span* v57; // [rsp+8h] [rbp-48h]
-            unsigned __int64 v58; // [rsp+8h] [rbp-48h]
-            unsigned __int64 v59; // [rsp+8h] [rbp-48h]
-            unsigned __int64 v60; // [rsp+8h] [rbp-48h]
-            bg::detail::Span* v61; // [rsp+8h] [rbp-48h]
-            bg::detail::Span* v62; // [rsp+8h] [rbp-48h]
-            unsigned __int64 v63; // [rsp+8h] [rbp-48h]
-            bg::detail::Span* v64; // [rsp+8h] [rbp-48h]
-            __int64 v65[7]; // [rsp+18h] [rbp-38h] BYREF
-
-            p_m_large_list = &this->m_large_list;
-            if(page_count <= 0x7F)
-            {
-                v4 = &this->m_free_lists[page_count];
-                if(v4 == this->m_free_lists[page_count].m_next)
-                {
-                    p_m_large_list = &this->m_large_list;
-                    v5 = &this->m_free_lists[page_count + 1];
-                    while(v5 != p_m_large_list)
-                    {
-                        v4 = v5++;
-                        if(v4 != v5[-1].m_next)
-                            goto LABEL_19;
-                    }
-                    goto LABEL_6;
-                }
-LABEL_19:
-                m_next = v4->m_next;
-                m_prev = m_next->m_prev;
-                m_page_count = m_next->m_page_count;
-                m_prev->m_next = m_next->m_next;
-                v17 = m_page_count - page_count;
-                m_next->m_next->m_prev = m_prev;
-                m_next->m_prev = 0LL;
-                m_next->m_next = 0LL;
-                if(!v17)
-                {
-LABEL_20:
-                    m_next->m_in_use = 1;
-                    return m_next;
-                }
-                m_free_list = (bg::detail::Span*)this->m_span_allocator.m_free_list;
-                m_start_page = m_next->m_start_page;
-                if(m_free_list)
-                {
-                    this->m_span_allocator.m_free_list = *(void**)&m_free_list->m_in_use;
-                }
-                else
-                {
-                    m_free_left = this->m_span_allocator.m_free_left;
-                    if(m_free_left <= 0x37)
-                    {
-                        v58 = m_next->m_start_page;
-                        v65[0] = 0x20000LL;
-                        RawMemory = (bg::detail::Span*)bg::detail::ShmAllocateRawMemory((size_t*)v65,
-                                                          0x20000LL);
-                        if(!RawMemory)
-                            goto LABEL_20;
-                        v50 = v65[0];
-                        m_free_list = RawMemory;
-                        m_start_page = v58;
-                        this->m_span_allocator.m_free_area = (char*)&RawMemory[1];
-                        this->m_span_allocator.m_free_left = v50 - 56;
-                    }
-                    else
-                    {
-                        m_free_list = (bg::detail::Span*)this->m_span_allocator.m_free_area;
-                        this->m_span_allocator.m_free_left = m_free_left - 56;
-                        this->m_span_allocator.m_free_area = (char*)&m_free_list[1];
-                        if(!m_free_list)
-                            goto LABEL_20;
-                    }
-                }
-                m_free_list->m_in_use = 0;
-                m_free_list->m_size_class = -1;
-                m_free_list->m_used_count = 0LL;
-                m_free_list->m_start_page = m_start_page + page_count;
-                m_free_list->m_page_count = v17;
-                m_free_list->m_prev = 0LL;
-                m_free_list->m_next = 0LL;
-                m_free_list->m_chunk_list = 0LL;
-                if(m_start_page + page_count > 0x7FFFFFFFFLL)
-                {
-                    v17 = m_free_list->m_page_count;
-                }
-                else
-                {
-                    this->m_span_map.lv0[(m_start_page + page_count) >> 25]->lv1[((m_start_page + page_count) >> 15) & 0x3FF]->lv2[(m_start_page + page_count) & 0x7FFF] = m_free_list;
-                }
-                if(v17 <= 1
-                  || ((v34 = v17 + m_free_list->m_start_page - 1, v34 > 0x7FFFFFFFFLL)
-                   ? (bg::detail::Span*)(
-                   v17 = m_free_list->m_page_count)
-                   : (this->m_span_map.lv0[v34 >> 25]->lv1[((v17 + m_free_list->m_start_page - 1) >> 15) & 0x3FF]->lv2[v34 & 0x7FFF] = m_free_list),
-                   v35 = &this->m_large_list,
-                   v17 <= 0x7F))
-                {
-                    v35 = &this->m_free_lists[v17];
-                }
-                v36 = v35->m_next;
-                m_free_list->m_prev = v35;
-                m_free_list->m_next = v36;
-                v35->m_next->m_prev = m_free_list;
-                v35->m_next = m_free_list;
-                m_next->m_page_count = page_count;
-                if(page_count)
-                {
-                    v37 = page_count + m_next->m_start_page - 1;
-                }
-                else
-                {
-
-                    v37 = m_next->m_start_page;
-                }
-                if(v37 > 0x7FFFFFFFFLL)
-                {
-                }
-                else
-                    this->m_span_map.lv0[v37 >> 25]->lv1[(v37 >> 15) & 0x3FF]->lv2[v37 & 0x7FFF] = m_next;
-                goto LABEL_20;
-            }
-LABEL_6:
-            v6 = this->m_large_list.m_next;
-            v7 = p_m_large_list;
-            if(v6 == p_m_large_list)
-                goto LABEL_23;
-            v8 = 0LL;
-            do
-            {
-                while(1)
-                {
-                    v9 = v6->m_page_count;
-                    if(page_count <= v9)
-                    {
-                        if(!v8 || v9 < v8->m_page_count)
-                        {
-                            v8 = v6;
-                            goto LABEL_14;
-                        }
-                        if(v9 == v8->m_page_count && v6->m_start_page < v8->m_start_page)
-                            break;
-                    }
-                    v6 = v6->m_next;
-                    if(p_m_large_list == v6)
-                        goto LABEL_15;
-                }
-                v8 = v6;
-LABEL_14:
-                v6 = v6->m_next;
-            } while(p_m_large_list != v6);
-LABEL_15:
-            if(!v8)
-            {
-LABEL_23:
-                if(!bg::detail::PageHeap::GrowHeap(page_count))
-                {
-LABEL_24:
-                    return 0LL;
-                }
-                if(page_count <= 0x7F)
-                {
-                    v18 = &this->m_free_lists[page_count];
-                    if(v18 != this->m_free_lists[page_count].m_next)
-                    {
-LABEL_51:
-                        v8 = v18->m_next;
-                        v29 = v8->m_prev;
-                        v30 = v8->m_page_count;
-                        v29->m_next = v8->m_next;
-                        v31 = v30 - page_count;
-                        v8->m_next->m_prev = v29;
-                        v8->m_prev = 0LL;
-                        v8->m_next = 0LL;
-                        if(v31)
-                        {
-                            m_free_area = (bg::detail::Span*)this->m_span_allocator.m_free_list;
-                            v43 = v8->m_start_page;
-                            if(m_free_area)
-                            {
-                                this->m_span_allocator.m_free_list = *(void**)&m_free_area->m_in_use;
-                            }
-                            else
-                            {
-                                v48 = this->m_span_allocator.m_free_left;
-                                if(v48 <= 0x37)
-                                {
-                                    v60 = v8->m_start_page;
-                                    v65[0] = 0x20000LL;
-                                    v52 = (bg::detail::Span*)bg::detail::ShmAllocateRawMemory(
-                                                                (size_t*)v65,
-                                                                v43);
-                                    if(!v52)
-                                        goto LABEL_52;
-                                    v53 = v65[0];
-                                    m_free_area = v52;
-                                    v43 = v60;
-                                    this->m_span_allocator.m_free_area = (char*)&v52[1];
-                                    this->m_span_allocator.m_free_left = v53 - 56;
-                                }
-                                else
-                                {
-                                    m_free_area = (bg::detail::Span*)this->m_span_allocator.m_free_area;
-                                    this->m_span_allocator.m_free_left = v48 - 56;
-                                    this->m_span_allocator.m_free_area = (char*)&m_free_area[1];
-                                    if(!m_free_area)
-                                        goto LABEL_52;
-                                }
-                            }
-                            m_free_area->m_in_use = 0;
-                            m_free_area->m_size_class = -1;
-                            m_free_area->m_used_count = 0LL;
-                            m_free_area->m_start_page = v43 + page_count;
-                            m_free_area->m_page_count = v31;
-                            m_free_area->m_prev = 0LL;
-                            m_free_area->m_next = 0LL;
-                            m_free_area->m_chunk_list = 0LL;
-                            if(v43 + page_count > 0x7FFFFFFFFLL)
-                            {
-                                v57 = m_free_area;
-                                m_free_area = v57;
-                                v31 = v57->m_page_count;
-                            }
-                            else
-                            {
-                                this->m_span_map.lv0[(v43 + page_count) >> 25]->lv1[((v43 + page_count) >> 15) & 0x3FF]->lv2[(v43 + page_count) & 0x7FFF] = m_free_area;
-                            }
-                            if(v31 <= 1
-                              || ((v44 = v31 + m_free_area->m_start_page - 1, v44 > 0x7FFFFFFFFLL)
-                               ? (bg::detail::Span*)(v62 = m_free_area,
-                               m_free_area = v62,
-                               v31 = v62->m_page_count)
-                               : (this->m_span_map.lv0[v44 >> 25]->lv1[((v31 + m_free_area->m_start_page - 1) >> 15) & 0x3FF]->lv2[v44 & 0x7FFF] = m_free_area),
-                               v31 <= 0x7F))
-                            {
-                                v7 = &this->m_free_lists[v31];
-                            }
-                            goto LABEL_47;
-                        }
-LABEL_52:
-                        v8->m_in_use = 1;
-                        return v8;
-                    }
-                    v19 = &this->m_free_lists[page_count + 1];
-                    while(v19 != p_m_large_list)
-                    {
-                        v18 = v19++;
-                        if(v18 != v19[-1].m_next)
-                            goto LABEL_51;
-                    }
-                }
-                v20 = this->m_large_list.m_next;
-                if(p_m_large_list == v20)
-                    goto LABEL_24;
-                v8 = 0LL;
-                do
-                {
-                    while(page_count > v20->m_page_count || v8 && v20->m_start_page >= v8->m_start_page)
-                    {
-                        v20 = v20->m_next;
-                        if(p_m_large_list == v20)
-                            goto LABEL_37;
-                    }
-                    v8 = v20;
-                    v20 = v20->m_next;
-                } while(p_m_large_list != v20);
-LABEL_37:
-                if(!v8)
-                    goto LABEL_24;
-                v21 = v8->m_prev;
-                v22 = v8->m_page_count;
-                v21->m_next = v8->m_next;
-                v23 = v22 - page_count;
-                v8->m_next->m_prev = v21;
-                v8->m_prev = 0LL;
-                v8->m_next = 0LL;
-                if(v23)
-                {
-                    m_free_area = (bg::detail::Span*)this->m_span_allocator.m_free_list;
-                    v25 = v8->m_start_page;
-                    if(m_free_area)
-                    {
-                        this->m_span_allocator.m_free_list = *(void**)&m_free_area->m_in_use;
-                        goto LABEL_41;
-                    }
-                    v45 = this->m_span_allocator.m_free_left;
-                    if(v45 <= 0x37)
-                    {
-                        v63 = v8->m_start_page;
-                        v65[0] = 0x20000LL;
-                        v54 = (bg::detail::Span*)bg::detail::ShmAllocateRawMemory(
-                                                    (size_t*)v65,
-                                                    v25);
-                        if(v54)
-                        {
-                            v55 = v65[0];
-                            m_free_area = v54;
-                            v25 = v63;
-                            this->m_span_allocator.m_free_area = (char*)&v54[1];
-                            this->m_span_allocator.m_free_left = v55 - 56;
-                            goto LABEL_41;
-                        }
-                    }
-                    else
-                    {
-                        m_free_area = (bg::detail::Span*)this->m_span_allocator.m_free_area;
-                        this->m_span_allocator.m_free_left = v45 - 56;
-                        this->m_span_allocator.m_free_area = (char*)&m_free_area[1];
-                        if(m_free_area)
-                        {
-LABEL_41:
-                            m_free_area->m_in_use = 0;
-                            m_free_area->m_size_class = -1;
-                            m_free_area->m_used_count = 0LL;
-                            m_free_area->m_start_page = v25 + page_count;
-                            m_free_area->m_page_count = v23;
-                            m_free_area->m_prev = 0LL;
-                            m_free_area->m_next = 0LL;
-                            m_free_area->m_chunk_list = 0LL;
-                            if(v25 + page_count > 0x7FFFFFFFFLL)
-                            {
-                                v61 = m_free_area;
-                                m_free_area = v61;
-                                v23 = v61->m_page_count;
-                            }
-                            else
-                            {
-                                this->m_span_map.lv0[(v25 + page_count) >> 25]->lv1[((v25 + page_count) >> 15) & 0x3FF]->lv2[(v25 + page_count) & 0x7FFF] = m_free_area;
-                            }
-                            if(v23 <= 1
-                              || ((v26 = v23 + m_free_area->m_start_page - 1, v26 > 0x7FFFFFFFFLL)
-                               ? (bg::detail::Span*)(v64 = m_free_area,
-                               m_free_area = v64,
-                               v23 = v64->m_page_count)
-                               : (this->m_span_map.lv0[v26 >> 25]->lv1[((v23 + m_free_area->m_start_page - 1) >> 15) & 0x3FF]->lv2[v26 & 0x7FFF] = m_free_area),
-                               v23 <= 0x7F))
-                            {
-                                v7 = &this->m_free_lists[v23];
-                            }
-LABEL_47:
-                            v27 = v7->m_next;
-                            m_free_area->m_prev = v7;
-                            m_free_area->m_next = v27;
-                            v7->m_next->m_prev = m_free_area;
-                            v7->m_next = m_free_area;
-                            v8->m_page_count = page_count;
-                            if(page_count)
-                            {
-                                v28 = page_count + v8->m_start_page - 1;
-                            }
-                            else
-                            {
-                                v28 = v8->m_start_page;
-                            }
-                            if(v28 > 0x7FFFFFFFFLL)
-                            {
-                            }
-                            else
-                                this->m_span_map.lv0[v28 >> 25]->lv1[(v28 >> 15) & 0x3FF]->lv2[v28 & 0x7FFF] = v8;
-                            goto LABEL_52;
-                        }
-                    }
-                }
-                goto LABEL_52;
-            }
-            v10 = v8->m_prev;
-            v11 = v8->m_page_count;
-            v10->m_next = v8->m_next;
-            v12 = v11 - page_count;
-            v8->m_next->m_prev = v10;
-            v8->m_prev = 0LL;
-            v8->m_next = 0LL;
-            if(!v12)
-                goto LABEL_17;
-            v38 = (bg::detail::Span*)this->m_span_allocator.m_free_list;
-            v39 = v8->m_start_page;
-            if(v38)
-            {
-                this->m_span_allocator.m_free_list = *(void**)&v38->m_in_use;
-                goto LABEL_69;
-            }
-            v47 = this->m_span_allocator.m_free_left;
-            if(v47 <= 0x37)
-            {
-                v56 = v8->m_start_page;
-                v59 = v12;
-                v65[0] = 0x20000LL;
-                v51 = (bg::detail::Span*)bg::detail::ShmAllocateRawMemory(
-                                            (size_t*)v65,
-                                            v39);
-                if(v51)
-                {
-                    v38 = v51;
-                    v12 = v59;
-                    v39 = v56;
-                    this->m_span_allocator.m_free_area = (char*)&v51[1];
-                    this->m_span_allocator.m_free_left = v65[0] - 56;
-                    goto LABEL_69;
-                }
-            }
-            else
-            {
-                v38 = (bg::detail::Span*)this->m_span_allocator.m_free_area;
-                this->m_span_allocator.m_free_left = v47 - 56;
-                this->m_span_allocator.m_free_area = (char*)&v38[1];
-                if(v38)
-                {
-LABEL_69:
-                    v38->m_in_use = 0;
-                    v38->m_size_class = -1;
-                    v38->m_used_count = 0LL;
-                    v38->m_start_page = v39 + page_count;
-                    v38->m_page_count = v12;
-                    v38->m_prev = 0LL;
-                    v38->m_next = 0LL;
-                    v38->m_chunk_list = 0LL;
-                    if(v39 + page_count > 0x7FFFFFFFFLL)
-                    {
-                        v12 = v38->m_page_count;
-                    }
-                    else
-                    {
-                        this->m_span_map.lv0[(v39 + page_count) >> 25]->lv1[((v39 + page_count) >> 15) & 0x3FF]->lv2[(v39 + page_count) & 0x7FFF] = v38;
-                    }
-                    if(v12 <= 1
-                      || ((v40 = v12 + v38->m_start_page - 1, v40 > 0x7FFFFFFFFLL)
-                       ? (bg::detail::Span*)(
-                       v12 = v38->m_page_count)
-                       : (this->m_span_map.lv0[v40 >> 25]->lv1[((v12 + v38->m_start_page - 1) >> 15) & 0x3FF]->lv2[v40 & 0x7FFF] = v38),
-                       v12 <= 0x7F))
-                    {
-                        v7 = &this->m_free_lists[v12];
-                    }
-                    v41 = v7->m_next;
-                    v38->m_prev = v7;
-                    v38->m_next = v41;
-                    v7->m_next->m_prev = v38;
-                    v7->m_next = v38;
-                    v8->m_page_count = page_count;
-                    if(page_count)
-                    {
-                        v42 = page_count + v8->m_start_page - 1;
-                    }
-                    else
-                    {
-
-                        v42 = v8->m_start_page;
-                    }
-                    if(v42 > 0x7FFFFFFFFLL)
-                    {
-                    }
-                    else
-                        this->m_span_map.lv0[v42 >> 25]->lv1[(v42 >> 15) & 0x3FF]->lv2[v42 & 0x7FFF] = v8;
-                }
-            }
-LABEL_17:
-            v8->m_in_use = 1;
-            return v8;
-        }
-
-    }
-}
-
-

+ 326 - 0
Project4/page_heap.cc

@@ -0,0 +1,326 @@
+#include "page_heap.h"
+#include "shm_helper.h"
+#include "size_map.h"
+#include "shm_config.h"
+namespace bg
+{
+    namespace detail
+    {
+        PageHeap::PageHeap()
+        {
+        }
+
+        bg::detail::Span* PageHeap::GetSpanMap(size_t start_page)
+        {
+            SHM_ASSERT_RETURN_NULL(start_page <= ShmConfig::MAX_PAGE_COUNT);
+
+            auto node1 = m_span_map.lv0[PTR_TO_LV0(start_page)];
+            if(node1 == nullptr)
+            {
+                return nullptr;
+            }
+
+            auto node2 = node1->lv1[PTR_TO_LV1(start_page)];
+            if(node2 == nullptr)
+            {
+                return nullptr;
+            }
+
+            auto node3 = node2->lv2[PTR_TO_LV2(start_page)];
+            return node3;
+        }
+
+        bool PageHeap::SetSpanMap(size_t page, bg::detail::Span* span)
+        {
+            SHM_ASSERT_RETURN_FALSE(span->m_start_page <= ShmConfig::MAX_PAGE_COUNT);
+            m_span_map.lv0[PTR_TO_LV0(page)]->lv1[PTR_TO_LV1(page)]->lv2[PTR_TO_LV2(page)] = span;
+            return true;
+        }
+
+        void PageHeap::DeallocateSpan(bg::detail::Span* s)
+        {
+            bg::detail::Span* pre_span = GetSpanMap(s->m_start_page - 1);
+            if(pre_span && !pre_span->m_in_use)
+            {
+                s->m_start_page -= pre_span->m_page_count;
+                s->m_page_count += pre_span->m_page_count;
+
+
+                pre_span->RemoveNextSpan();
+
+                *(void**)pre_span = m_span_allocator.m_free_list;
+                m_span_allocator.m_free_list = pre_span;
+                SetSpanMap(s->m_start_page, s);
+            }
+
+            bg::detail::Span* next_span = GetSpanMap(s->m_start_page + s->m_page_count);
+            if(next_span && next_span->m_in_use != true)
+            {
+                s->m_page_count += next_span->m_page_count;
+
+                next_span->RemoveNextSpan();
+
+                *(void**)next_span = m_span_allocator.m_free_list;
+
+                m_span_allocator.m_free_list = next_span;
+
+                if(s->m_page_count)
+                {
+                    SetSpanMap(s->m_page_count + s->m_start_page - 1, s);
+                }
+            }
+
+            bg::detail::Span* p_list;
+            p_list = &m_large_list;
+            if(s->m_page_count <= 0x7F)
+            {
+                p_list = &m_free_lists[s->m_page_count];
+            }
+            p_list->InstertNextSpan(s);
+
+        }
+
+        void PageHeap::RegisterSpan(bg::detail::Span* span)
+        {
+            size_t start = 1ll;
+            size_t end = span->m_page_count - 1;
+            while(end > start)
+            {
+                size_t index = span->m_start_page + start;
+                SetSpanMap(index, span);
+                ++start;
+            }
+        }
+
+        bool PageHeap::GrowHeap(size_t page_count)
+        {
+            size_t real_bytes{};
+            size_t page_start{};
+            void* rawmemoey{};
+            if(page_count > ShmConfig::MAX_PAGE_COUNT)
+            {
+                return false;
+            }
+
+            if(page_count > 0x7F)
+            {
+                real_bytes = PAGES_TO_BYTES(page_count);
+                rawmemoey = bg::detail::ShmAllocateRawMemory(&real_bytes, PAGE_BYTES);
+                if(!rawmemoey)
+                {
+                    return false;
+                }
+            }
+            else
+            {
+                real_bytes = 0x100000LL;
+                rawmemoey = bg::detail::ShmAllocateRawMemory(&real_bytes, PAGE_BYTES);
+                if(!rawmemoey)
+                {
+                    real_bytes = PAGES_TO_BYTES(page_count);
+                    rawmemoey = bg::detail::ShmAllocateRawMemory(&real_bytes, PAGE_BYTES);
+                    if(!rawmemoey)
+                    {
+                        return false;
+                    }
+                }
+            }
+            page_start = BYTES_TO_PAGES((int64_t)rawmemoey);
+            size_t real_pages = BYTES_TO_PAGES(real_bytes);
+            size_t page_end = page_start + real_pages;
+
+            if((int64_t)rawmemoey >> 48)
+            {
+                SHM_ERROR("annot allocate enough space in span map, memory(%p, %#lx) leaked.", rawmemoey, real_bytes);
+                return false;
+            }
+
+            for(size_t index = page_start; index < page_end; ++index)
+            {
+                size_t lv0_index = PTR_TO_LV0(index);
+                size_t lv1_index = PTR_TO_LV1(index);
+                size_t lv2_index = PTR_TO_LV2(index);
+                if(m_span_map.lv0[lv0_index] && m_span_map.lv0[lv0_index]->lv1[lv1_index])
+                {
+                    continue;
+                }
+                else
+                {
+                    size_t node1_size = sizeof(RadixTree::NodeV1);
+                    RadixTree::NodeV1* p_node1 = (RadixTree::NodeV1*)bg::detail::ShmAllocateRawMemory(
+                        &node1_size, sizeof(RadixTree::NodeV1));
+
+                    if(!p_node1)
+                    {
+                        break;
+                    }
+                    m_span_map.lv0[lv0_index] = p_node1;
+                    new (p_node1) RadixTree::NodeV1();
+
+                }
+                size_t node2_size = sizeof(RadixTree::NodeV2);
+                RadixTree::NodeV2* p_node2 = (RadixTree::NodeV2*)bg::detail::ShmAllocateRawMemory(&node2_size, sizeof(RadixTree::NodeV2));
+                if(!p_node2)
+                {
+                    break;
+                }
+                m_span_map.lv0[lv0_index]->lv1[lv1_index] = p_node2;
+                new (p_node2) RadixTree::NodeV2();
+                m_span_map.lv0[lv0_index]->lv1[lv1_index]->lv2[lv2_index];
+            }
+
+
+            bg::detail::Span* free_span = GetNewSpan();
+            if(!free_span)
+            {
+                SHM_ERROR("cannot allocate new span, memory(%p, %#lx) leaked.", rawmemoey, real_bytes);
+                return false;
+            }
+            new (free_span) Span(page_start, page_count);
+
+            SetSpanMap(page_start, free_span);
+
+            if(real_pages > 1)
+            {
+                SetSpanMap(page_end - 1, free_span);
+            }
+            free_span->m_in_use = 1;
+            this->DeallocateSpan(free_span);
+            return true;
+        }
+
+        bg::detail::Span* PageHeap::AllocateSpan(size_t page_count)
+        {
+            auto span = GetLastSpan(page_count);
+            if(!span)
+            {
+                if(!GrowHeap(page_count) || !(span = GetLastSpan(page_count)))
+                {
+                    SHM_ERROR("cannot allocate span, page count: %lu.", page_count);
+                    return nullptr;
+                }
+
+            }
+            span->m_prev->RemoveNextSpan();
+
+            do
+            {
+                int64_t diff = page_count - span->m_page_count;
+                if(diff == 0)
+                {
+                    break;
+                }
+
+                Span* free_list = GetNewSpan();
+                if(!free_list)
+                {
+                    break;
+                }
+                size_t start_page = span->m_start_page + page_count;
+                new (free_list) Span(start_page, diff);
+                SetSpanMap(start_page, free_list);
+
+                Span* list;
+                if(diff <= 1 || SetSpanMap(start_page + diff - 1, free_list), list = &m_large_list, diff <= 0x7f)
+                {
+                    list = &m_free_lists[diff];
+                }
+
+                list->InstertNextSpan(free_list);
+
+                span->m_page_count = page_count;
+                if(page_count)
+                {
+                    SetSpanMap(page_count + span->m_start_page - 1, free_list);
+                }
+            } while(false);
+
+            span->m_in_use = 1;
+            return span;
+        }
+
+        bg::detail::Span* PageHeap::GetNewSpan()
+        {
+            bg::detail::Span* free_span = (bg::detail::Span*)m_span_allocator.m_free_list;
+            if(free_span)
+            {
+                m_span_allocator.m_free_list = (void*)&free_span->m_in_use;
+                return free_span;
+            }
+            size_t free_left = this->m_span_allocator.m_free_left;
+            if(free_left <= 0x37)
+            {
+                size_t spans_bytes = FREE_AREA_SIZE;
+                bg::detail::Span* spans = (bg::detail::Span*)bg::detail::ShmAllocateRawMemory(&spans_bytes, PAGE_BYTES);
+
+                if(spans)
+                {
+                    free_span = spans;
+                    this->m_span_allocator.m_free_area = (char*)&spans[1];
+                    this->m_span_allocator.m_free_left = spans_bytes - sizeof(bg::detail::Span);
+                    return free_span;
+                }
+            }
+            else
+            {
+                free_span = (bg::detail::Span*)this->m_span_allocator.m_free_area;
+                this->m_span_allocator.m_free_left -= sizeof(bg::detail::Span);
+                this->m_span_allocator.m_free_area += sizeof(bg::detail::Span);
+                if(free_span)
+                {
+                    return free_span;
+                }
+            }
+
+            return nullptr;
+        }
+
+        bg::detail::Span* PageHeap::GetLastSpan(size_t page_count)
+        {
+            if(page_count <= 0x7f)
+            {
+                Span* next_span = &m_free_lists[page_count];
+                Span* free_span = next_span->m_next;
+                if(next_span == next_span->m_next)
+                {
+                    for(&m_free_lists[page_count + 1]; next_span != &m_large_list; ++next_span)
+                    {
+                        if(next_span->m_next != next_span)
+                        {
+                            free_span = next_span->m_next;
+                            break;
+                        }
+                    }
+                }
+                if(free_span != free_span->m_next)
+                {
+                    return free_span;
+                }
+            }
+
+            if(m_large_list.m_next != &m_large_list)
+            {
+                Span* next_span = m_large_list.m_next;
+                Span* free_span = nullptr;
+
+                for(; &m_large_list == next_span; next_span = next_span->m_next)
+                {
+                    if(page_count > next_span->m_page_count)
+                    {
+                        continue;
+                    }
+                    if(!free_span || next_span->m_page_count < free_span->m_page_count ||
+                       (next_span->m_page_count == free_span->m_page_count && next_span->m_start_page < free_span->m_start_page))
+                    {
+                        free_span = next_span;
+                    }
+
+                }
+                return free_span;
+            }
+            return nullptr;
+        }
+    }
+
+
+}

+ 30 - 0
Project4/page.h → Project4/page_heap.h

@@ -9,6 +9,28 @@ namespace bg
     {
         struct Span
         {
+            Span() = default;
+            Span(size_t start_page, size_t page_count) : m_start_page(start_page), m_page_count(page_count) {}
+
+            void RemoveNextSpan()
+            {
+                auto next_span = m_next;
+
+                m_next = next_span->m_next;
+                next_span->m_next->m_prev = next_span->m_prev;
+
+                next_span->m_prev = nullptr;
+                next_span->m_next = nullptr;
+            }
+
+            void InstertNextSpan(Span* span)
+            {
+                span->m_prev = m_next->m_prev;
+                span->m_next = m_next;
+                m_next->m_prev = span;
+                m_next = span;
+            }
+
             bool m_in_use{};
             unsigned char m_size_class{255};
             size_t m_used_count{};
@@ -50,6 +72,10 @@ namespace bg
         public:
             PageHeap();
 
+            bg::detail::Span* GetSpanMap(size_t start_page);
+
+            bool SetSpanMap(size_t page, bg::detail::Span* span);
+
             void DeallocateSpan(bg::detail::Span* s);
 
             void RegisterSpan(bg::detail::Span* s);
@@ -58,6 +84,10 @@ namespace bg
 
             bg::detail::Span* AllocateSpan(size_t page_count);
 
+            bg::detail::Span* GetNewSpan();
+
+            bg::detail::Span* GetLastSpan(size_t page_count);
+
             using  RadixTree = RadixTree<10ul, 10ul, 15ul>;
             RadixTree m_span_map;
             MetadataAllocator<bg::detail::Span> m_span_allocator;

+ 2 - 1
Project4/shm_config.h

@@ -3,13 +3,14 @@
 #define SMALL_CALIGNMENT 8			
 #define SMALL_BYTES_TO_INDEX(bytes) ((bytes + 7) >> 3)        // 小字节获取class index
 #define BIG_BYTES_TO_INDEX(bytes) ((bytes + (BIG_CALIGNMENT - 1)) >> 7)      // 大字节获取class index
-#define CALIGNMENT_MAX_BYTES 0x2000LL                         // 对齐最大字节数
+#define PAGE_BYTES 0x2000LL                         // 一页字节
 #define BYTES_COMP_VALUE 0x400                                // 大小字节数
 #define CLASS_TOTAL_BYTES 65536                               
 #define CLASS_MAX_BYTES 0x40000                               // class 最大字节数
 #define MAX_CLASSS  32										  
 #define CLASS_MAX_COUNT 87									  // 总共类数量
 #define PAGE_RIGHT_BIT 13								  // 总共类数量
+#define FREE_AREA_SIZE 0x20000LL                                
 
 #define BYTES_TO_PAGES(bytes)    ((bytes) >> 13)
 #define PAGES_TO_BYTES(page)    ((page) << 13)

+ 1 - 1
Project4/shm_manager.h

@@ -1,6 +1,6 @@
 #pragma once
 #include "shm.h"
-#include "page.h"
+#include "page_heap.h"
 #include "size_map.h"
 
 

+ 3 - 3
Project4/size_map.cc

@@ -29,7 +29,7 @@ namespace bg
                 size_t alig_page_byte = 0LL;
                 do
                 {
-                    for(alig_page_byte += CALIGNMENT_MAX_BYTES; alig_page_byte % size > alig_page_byte >> 3; alig_page_byte += CALIGNMENT_MAX_BYTES);
+                    for(alig_page_byte += PAGE_BYTES; alig_page_byte % size > alig_page_byte >> 3; alig_page_byte += PAGE_BYTES);
                 } while(alig_page_byte / size < class_cnt);
 
                 size_t  page_cnt = BYTES_TO_PAGES(alig_page_byte);
@@ -133,8 +133,8 @@ FAIL:
             size_t result; // rax
 
             char bit{};
-            result = CALIGNMENT_MAX_BYTES;
-            if(bytes < (CALIGNMENT_MAX_BYTES << 4))
+            result = PAGE_BYTES;
+            if(bytes < (PAGE_BYTES << 4))
             {
                 if(bytes <= 0x7F)
                 {