* @brief This function will init slab memory management algorithm * * @param name is the name of the slab memory management object. * * @param begin_addr the beginning address of system page. * * @param size is the size of the memory. * * @return Return a pointer to the slab memory object. */
| 322 | * @return Return a pointer to the slab memory object. |
| 323 | */ |
| 324 | rt_slab_t rt_slab_init(const char *name, void *begin_addr, rt_size_t size) |
| 325 | { |
| 326 | rt_uint32_t limsize, npages; |
| 327 | rt_uintptr_t start_addr, begin_align, end_align; |
| 328 | struct rt_slab *slab; |
| 329 | |
| 330 | slab = (struct rt_slab *)RT_ALIGN((rt_uintptr_t)begin_addr, RT_ALIGN_SIZE); |
| 331 | start_addr = (rt_uintptr_t)slab + sizeof(*slab); |
| 332 | /* align begin and end addr to page */ |
| 333 | begin_align = RT_ALIGN((rt_uintptr_t)start_addr, RT_MM_PAGE_SIZE); |
| 334 | end_align = RT_ALIGN_DOWN((rt_uintptr_t)begin_addr + size, RT_MM_PAGE_SIZE); |
| 335 | if (begin_align >= end_align) |
| 336 | { |
| 337 | rt_kprintf("slab init errr. wrong address[0x%x - 0x%x]\n", |
| 338 | (rt_uintptr_t)begin_addr, (rt_uintptr_t)begin_addr + size); |
| 339 | return RT_NULL; |
| 340 | } |
| 341 | |
| 342 | limsize = end_align - begin_align; |
| 343 | npages = limsize / RT_MM_PAGE_SIZE; |
| 344 | LOG_D("heap[0x%x - 0x%x], size 0x%x, 0x%x pages", |
| 345 | begin_align, end_align, limsize, npages); |
| 346 | |
| 347 | rt_memset(slab, 0, sizeof(*slab)); |
| 348 | /* initialize slab memory object */ |
| 349 | rt_object_init(&(slab->parent.parent), RT_Object_Class_Memory, name); |
| 350 | slab->parent.algorithm = "slab"; |
| 351 | slab->parent.address = begin_align; |
| 352 | slab->parent.total = limsize; |
| 353 | slab->parent.used = 0; |
| 354 | slab->parent.max = 0; |
| 355 | slab->heap_start = begin_align; |
| 356 | slab->heap_end = end_align; |
| 357 | |
| 358 | /* init pages */ |
| 359 | rt_slab_page_init(slab, (void *)slab->heap_start, npages); |
| 360 | |
| 361 | /* calculate zone size */ |
| 362 | slab->zone_size = ZALLOC_MIN_ZONE_SIZE; |
| 363 | while (slab->zone_size < ZALLOC_MAX_ZONE_SIZE && (slab->zone_size << 1) < (limsize / 1024)) |
| 364 | slab->zone_size <<= 1; |
| 365 | |
| 366 | slab->zone_limit = slab->zone_size / 4; |
| 367 | if (slab->zone_limit > ZALLOC_ZONE_LIMIT) |
| 368 | slab->zone_limit = ZALLOC_ZONE_LIMIT; |
| 369 | |
| 370 | slab->zone_page_cnt = slab->zone_size / RT_MM_PAGE_SIZE; |
| 371 | |
| 372 | LOG_D("zone size 0x%x, zone page count 0x%x", |
| 373 | slab->zone_size, slab->zone_page_cnt); |
| 374 | |
| 375 | /* allocate slab->memusage array */ |
| 376 | limsize = npages * sizeof(struct rt_slab_memusage); |
| 377 | limsize = RT_ALIGN(limsize, RT_MM_PAGE_SIZE); |
| 378 | slab->memusage = rt_slab_page_alloc((rt_slab_t)(&slab->parent), limsize / RT_MM_PAGE_SIZE); |
| 379 | |
| 380 | LOG_D("slab->memusage 0x%x, size 0x%x", |
| 381 | (rt_uintptr_t)slab->memusage, limsize); |
no test coverage detected