| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858 |
- /*****************************************************************************
- *
- * File Name : wm_mem.c
- *
- * Description: memory manager Module
- *
- * Copyright (c) 2014 Winner Micro Electronic Design Co., Ltd.
- * All rights reserved.
- *
- * Author : dave
- *
- * Date : 2014-6-12
- *****************************************************************************/
- #include "wm_osal.h"
- #include "wm_mem.h"
- #include "list.h"
- #include <string.h>
- #if 0
- extern u8 tls_get_isr_count(void);
- /**
- * This variable is set if the memory mananger has been initialized.
- * This is available only for debug version of the driver
- */
- bool memory_manager_initialized = false;
- /**
- * This mutex is used to synchronize the list of allocated
- * memory blocks. This is a debug version only feature
- */
- tls_os_sem_t *mem_sem;
- #if WM_MEM_DEBUG
- struct dl_list memory_used_list;
- struct dl_list memory_free_list;
- #define MEM_BLOCK_SIZE 800
- MEMORY_BLOCK mem_blocks[MEM_BLOCK_SIZE];
- u32 alloc_heap_mem_bytes = 0;
- u32 alloc_heap_mem_blk_cnt = 0;
- u32 alloc_heap_mem_max_size = 0;
- #define PRE_OVERSIZE 0
- #define OVERSIZE 0
- /**
- * This is a debug only function that performs memory management operations for us.
- * Memory allocated using this function is tracked, flagged when leaked, and caught for
- * overflows and underflows.
- *
- * \param size The size in bytes of memory to
- * allocate
- *
- * \param file The full path of file where this
- * function is invoked from
- * \param line The line number in the file where this
- * method was called from
- * \return Pointer to the allocated memory or NULL in case of a failure
- */
- void * mem_alloc_debug(u32 size, char* file, int line)
- {
- void *buf = NULL;
- u32 pad_len;
- int i = 0;
- u32 cpu_sr;
- //
- // If the memory manager has not been initialized, do so now
- //
- cpu_sr = tls_os_set_critical();
- if (!memory_manager_initialized) {
- tls_os_status_t os_status;
- memory_manager_initialized = true;
- //
- // NOTE: If two thread allocate the very first allocation simultaneously
- // it could cause double initialization of the memory manager. This is a
- // highly unlikely scenario and will occur in debug versions only.
- //
- os_status = tls_os_sem_create(&mem_sem, 1);
- if(os_status != TLS_OS_SUCCESS)
- printf("mem_alloc_debug: tls_os_sem_create mem_sem error\r\n");
- dl_list_init(&memory_used_list);
- dl_list_init(&memory_free_list);
- for(i = 0; i < MEM_BLOCK_SIZE; i++)
- {
- dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
- }
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- //
- // Allocate the required memory chunk plus header and trailer bytes
- //
- pad_len = sizeof(u32) - (size & 0x3);
- buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
- if (buf) {
- //
- // Memory allocation succeeded. Add information about the allocated
- // block in the list that tracks all allocations.
- //
- PMEMORY_PATTERN mem_ptn_hd;
- PMEMORY_PATTERN mem_ptn_tl;
- PMEMORY_BLOCK mem_blk_hd1;
- if(dl_list_empty(&memory_free_list))
- {
- printf("Memory blocks empty!\r\n");
- free(buf);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- tls_mem_alloc_info();
- return NULL;
- }
- mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
- dl_list_del(&mem_blk_hd1->list);
- dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
- alloc_heap_mem_bytes += size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
- alloc_heap_mem_blk_cnt++;
- if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
- {
- alloc_heap_mem_max_size = alloc_heap_mem_bytes;
- //printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
- }
-
- mem_blk_hd1->pad = pad_len;
- mem_blk_hd1->file = file;
- mem_blk_hd1->line = line;
- mem_blk_hd1->length = size;
- mem_blk_hd1->header_pattern = (u32)buf;
-
- // Fill in the memory header and trailer
- mem_ptn_hd = (PMEMORY_PATTERN)buf;
- mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
- /*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
- mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
- mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
- mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
- mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
- /*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
- mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
- mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
- // Jump ahead by memory header so pointer returned to caller points at the right place
- buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
- #if 0
- printf("==>Memory was allocated from %s at line %d with length %d\n",
- mem_blk_hd1->file,
- mem_blk_hd1->line,
- mem_blk_hd1->length);
- printf("==>mem alloc ptr = 0x%x\n", buf);
- #endif
- }
- else
- {
- printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\r\n",
- file,
- line,
- size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- tls_mem_alloc_info();
- return buf;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- return buf;
- }
- void * mem_calloc_debug(u32 n, u32 size, char* file, int line)
- {
- void *buf = NULL;
- u32 pad_len;
- int i = 0;
- u32 cpu_sr;
- //
- // If the memory manager has not been initialized, do so now
- //
- cpu_sr = tls_os_set_critical();
- if (!memory_manager_initialized) {
- tls_os_status_t os_status;
- memory_manager_initialized = true;
- //
- // NOTE: If two thread allocate the very first allocation simultaneously
- // it could cause double initialization of the memory manager. This is a
- // highly unlikely scenario and will occur in debug versions only.
- //
- os_status = tls_os_sem_create(&mem_sem, 1);
- if(os_status != TLS_OS_SUCCESS)
- printf("mem_alloc_debug: tls_os_sem_create mem_sem error\r\n");
- dl_list_init(&memory_used_list);
- dl_list_init(&memory_free_list);
- for(i = 0; i < MEM_BLOCK_SIZE; i++)
- {
- dl_list_add_tail(&memory_free_list, &mem_blocks[i].list);
- }
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- //
- // Allocate the required memory chunk plus header and trailer bytes
- //
- pad_len = sizeof(u32) - ((n*size) & 0x3);
- buf = malloc(sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + n*size + pad_len + OVERSIZE + sizeof(MEMORY_PATTERN));
- if (buf) {
- //
- // Memory allocation succeeded. Add information about the allocated
- // block in the list that tracks all allocations.
- //
- PMEMORY_PATTERN mem_ptn_hd;
- PMEMORY_PATTERN mem_ptn_tl;
- PMEMORY_BLOCK mem_blk_hd1;
- if(dl_list_empty(&memory_free_list))
- {
- printf("Memory blocks empty!\r\n");
- free(buf);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- tls_mem_alloc_info();
- return NULL;
- }
- mem_blk_hd1 = dl_list_first(&memory_free_list, MEMORY_BLOCK, list);
- dl_list_del(&mem_blk_hd1->list);
- dl_list_add_tail(&memory_used_list, &mem_blk_hd1->list);
- alloc_heap_mem_bytes += n*size+sizeof(MEMORY_PATTERN)+sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE;
- alloc_heap_mem_blk_cnt++;
- if (alloc_heap_mem_bytes > alloc_heap_mem_max_size)
- {
- alloc_heap_mem_max_size = alloc_heap_mem_bytes;
- //printf("alloc_heap_mem_max_size=%d\n", alloc_heap_mem_max_size);
- }
-
- mem_blk_hd1->pad = pad_len;
- mem_blk_hd1->file = file;
- mem_blk_hd1->line = line;
- mem_blk_hd1->length = n*size;
- mem_blk_hd1->header_pattern = (u32)buf;
-
- // Fill in the memory header and trailer
- mem_ptn_hd = (PMEMORY_PATTERN)buf;
- mem_ptn_hd->pattern0= MEM_HEADER_PATTERN;
- /*mem_ptn_hd->pattern1= MEM_HEADER_PATTERN;
- mem_ptn_hd->pattern2= MEM_HEADER_PATTERN;
- mem_ptn_hd->pattern3= MEM_HEADER_PATTERN;*/
- mem_ptn_tl = (PMEMORY_PATTERN)(((u8 *)(buf))+n*size + sizeof(MEMORY_PATTERN)+pad_len + PRE_OVERSIZE + OVERSIZE);
- mem_ptn_tl->pattern0= MEM_TAILER_PATTERN;
- /*mem_ptn_tl->pattern1= MEM_TAILER_PATTERN;
- mem_ptn_tl->pattern2= MEM_TAILER_PATTERN;
- mem_ptn_tl->pattern3= MEM_TAILER_PATTERN;*/
- // Jump ahead by memory header so pointer returned to caller points at the right place
- buf = ((u8 *)buf) + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE;
- #if 0
- printf("==>Memory was allocated from %s at line %d with length %d\r\n",
- mem_blk_hd1->file,
- mem_blk_hd1->line,
- mem_blk_hd1->length);
- printf("==>mem alloc ptr = 0x%x\n", buf);
- #endif
- }
- else
- {
- printf("==>Memory was allocated from %s at line %d with length %d, allocated size %d, count %d\r\n",
- file,
- line,
- n*size, alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
-
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- tls_mem_alloc_info();
- return buf;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- return buf;
- }
- /**
- * This routine is called to free memory which was previously allocated using MpAllocateMemory function.
- * Before freeing the memory, this function checks and makes sure that no overflow or underflows have
- * happened and will also try to detect multiple frees of the same memory chunk.
- *
- * \param p Pointer to allocated memory
- */
- void mem_free_debug(void *p, char* file, int line)
- {
- PMEMORY_PATTERN mem_ptn_hd;
- PMEMORY_PATTERN mem_ptn_tl;
- PMEMORY_BLOCK mem_blk_hd1;
- u8 needfree = 0;
- u8 haserr = 0;
- u32 cpu_sr;
- // Jump back by memory header size so we can get to the header
- mem_ptn_hd = (PMEMORY_PATTERN) (((u8 *)p) - sizeof(MEMORY_PATTERN) - PRE_OVERSIZE);
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- dl_list_for_each(mem_blk_hd1, &memory_used_list, MEMORY_BLOCK, list){
- if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
- {
- needfree = 1;
- break;
- }
- }
- if(needfree)
- {
- dl_list_del(&mem_blk_hd1->list);
- dl_list_add_tail(&memory_free_list, &mem_blk_hd1->list);
- alloc_heap_mem_bytes -= mem_blk_hd1->length + sizeof(MEMORY_PATTERN) + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + OVERSIZE +
- mem_blk_hd1->pad;
- alloc_heap_mem_blk_cnt--;
- }
- if(needfree == 0)
- {
- printf("Memory Block %p was deallocated from %s at line %d \r\n", mem_ptn_hd, file, line);
- printf("Memory %p has been deallocated!\r\n", p);
- dl_list_for_each_reverse(mem_blk_hd1, &memory_free_list, MEMORY_BLOCK, list){
- if(mem_blk_hd1->header_pattern == (u32)mem_ptn_hd)
- {
- printf("Memory Block %p has been put free list!\r\n", mem_ptn_hd);
- break;
- }
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- tls_mem_alloc_info();
- return;
- }
- #if 0
- if(mem_blk_hd1->line == 976 || mem_blk_hd1->line == 983)
- {
- printf("Memory Block %p can not deallocated from %s at line %d \r\n", mem_ptn_hd, file, line);
- printf("Memory %p has been deallocated!\r\n", p);
- tls_mem_alloc_info();
- }
- #endif
- mem_ptn_tl = (PMEMORY_PATTERN) ((u8 *)p + mem_blk_hd1->length + mem_blk_hd1->pad + OVERSIZE);
- //
- // Check that header was not corrupted
- //
- if (mem_ptn_hd->pattern0 != MEM_HEADER_PATTERN /*|| mem_ptn_hd->pattern1 != MEM_HEADER_PATTERN
- || mem_ptn_hd->pattern2 != MEM_HEADER_PATTERN || mem_ptn_hd->pattern3 != MEM_HEADER_PATTERN*/)
- {
- printf("Memory %p was deallocated from %s at line %d \r\n", p, file, line);
- printf("Memory header corruption due to underflow detected at memory block %p\r\n",
- mem_ptn_hd);
- printf("Header pattern 0(0x%x)\r\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
- mem_ptn_hd->pattern0/*,
- mem_ptn_hd->pattern1,
- mem_ptn_hd->pattern2,
- mem_ptn_hd->pattern3*/);
- //printf("Dumping information about memory block. "
- // "This information may itself have been "
- // "corrupted and could cause machine to bugcheck.\r\n");
- printf("Memory was allocated from %s at line %d with length %d\r\n",
- mem_blk_hd1->file,
- mem_blk_hd1->line,
- mem_blk_hd1->length);
- haserr = 1;
- }
- #if 0
- printf("<==free memory allocated from %s at line %d with length %d\n",
- mem_blk_hd->file,
- mem_blk_hd->line,
- mem_blk_hd->length);
- printf("<==free memory 0x%x\n", (u8 *)mem_blk_hd+sizeof(*mem_blk_hd));
- #endif
- //
- // Check that trailer was not corrupted
- //
- if(mem_ptn_tl->pattern0 != MEM_TAILER_PATTERN /*|| mem_ptn_tl->pattern1 != MEM_TAILER_PATTERN
- || mem_ptn_tl->pattern2 != MEM_TAILER_PATTERN || mem_ptn_tl->pattern3 != MEM_TAILER_PATTERN*/) {
- printf("Memory %p was deallocated from %s at line %d \r\n", p, file, line);
- printf("Memory tailer corruption due to overflow detected at %p\r\n", mem_ptn_hd);
- printf("Tailer pattern 0(0x%x)\r\n",//, 1(0x%x), 2(0x%x), 3(0x%x)
- mem_ptn_tl->pattern0/*,
- mem_ptn_tl->pattern1,
- mem_ptn_tl->pattern2,
- mem_ptn_tl->pattern3*/);
- //printf("Dumping information about memory block. "
- // "This information may itself have been "
- // "corrupted and could cause machine to bugcheck.\r\n");
- printf("Memory was allocated from %s at line %d with length %d\r\n",
- mem_blk_hd1->file, mem_blk_hd1->line, mem_blk_hd1->length);
- haserr = 1;
- }
- if(needfree){
- free(mem_ptn_hd);
- }
-
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- if(haserr)
- tls_mem_alloc_info();
- }
- void * mem_realloc_debug(void *mem_address, u32 size, char* file, int line)
- {
- void * mem_re_addr;
- u32 cpu_sr;
- if ((mem_re_addr = mem_alloc_debug(size, file, line)) == NULL){
- printf("mem_realloc_debug failed(size=%d).\r\n", size);
- return NULL;
- }
- if(mem_address != NULL)
- {
- cpu_sr = tls_os_set_critical();
- memcpy(mem_re_addr, mem_address, size);
- tls_os_release_critical(cpu_sr);
- mem_free_debug(mem_address, file, line);
- }
- //printf("mem_realloc_debug mem_address=%p, mem_re_addr=%p, size=%d, file=%s, line=%d\n", mem_address, mem_re_addr, size, file, line);
- return mem_re_addr;
- }
- void tls_mem_alloc_info(void)
- {
- int i;
- MEMORY_BLOCK * pos;
- u32 cpu_sr;
-
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- printf("==>Memory was allocated size %d, count %d\r\n",
- alloc_heap_mem_bytes, alloc_heap_mem_blk_cnt);
- i = 1;
- dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
- printf("Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\r\n",
- i, (void *)pos->header_pattern, pos->file, pos->line, pos->length);
- i++;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
-
- }
- int is_safe_addr_debug(void* p, u32 len, char* file, int line)
- {
- int i;
- MEMORY_BLOCK * pos;
- u32 cpu_sr;
- if(((u32)p) >= (u32)0x64ae8 || ((u32)p) < (u32)0x54ae8)
- {
- return 1;
- }
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- i = 1;
- dl_list_for_each(pos, &memory_used_list, MEMORY_BLOCK, list){
- if((pos->header_pattern + sizeof (MEMORY_PATTERN) + PRE_OVERSIZE) <= ((u32)p) && ((u32)p) <= ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
- {
- if(((u32)p) + len > ((u32)(pos->header_pattern + sizeof(MEMORY_PATTERN) + PRE_OVERSIZE + pos->length)))
- {
- printf("==>Memory oversize. Block(%2d): addr<%p>, file<%s>, line<%d>, length<%d>\r\n",
- i, (void *)pos->header_pattern, pos->file, pos->line, pos->length);
- break;
- }
- else
- {
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- return 1;
- }
- }
- //else if(((u32)p) < pos->header_pattern)
- //{
- // //tls_os_release_critical(cpu_sr);
- // tls_os_sem_release(mem_sem);
- // return 1;
- // }
- i++;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- printf("==>Memory is not safe addr<%p>, file<%s>, line<%d>.\r\n",p, file, line);
- return 0;
- }
- #else /* WM_MEM_DEBUG */
- #if TLS_OS_FREERTOS
- u32 alloc_heap_mem_bytes = 0;
- u32 alloc_heap_mem_blk_cnt = 0;
- u32 alloc_heap_mem_max_size = 0;
- #define OS_MEM_FLAG (0x5AA5A55A)
- #define NON_OS_MEM_FLAG (0xA55A5A5A)
- #define MEM_HEAD_FLAG (0xBB55B55B)
- #endif
- #define USING_ADD_HEADER 1
- extern u32 total_mem_size;
- void * mem_alloc_debug(u32 size)
- {
- u32 cpu_sr = 0;
- u32 *buffer = NULL;
- u32 length = size;
- //printf("size:%d\n", size);
- if (!memory_manager_initialized) {
- tls_os_status_t os_status;
- cpu_sr = tls_os_set_critical();
- memory_manager_initialized = true;
- //
- // NOTE: If two thread allocate the very first allocation simultaneously
- // it could cause double initialization of the memory manager. This is a
- // highly unlikely scenario and will occur in debug versions only.
- //
- os_status = tls_os_sem_create(&mem_sem, 1);
- if(os_status != TLS_OS_SUCCESS)
- printf("mem_alloc_debug: tls_os_sem_create mem_sem error\r\n");
- tls_os_release_critical(cpu_sr);
- }
- #if USING_ADD_HEADER
- length += 8;
- if(tls_get_isr_count() > 0)
- {
- extern void *pvPortMalloc( size_t xWantedSize );
- buffer = pvPortMalloc(length);
- if(buffer)
- {
- *buffer = OS_MEM_FLAG;
- buffer++;
- *buffer = length;
- buffer++;
- }
- }
- else
- {
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- buffer = (u32*)malloc(length);
- if(buffer)
- {
- *buffer = NON_OS_MEM_FLAG;
- buffer++;
- *buffer = length;
- buffer++;
- total_mem_size -= length;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- }
- #else
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- buffer = (u32*)malloc(length);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- #endif
- return buffer;
- }
- void mem_free_debug(void *p)
- {
- u32 cpu_sr = 0;
- // u32 len = 0;
- #if USING_ADD_HEADER
- u32* intMemPtr = NULL;
- u8 isrstatus = 0;
- isrstatus = tls_get_isr_count();
- if(isrstatus == 0)
- {
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- }
-
- intMemPtr = (u32*)p;
- if(p)
- {
- intMemPtr -= 2;
- if (*intMemPtr == OS_MEM_FLAG)
- {
- extern void vPortFree( void *pv );
- vPortFree(intMemPtr);
- intMemPtr = NULL;
- }
- else if (*intMemPtr == NON_OS_MEM_FLAG)
- {
- total_mem_size += *(intMemPtr + 1);
- free(intMemPtr);
- intMemPtr = NULL;
- }
- else
- {
- printf("mem_free_debug ptr error!!!!!\r\n");
- }
- }
- if(isrstatus == 0)
- {
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- }
- #else //UCOSII
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- free(p);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- #endif
- }
- void * mem_realloc_debug(void *mem_address, u32 size)
- {
- u32 * mem_re_addr = NULL;
- u32 cpu_sr = 0;
- u32 length = size;
- #if USING_ADD_HEADER
- length = size + 2*4;
- if(tls_get_isr_count() > 0)
- {
- extern void *pvPortMalloc( size_t xWantedSize );
- mem_re_addr = pvPortMalloc(length);
- if (mem_re_addr)
- {
- return NULL;
- }
- if(mem_address != NULL)
- {
- if (*((u32 *)mem_address-1)> size)
- {
- memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, size);
- }
- else
- {
- memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, *((u32 *)mem_address-1));
- }
- mem_free_debug(mem_address);
- mem_address = NULL;
- }
- if(mem_re_addr)
- {
- *mem_re_addr = OS_MEM_FLAG;
- mem_re_addr ++;
- *mem_re_addr = length;
- mem_re_addr ++;
- }
- }
- else
- {
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- mem_re_addr = (u32*)malloc(length);
- if(mem_re_addr && mem_address)
- {
- if (*((u32 *)mem_address-1)> size)
- {
- memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, size);
- }
- else
- {
- memcpy((u8 *)(mem_re_addr + 2), (u8 *)mem_address, *((u32 *)mem_address-1));
- }
- *mem_re_addr = NON_OS_MEM_FLAG;
- mem_re_addr ++;
- *mem_re_addr = length;
- mem_re_addr ++;
- total_mem_size -= length;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- mem_free_debug(mem_address);
- }
- #else
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- mem_re_addr = realloc(mem_address, length);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- #endif
- //if(mem_re_addr == NULL)
- //{
- // printf("realloc error \r\n");
- //}
- return mem_re_addr;
- }
- void *mem_calloc_debug(u32 n, u32 size)
- {
- u32 cpu_sr = 0;
- u32 *buffer = NULL;
- u32 length = 0;
- #if USING_ADD_HEADER
- length = n*size;
- length += 2*4;
- if(tls_get_isr_count() > 0)
- {
- extern void *pvPortMalloc( size_t xWantedSize );
- buffer = pvPortMalloc(length);
- if(buffer)
- {
- memset(buffer, 0, length);
- *buffer = OS_MEM_FLAG;
- buffer ++;
- *buffer = length;
- buffer ++;
- }
- }
- else
- {
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- buffer = (u32*)malloc(length);
- if(buffer)
- {
- memset(buffer, 0, length);
- *buffer = NON_OS_MEM_FLAG;
- buffer ++;
- *buffer = length;
- buffer ++;
- total_mem_size -= length;
- }
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- }
- #else //UCOSII
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- buffer = (u32*)calloc(n,size);
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- #endif
- //if(buffer == NULL)
- //{
- // printf("calloc error \r\n");
- //}
- return buffer;
- }
- #endif /* WM_MEM_DEBUG */
- extern u32 __heap_end;
- extern u32 __heap_start;
- u32 tls_mem_get_avail_heapsize(void)
- {
- #if USING_ADD_HEADER
- u32 availablemem = 0;
- u32 cpu_sr;
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- availablemem = total_mem_size;
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- return availablemem;
- #else
- u8 *p = NULL;
- u32 startpos = 0;
- u32 stoppos = 0;
- u32 laststartpos = 0;
- static u32 last_avail_heapsize = 0;
- u32 cpu_sr = 0;
- if (!memory_manager_initialized) {
- tls_os_status_t os_status;
- memory_manager_initialized = true;
- //
- // NOTE: If two thread allocate the very first allocation simultaneously
- // it could cause double initialization of the memory manager. This is a
- // highly unlikely scenario and will occur in debug versions only.
- //
- os_status = tls_os_sem_create(&mem_sem, 1);
- if(os_status != TLS_OS_SUCCESS)
- printf("mem_alloc_debug: tls_os_sem_create mem_sem error\n");
- }
- tls_os_sem_acquire(mem_sem, 0);
- cpu_sr = tls_os_set_critical();
- if (last_avail_heapsize)
- {
- startpos = last_avail_heapsize;
- stoppos = last_avail_heapsize*2;
- if (startpos > ((u32)&__heap_end - (u32)&__heap_start))
- {
- startpos = (u32)&__heap_end - (u32)&__heap_start;
- }
- }
- else
- {
- startpos = (u32)&__heap_end - (u32)&__heap_start;
- stoppos = (u32)&__heap_end - (u32)&__heap_start;
- }
- for (;startpos <= stoppos;)
- {
- p = malloc(startpos);
- if (p)
- {
- free(p);
- if (startpos < 1024 || (stoppos - startpos) < 1024
- || (startpos == ((u32)&__heap_end - (u32)&__heap_start)))
- {
- last_avail_heapsize = startpos;
- goto END;
- }
- laststartpos = startpos;
- startpos = (stoppos + startpos)>>1;
- }
- else
- {
- stoppos = startpos;
- if (laststartpos)
- {
- startpos = (laststartpos + stoppos)/2;
- }
- else
- {
- startpos = startpos>>1;
- }
- if (startpos < 1024 || (stoppos - startpos) < 1024)
- {
- last_avail_heapsize = startpos;
- goto END;
- }
- }
- }
- END:
- tls_os_release_critical(cpu_sr);
- tls_os_sem_release(mem_sem);
- return startpos;
- #endif
- }
- #endif
|