/// Allocate a memory block from a Memory Pool. /// \param[in] mem pointer to memory pool. /// \param[in] size size of a memory block in bytes. /// \param[in] type memory block type: 0 - generic, 1 - control block /// \return allocated memory block or NULL in case of no memory is available. __WEAK void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type) { mem_block_t *p, *p_new, *ptr; uint32_t hole_size; if ((mem == NULL) || (size == 0U) || (type & ~MB_INFO_TYPE_MASK)) { EvrRtxMemoryAlloc(mem, size, type, NULL); return NULL; } // Add header to size size += sizeof(mem_block_t); // Make sure that block is 8-byte aligned size = (size + 7U) & ~((uint32_t)7U); // Search for hole big enough p = (mem_block_t *)((uint32_t)mem + sizeof(mem_head_t)); for (;;) { hole_size = (uint32_t)p->next - (uint32_t)p; hole_size -= p->info & MB_INFO_LEN_MASK; if (hole_size >= size) { // Hole found break; } p = p->next; if (p->next == NULL) { // Failed (end of list) EvrRtxMemoryAlloc(mem, size, type, NULL); return NULL; } } ((mem_head_t *)mem)->used += size; if (p->info == 0U) { // No block allocated, set info of first element p->info = size | type; ptr = (mem_block_t *)((uint32_t)p + sizeof(mem_block_t)); } else { // Insert new element into the list p_new = (mem_block_t *)((uint32_t)p + (p->info & MB_INFO_LEN_MASK)); p_new->next = p->next; p_new->info = size | type; p->next = p_new; ptr = (mem_block_t *)((uint32_t)p_new + sizeof(mem_block_t)); } EvrRtxMemoryAlloc(mem, size, type, ptr); return ptr; }
/// Allocate a memory block from a Memory Pool. /// \param[in] mem pointer to memory pool. /// \param[in] size size of a memory block in bytes. /// \param[in] type memory block type: 0 - generic, 1 - control block /// \return allocated memory block or NULL in case of no memory is available. __WEAK void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type) { mem_block_t *ptr; mem_block_t *p, *p_new; uint32_t block_size; uint32_t hole_size; // Check parameters if ((mem == NULL) || (size == 0U) || ((type & ~MB_INFO_TYPE_MASK) != 0U)) { EvrRtxMemoryAlloc(mem, size, type, NULL); //lint -e{904} "Return statement before end of function" [MISRA Note 1] return NULL; } // Add block header to size block_size = size + sizeof(mem_block_t); // Make sure that block is 8-byte aligned block_size = (block_size + 7U) & ~((uint32_t)7U); // Search for hole big enough p = MemBlockPtr(mem, sizeof(mem_head_t)); for (;;) { //lint -e{923} -e{9078} "cast from pointer to unsigned int" hole_size = (uint32_t)p->next - (uint32_t)p; hole_size -= p->info & MB_INFO_LEN_MASK; if (hole_size >= block_size) { // Hole found break; } p = p->next; if (p->next == NULL) { // Failed (end of list) EvrRtxMemoryAlloc(mem, size, type, NULL); //lint -e{904} "Return statement before end of function" [MISRA Note 1] return NULL; } } // Update used memory (MemHeadPtr(mem))->used += block_size; // Update max used memory p_new = MemBlockPtr(mem, (MemHeadPtr(mem))->size - sizeof(mem_block_t)); if (p_new->info < (MemHeadPtr(mem))->used) { p_new->info = (MemHeadPtr(mem))->used; } // Allocate block if (p->info == 0U) { // No block allocated, set info of first element p->info = block_size | type; ptr = MemBlockPtr(p, sizeof(mem_block_t)); } else { // Insert new element into the list p_new = MemBlockPtr(p, p->info & MB_INFO_LEN_MASK); p_new->next = p->next; p_new->info = block_size | type; p->next = p_new; ptr = MemBlockPtr(p_new, sizeof(mem_block_t)); } EvrRtxMemoryAlloc(mem, size, type, ptr); return ptr; }