소스 검색

优化page init过程,提升启动速度

shaojinchun 4 년 전
부모
커밋
2664bdadd7
2개의 변경된 파일66개의 추가작업 그리고 12개의 파일을 삭제
  1. 61 12
      libcpu/arm/cortex-a/page.c
  2. 5 0
      libcpu/arm/cortex-a/start_gcc.S

+ 61 - 12
libcpu/arm/cortex-a/page.c

@@ -37,12 +37,50 @@ static size_t page_nr;
 
 
 static struct page *page_list[ARCH_PAGE_LIST_SIZE];
 static struct page *page_list[ARCH_PAGE_LIST_SIZE];
 
 
+RT_WEAK int rt_clz(size_t n)
+{
+    int bits = sizeof(size_t) * 8;
+
+    n |= (n >> 1);
+    n |= (n >> 2);
+    n |= (n >> 4);
+    n |= (n >> 8);
+    n |= (n >> 16);
+
+#ifdef ARCH_CPU_64BIT
+    n |= (n >> 32);
+
+    n = (n & 0x5555555555555555UL) + ((n >> 1) & 0x5555555555555555UL);
+    n = (n & 0x3333333333333333UL) + ((n >> 2) & 0x3333333333333333UL);
+    n = (n & 0x0707070707070707UL) + ((n >> 4) & 0x0707070707070707UL);
+    n = (n & 0x000f000f000f000fUL) + ((n >> 8) & 0x000f000f000f000fUL);
+    n = (n & 0x0000001f0000001fUL) + ((n >> 16) & 0x0000001f0000001fUL);
+    n = (n & 0x000000000000003fUL) + ((n >> 32) & 0x000000000000003fUL);
+#else
+    n = (n & 0x55555555UL) + ((n >> 1) & 0x55555555UL);
+    n = (n & 0x33333333UL) + ((n >> 2) & 0x33333333UL);
+    n = (n & 0x07070707UL) + ((n >> 4) & 0x07070707UL);
+    n = (n & 0x000f000fUL) + ((n >> 8) & 0x000f000fUL);
+    n = (n & 0x0000001fUL) + ((n >> 16) & 0x0000001fUL);
+#endif
+    return bits - n;
+}
+
+RT_WEAK int rt_ctz(size_t n)
+{
+    int ret = sizeof(size_t) * 8;
+
+    if (n)
+    {
+        ret -= (rt_clz(n ^ (n - 1)) + 1);
+    }
+    return ret;
+}
+
 size_t rt_page_bits(size_t size)
 size_t rt_page_bits(size_t size)
 {
 {
-    int bit;
+    int bit = sizeof(size_t) * 8 - rt_clz(size) - 1;
 
 
-    bit = __builtin_clz(size);
-    bit = (31 - bit);
     if ((size ^ (1UL << bit)) != 0)
     if ((size ^ (1UL << bit)) != 0)
     {
     {
         bit++;
         bit++;
@@ -145,6 +183,7 @@ static int _pages_free(struct page *p, uint32_t size_bits)
     struct page *buddy;
     struct page *buddy;
 
 
     RT_ASSERT(p->ref_cnt > 0);
     RT_ASSERT(p->ref_cnt > 0);
+    RT_ASSERT(p->size_bits == ARCH_ADDRESS_WIDTH_BITS);
 
 
     p->ref_cnt--;
     p->ref_cnt--;
     if (p->ref_cnt != 0)
     if (p->ref_cnt != 0)
@@ -205,6 +244,7 @@ static struct page *_pages_alloc(uint32_t size_bits)
             level--;
             level--;
         }
         }
     }
     }
+    p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
     p->ref_cnt = 1;
     p->ref_cnt = 1;
     return p;
     return p;
 }
 }
@@ -317,6 +357,8 @@ void rt_page_init(rt_region_t reg)
         LOG_D("total = 0x%08x\n", total);
         LOG_D("total = 0x%08x\n", total);
         LOG_D("mnr = 0x%08x\n", mnr);
         LOG_D("mnr = 0x%08x\n", mnr);
 
 
+        RT_ASSERT(mnr < total);
+
         page_start = (struct page*)reg.start;
         page_start = (struct page*)reg.start;
         reg.start += (mnr << ARCH_PAGE_SHIFT);
         reg.start += (mnr << ARCH_PAGE_SHIFT);
         page_addr = (void*)reg.start;
         page_addr = (void*)reg.start;
@@ -331,17 +373,24 @@ void rt_page_init(rt_region_t reg)
         page_list[i] = 0;
         page_list[i] = 0;
     }
     }
 
 
-    /* init page struct */
-    for (i = 0; i < page_nr; i++)
+    /* add pages to free list */
+    while (reg.start != reg.end)
     {
     {
-        page_start[i].size_bits = ARCH_ADDRESS_WIDTH_BITS;
-        page_start[i].ref_cnt = 1;
-    }
+        struct page *p;
+        int align_bits;
+        int size_bits;
 
 
-    /* add to free list */
-    for (i = 0; i < page_nr; i++)
-    {
-        _pages_free(page_start + i, 0);
+        size_bits = ARCH_ADDRESS_WIDTH_BITS - 1 - rt_clz(reg.end - reg.start);
+        align_bits = rt_ctz(reg.start);
+        if (align_bits < size_bits)
+        {
+            size_bits = align_bits;
+        }
+        p = addr_to_page((void*)reg.start);
+        p->size_bits = ARCH_ADDRESS_WIDTH_BITS;
+        p->ref_cnt = 1;
+        _pages_free(p, size_bits - ARCH_PAGE_SHIFT);
+        reg.start += (1UL << size_bits);
     }
     }
 }
 }
 #endif
 #endif

+ 5 - 0
libcpu/arm/cortex-a/start_gcc.S

@@ -632,6 +632,11 @@ set_secondary_cpu_boot_address:
 #endif
 #endif
     mov     pc, lr
     mov     pc, lr
 
 
+.global rt_clz
+rt_clz:
+    clz r0, r0
+    bx lr
+
 .global secondary_cpu_start
 .global secondary_cpu_start
 secondary_cpu_start:
 secondary_cpu_start:
 #ifdef RT_USING_USERSPACE
 #ifdef RT_USING_USERSPACE