* @brief This function will change the size of previously allocated memory block. * * @param m the small memory management object. * * @param rmem is the pointer to memory allocated by rt_mem_alloc. * * @param newsize is the required new size. * * @return the changed memory block address. */
| 401 | * @return the changed memory block address. |
| 402 | */ |
| 403 | void *rt_smem_realloc(rt_smem_t m, void *rmem, rt_size_t newsize) |
| 404 | { |
| 405 | rt_size_t size; |
| 406 | rt_size_t ptr, ptr2; |
| 407 | struct rt_small_mem_item *mem, *mem2; |
| 408 | struct rt_small_mem *small_mem; |
| 409 | void *nmem; |
| 410 | |
| 411 | RT_ASSERT(m != RT_NULL); |
| 412 | RT_ASSERT(rt_object_get_type(&m->parent) == RT_Object_Class_Memory); |
| 413 | RT_ASSERT(rt_object_is_systemobject(&m->parent)); |
| 414 | |
| 415 | small_mem = (struct rt_small_mem *)m; |
| 416 | /* alignment size */ |
| 417 | newsize = RT_ALIGN(newsize, RT_ALIGN_SIZE); |
| 418 | if (newsize > small_mem->mem_size_aligned) |
| 419 | { |
| 420 | LOG_D("realloc: out of memory"); |
| 421 | |
| 422 | return RT_NULL; |
| 423 | } |
| 424 | else if (newsize == 0) |
| 425 | { |
| 426 | rt_smem_free(rmem); |
| 427 | return RT_NULL; |
| 428 | } |
| 429 | |
| 430 | /* allocate a new memory block */ |
| 431 | if (rmem == RT_NULL) |
| 432 | return rt_smem_alloc(&small_mem->parent, newsize); |
| 433 | |
| 434 | RT_ASSERT((((rt_uintptr_t)rmem) & (RT_ALIGN_SIZE - 1)) == 0); |
| 435 | RT_ASSERT((rt_uint8_t *)rmem >= (rt_uint8_t *)small_mem->heap_ptr); |
| 436 | RT_ASSERT((rt_uint8_t *)rmem < (rt_uint8_t *)small_mem->heap_end); |
| 437 | |
| 438 | mem = (struct rt_small_mem_item *)((rt_uint8_t *)rmem - SIZEOF_STRUCT_MEM); |
| 439 | |
| 440 | /* current memory block size */ |
| 441 | ptr = (rt_uint8_t *)mem - small_mem->heap_ptr; |
| 442 | size = mem->next - ptr - SIZEOF_STRUCT_MEM; |
| 443 | if (size == newsize) |
| 444 | { |
| 445 | /* the size is the same as */ |
| 446 | return rmem; |
| 447 | } |
| 448 | |
| 449 | if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) |
| 450 | { |
| 451 | /* split memory block */ |
| 452 | small_mem->parent.used -= (size - newsize); |
| 453 | |
| 454 | ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; |
| 455 | mem2 = (struct rt_small_mem_item *)&small_mem->heap_ptr[ptr2]; |
| 456 | mem2->pool_ptr = MEM_FREED(small_mem); |
| 457 | mem2->next = mem->next; |
| 458 | mem2->prev = ptr; |
| 459 | #ifdef RT_USING_MEMTRACE |
| 460 | rt_smem_setname(mem2, " "); |
no test coverage detected