| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- /*
- * This file is part of the PikaPython project.
- * http://github.com/pikastech/pikapython
- *
- * MIT License
- *
- * Copyright (c) 2021 lyon liang6516@outlook.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- #define __DATA_MEMORY_CLASS_IMPLEMENT__
- #include "dataMemory.h"
- #include "PikaPlatform.h"
- volatile PikaMemInfo g_PikaMemInfo = {0};
- void* pikaMalloc(uint32_t size) {
- /* pika memory lock */
- if (0 != pika_is_locked_pikaMemory()) {
- pika_platform_wait();
- }
- //! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment
- #if PIKA_ARG_ALIGN_ENABLE
- /* force alignment to avoid unaligned access */
- size = mem_align(size);
- #endif
- g_PikaMemInfo.heapUsed += size;
- if (g_PikaMemInfo.heapUsedMax < g_PikaMemInfo.heapUsed) {
- g_PikaMemInfo.heapUsedMax = g_PikaMemInfo.heapUsed;
- }
- pika_platform_disable_irq_handle();
- void* mem = pika_user_malloc(size);
- pika_platform_enable_irq_handle();
- if (NULL == mem) {
- pika_platform_printf(
- "Error: No heap space! Please reset the device.\r\n");
- while (1) {
- }
- }
- return mem;
- }
- void pikaFree(void* mem, uint32_t size) {
- pika_assert(mem != NULL);
- if (0 != pika_is_locked_pikaMemory()) {
- pika_platform_wait();
- }
- //! if you unsure about the __impl_pikaMalloc, uncomment this to force alignment
- #if PIKA_ARG_ALIGN_ENABLE
- /* force alignment to avoid unaligned access */
- size = mem_align(size);
- #endif
- pika_platform_disable_irq_handle();
- pika_user_free(mem, size);
- pika_platform_enable_irq_handle();
- g_PikaMemInfo.heapUsed -= size;
- }
- uint32_t pikaMemNow(void) {
- return g_PikaMemInfo.heapUsed;
- // return 0;
- }
- uint32_t pikaMemMax(void) {
- return g_PikaMemInfo.heapUsedMax;
- }
- void pikaMemMaxReset(void) {
- g_PikaMemInfo.heapUsedMax = 0;
- }
- #if PIKA_POOL_ENABLE
- uint32_t pool_getBlockIndex_byMemSize(Pool* pool, uint32_t size) {
- if (0 == size) {
- return 0;
- }
- return (size - 1) / pool->aline + 1;
- }
- uint32_t pool_aline(Pool* pool, uint32_t size) {
- return pool_getBlockIndex_byMemSize(pool, size) * pool->aline;
- }
- Pool pool_init(uint32_t size, uint8_t aline) {
- Pool pool;
- pool.aline = aline;
- uint32_t block_size = pool_getBlockIndex_byMemSize(&pool, size);
- pool.size = pool_aline(&pool, size);
- pool.bitmap = bitmap_init(block_size);
- pool.mem = pika_platform_malloc(pool_aline(&pool, pool.size));
- pool.first_free_block = 0;
- pool.purl_free_block_start = 0;
- pool.inited = pika_true;
- return pool;
- }
- void pool_deinit(Pool* pool) {
- pika_platform_free(pool->mem);
- pool->mem = NULL;
- bitmap_deinit(pool->bitmap);
- }
- void* pool_getBytes_byBlockIndex(Pool* pool, uint32_t block_index) {
- return pool->mem + block_index * pool->aline;
- }
- uint32_t pool_getBlockIndex_byMem(Pool* pool, void* mem) {
- uint32_t mem_size = (uintptr_t)mem - (uintptr_t)pool->mem;
- return pool_getBlockIndex_byMemSize(pool, mem_size);
- }
- void pool_printBlocks(Pool* pool, uint32_t size_min, uint32_t size_max) {
- uint32_t block_index_min = pool_getBlockIndex_byMemSize(pool, size_min);
- uint32_t block_index_max = pool_getBlockIndex_byMemSize(pool, size_max);
- pika_platform_printf("[bitmap]\r\n");
- uint8_t is_end = 0;
- for (uint32_t i = block_index_min; i < block_index_max; i += 16) {
- if (is_end) {
- break;
- }
- pika_platform_printf("0x%x\t: 0x%d", i * pool->aline,
- (i + 15) * pool->aline);
- for (uint32_t j = i; j < i + 16; j += 4) {
- if (is_end) {
- break;
- }
- for (uint32_t k = j; k < j + 4; k++) {
- if (k >= block_index_max) {
- is_end = 1;
- break;
- }
- pika_platform_printf("%d", bitmap_get(pool->bitmap, k));
- }
- pika_platform_printf(" ");
- }
- pika_platform_printf("\r\n");
- }
- }
- void* pool_malloc(Pool* pool, uint32_t size) {
- uint32_t block_index_max = pool_getBlockIndex_byMemSize(pool, pool->size);
- uint32_t block_num_need = pool_getBlockIndex_byMemSize(pool, size);
- uint32_t block_num_found = 0;
- uint8_t found_first_free = 0;
- uint32_t block_index;
- /* high speed malloc */
- block_index = pool->purl_free_block_start + block_num_need - 1;
- if (block_index < block_index_max) {
- goto found;
- }
- /* low speed malloc */
- for (block_index = pool->first_free_block;
- block_index < pool->purl_free_block_start; block_index++) {
- /* 8 bit is not free */
- uint8_t bitmap_byte = bitmap_getByte(pool->bitmap, block_index);
- if (0xFF == bitmap_byte) {
- block_index = 8 * (block_index / 8) + 7;
- block_num_found = 0;
- continue;
- }
- /* found a free block */
- if (0 == bitmap_get(pool->bitmap, block_index)) {
- /* save the first free */
- if (!found_first_free) {
- pool->first_free_block = block_index;
- found_first_free = 1;
- }
- block_num_found++;
- } else {
- /* a used block appeared, find again */
- block_num_found = 0;
- }
- /* found all request blocks */
- if (block_num_found >= block_num_need) {
- goto found;
- }
- }
- /* malloc for purl free blocks */
- block_index = pool->purl_free_block_start + block_num_need - 1;
- if (block_index < block_index_max) {
- goto found;
- }
- /* no found */
- return NULL;
- found:
- /* set 1 for found blocks */
- for (uint32_t i = 0; i < block_num_need; i++) {
- bitmap_set(pool->bitmap, block_index - i, 1);
- }
- /* save last used block */
- if (block_index >= pool->purl_free_block_start) {
- pool->purl_free_block_start = block_index + 1;
- }
- /* return mem by block index */
- return pool_getBytes_byBlockIndex(pool, block_index - block_num_need + 1);
- }
- void pool_free(Pool* pool, void* mem, uint32_t size) {
- uint32_t block_num = pool_getBlockIndex_byMemSize(pool, size);
- uint32_t block_index = pool_getBlockIndex_byMem(pool, mem);
- for (uint32_t i = 0; i < block_num; i++) {
- bitmap_set(pool->bitmap, block_index + i, 0);
- }
- /* save min free block index to add speed */
- if (block_index < pool->first_free_block) {
- pool->first_free_block = block_index;
- }
- /* save last free block index to add speed */
- uint32_t block_end = block_index + block_num - 1;
- if (block_end == pool->purl_free_block_start - 1) {
- uint32_t first_pure_free_block = block_index;
- /* back to first used block */
- if (0 != first_pure_free_block) {
- while (0 == bitmap_get(pool->bitmap, first_pure_free_block - 1)) {
- first_pure_free_block--;
- if (0 == first_pure_free_block) {
- break;
- }
- }
- }
- pool->purl_free_block_start = first_pure_free_block;
- }
- return;
- }
- BitMap bitmap_init(uint32_t size) {
- BitMap mem_bit_map =
- (BitMap)pika_platform_malloc(((size - 1) / 8 + 1) * sizeof(char));
- if (mem_bit_map == NULL) {
- return NULL;
- }
- uint32_t size_mem_bit_map = (size - 1) / 8 + 1;
- pika_platform_memset(mem_bit_map, 0x0, size_mem_bit_map);
- return mem_bit_map;
- }
- void bitmap_set(BitMap bitmap, uint32_t index, uint8_t bit) {
- uint32_t index_byte = index / 8;
- uint8_t index_bit = index % 8;
- uint8_t x = (0x1 << index_bit);
- /* set 1 */
- if (bit) {
- bitmap[index_byte] |= x;
- return;
- }
- /* set 0 */
- bitmap[index_byte] &= ~x;
- return;
- }
- uint8_t bitmap_getByte(BitMap bitmap, uint32_t index) {
- uint32_t index_byte = (index) / 8;
- uint8_t byte;
- byte = bitmap[index_byte];
- return byte;
- }
- uint8_t bitmap_get(BitMap bitmap, uint32_t index) {
- uint32_t index_byte = (index) / 8;
- uint8_t index_bit = (index) % 8;
- uint8_t x = (0x1 << index_bit);
- uint8_t bit;
- bit = bitmap[index_byte] & x;
- return bit > 0 ? 1 : 0;
- }
- void bitmap_deinit(BitMap bitmap) {
- pika_platform_free(bitmap);
- }
- Pool pikaPool = {0};
- void* pika_user_malloc(size_t size) {
- return pool_malloc(&pikaPool, size);
- }
- void pika_user_free(void* ptrm, size_t size) {
- pool_free(&pikaPool, ptrm, size);
- }
- #endif
- void mem_pool_init(void) {
- #if PIKA_POOL_ENABLE
- if (!pikaPool.inited) {
- pikaPool = pool_init(PIKA_POOL_SIZE, PIKA_POOL_ALIGN);
- }
- #endif
- }
- void _mem_cache_deinit(void) {
- #if PIKA_ARG_CACHE_ENABLE
- while (g_PikaMemInfo.cache_pool_top) {
- pika_user_free(
- g_PikaMemInfo.cache_pool[g_PikaMemInfo.cache_pool_top - 1], 0);
- g_PikaMemInfo.cache_pool_top--;
- }
- #endif
- }
- void mem_pool_deinit(void) {
- _mem_cache_deinit();
- #if PIKA_POOL_ENABLE
- pool_deinit(&pikaPool);
- #endif
- }
|