MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / rt_smem_alloc

Function rt_smem_alloc

src/mem.c:271–389  ·  view source on GitHub ↗

* @brief Allocate a block of memory with a minimum of 'size' bytes. * * @param m the small memory management object. * * @param size is the minimum size of the requested block in bytes. * * @return the pointer to allocated memory or NULL if no free memory was found. */

Source from the content-addressed store, hash-verified

269 * @return the pointer to allocated memory or NULL if no free memory was found.
270 */
271void *rt_smem_alloc(rt_smem_t m, rt_size_t size)
272{
273 rt_size_t ptr, ptr2;
274 struct rt_small_mem_item *mem, *mem2;
275 struct rt_small_mem *small_mem;
276
277 if (size == 0)
278 return RT_NULL;
279
280 RT_ASSERT(m != RT_NULL);
281 RT_ASSERT(rt_object_get_type(&m->parent) == RT_Object_Class_Memory);
282 RT_ASSERT(rt_object_is_systemobject(&m->parent));
283
284 small_mem = (struct rt_small_mem *)m;
285 /* alignment size */
286 size = RT_ALIGN(size, RT_ALIGN_SIZE);
287
288 /* every data block must be at least MIN_SIZE_ALIGNED long */
289 if (size < MIN_SIZE_ALIGNED)
290 size = MIN_SIZE_ALIGNED;
291
292 if (size > small_mem->mem_size_aligned)
293 {
294 LOG_D("no memory");
295
296 return RT_NULL;
297 }
298
299 for (ptr = (rt_uint8_t *)small_mem->lfree - small_mem->heap_ptr;
300 ptr <= small_mem->mem_size_aligned - size;
301 ptr = ((struct rt_small_mem_item *)&small_mem->heap_ptr[ptr])->next)
302 {
303 mem = (struct rt_small_mem_item *)&small_mem->heap_ptr[ptr];
304
305 if ((!MEM_ISUSED(mem)) && (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size)
306 {
307 /* mem is not used and at least perfect fit is possible:
308 * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */
309
310 if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >=
311 (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED))
312 {
313 /* (in addition to the above, we test if another struct rt_small_mem_item (SIZEOF_STRUCT_MEM) containing
314 * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem')
315 * -> split large block, create empty remainder,
316 * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if
317 * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
318 * struct rt_small_mem_item would fit in but no data between mem2 and mem2->next
319 * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty
320 * region that couldn't hold data, but when mem->next gets freed,
321 * the 2 regions would be combined, resulting in more free memory
322 */
323 ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
324
325 /* create mem2 struct */
326 mem2 = (struct rt_small_mem_item *)&small_mem->heap_ptr[ptr2];
327 mem2->pool_ptr = MEM_FREED(small_mem);
328 mem2->next = mem->next;

Callers 4

rt_smem_reallocFunction · 0.85
mem_functional_testFunction · 0.85
mem_alloc_testFunction · 0.85
mem_realloc_testFunction · 0.85

Calls 4

rt_object_get_typeFunction · 0.85
rt_smem_setnameFunction · 0.85
rt_thread_selfFunction · 0.85

Tested by

no test coverage detected