硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1967|回复: 3
收起左侧

[算法] SEGGER提供的malloc,calloc,realloc,free重定义源文件完整代码

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
发表于 2020-8-18 14:32:43 | 显示全部楼层 |阅读模式


Embedded Sutudio安装目录路径:SEGGER\SEGGER Embedded Studio for ARM 5.10\source

  1. // **********************************************************************
  2. // *                    SEGGER Microcontroller GmbH                     *
  3. // *                        The Embedded Experts                        *
  4. // **********************************************************************
  5. // *                                                                    *
  6. // *            (c) 2014 - 2020 SEGGER Microcontroller GmbH             *
  7. // *            (c) 2001 - 2020 Rowley Associates Limited               *
  8. // *                                                                    *
  9. // *           www.segger.com     Support: support@segger.com           *
  10. // *                                                                    *
  11. // **********************************************************************
  12. // *                                                                    *
  13. // * All rights reserved.                                               *
  14. // *                                                                    *
  15. // * Redistribution and use in source and binary forms, with or         *
  16. // * without modification, are permitted provided that the following    *
  17. // * condition is met:                                                  *
  18. // *                                                                    *
  19. // * - Redistributions of source code must retain the above copyright   *
  20. // *   notice, this condition and the following disclaimer.             *
  21. // *                                                                    *
  22. // * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND             *
  23. // * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,        *
  24. // * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF           *
  25. // * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE           *
  26. // * DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
  27. // * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR           *
  28. // * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  *
  29. // * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;    *
  30. // * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF      *
  31. // * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT          *
  32. // * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE  *
  33. // * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
  34. // * DAMAGE.                                                            *
  35. // *                                                                    *
  36. // **********************************************************************

  37. #include "stdlib.h"
  38. #include "string.h"
  39. #include "__libc.h"

  40. #if defined(__CROSSWORKS_ARM) || defined(__SES_ARM) || defined(__SES_RISCV)

  41. void *calloc(size_t nobj, size_t size)__attribute__((weak));
  42. void *malloc(size_t size)__attribute__((weak));
  43. void free(void *addr)__attribute__((weak));
  44. void *realloc(void *p, size_t size)__attribute__((weak));

  45. #endif

  46. typedef struct heap_tag
  47. {
  48.   struct heap_tag *next;
  49.   unsigned size;
  50. } heap_t;

  51. extern heap_t __heap_start__;
  52. static heap_t *heap = &__heap_start__;

  53. #define HEAP_CHUNK_SIZE  16   /* Must be a power of two. */
  54. #define ADDADR(x,n)  ((void *)((unsigned char *)(x)+(n)))

  55. #if defined(__CROSSWORKS_ARM) || defined(__SES_ARM) || defined(__SES_RISCV)
  56. extern char __heap_end__[];
  57. static size_t
  58. raw_heap_size(void)
  59. {
  60.   return __heap_end__ - (char *)&__heap_start__;
  61. }
  62. static int
  63. in_heap(void *addr)
  64. {  
  65.   return addr >= (void*)&__heap_start__ && addr <= (void*)__heap_end__;
  66. }
  67. #endif

  68. void *
  69. calloc(size_t nobj, size_t size)
  70. {
  71.   size_t arrsize = nobj * size;
  72.   void *m = malloc(arrsize);
  73.   if (m)
  74.     memset(m, 0, arrsize);
  75.   return m;
  76. }

  77. void *
  78. malloc(size_t size)
  79. {         
  80.   heap_t *p, *q, *best;
  81.   unsigned best_size;   

  82. #if defined(__CROSSWORKS_ARM) || defined(__SES_ARM) || defined(__SES_RISCV)
  83.   // Protect against small heaps requested by the user/IDE.
  84.   if (raw_heap_size() <= HEAP_CHUNK_SIZE)
  85.     return 0;
  86. #endif

  87.   __heap_lock();

  88.   /* Round up to a multiple of HEAP_CHUNK_SIZE and account for size word. */
  89.   size = (size + sizeof(unsigned) + HEAP_CHUNK_SIZE-1) & (unsigned)(-HEAP_CHUNK_SIZE);

  90.   /* Find first block that could satisfy request. */
  91.   p = heap;
  92.   q = 0;

  93.   /* No best-fit block. */
  94.   best_size = ~0U;
  95.   best = 0;

  96.   /* Search for best-fit block. */
  97.   while (p)
  98.     {

  99.       /* Check whether block is correct size. */
  100.       if (p->size == size)
  101.         {
  102.           /* Exact fit - remove block from the free list. */
  103.           if (q)
  104.             q->next = p->next;
  105.           else
  106.             heap = p->next;

  107.           /* Short-cut return. */
  108.           *((unsigned *)p) = size;
  109.           __heap_unlock();
  110.           return ((char *)p) + sizeof(unsigned);
  111.         }

  112.       /* Check whether block can be split. */
  113.       else if (p->size > size && p->size < best_size)
  114.         {
  115.           best = p;
  116.           best_size = p->size;
  117.         }

  118.       /* Consider next block. */
  119.       q = p;
  120.       p = p->next;
  121.     }

  122.   /* Block must be split; take free memory from top of block. */
  123.   if (best)
  124.     {
  125.       best->size -= size;
  126.       p = ADDADR(best, best_size - size);
  127.       *((unsigned *)p) = size;  
  128.       //memset((char*)p+sizeof(unsigned), 0xAE, size-2);
  129.       __heap_unlock();
  130.       return ((char *)p) + sizeof(unsigned);
  131.     }
  132.   else
  133.     {
  134.       __heap_unlock();
  135.       return 0;
  136.     }
  137. }

  138. void
  139. free(void *addr)
  140. {
  141.   heap_t *p, *rover, *prev;
  142.   unsigned size;  

  143.   if (addr == 0)
  144.     return;

  145. #if defined(__CROSSWORKS_ARM) || defined(__SES_ARM) || defined(__SES_RISCV)
  146.   if (!in_heap(addr))
  147.     return;
  148. #endif

  149.   __heap_lock();

  150.   /* Adjust backwards to actual memory block origin. */
  151.   addr = ((char *)addr) - sizeof(unsigned);

  152.   /* Recover size */
  153.   size = *((unsigned *)addr);
  154.   
  155.   if (addr)
  156.     {
  157.       //memset(addr, 0xFE, size);  

  158.       /* Deallocated onto non-existent heap? */
  159.       if (heap == 0)
  160.         {
  161.           /* Yes, add this floating block to the heap. */
  162.           heap = addr;
  163.           heap->next = 0;
  164.           heap->size = size;
  165.         }
  166.       else
  167.         {
  168.           /* Search for block adjacent to p, but with lower address. */
  169.           p = addr; rover = heap; prev = 0;
  170.           while (rover && rover < (heap_t *)addr)
  171.             {
  172.               prev = rover; rover = rover->next;
  173.             }

  174.           /* Check for double-dispose of a pointer. */
  175.           /* For efficiency, this could be removed. */
  176.     #if 0
  177.           if ((rover = addr) ||
  178.               prev & (DIFADR(addr, ADDADR(prev, prev->size)) < 0))
  179.             HALT(DOUBLEDISPOSE);
  180.           END;
  181.     #endif

  182.           /* Return block to free list */
  183.           p->next = rover;
  184.           p->size = size;
  185.           if (prev)
  186.             prev->next = p;
  187.           else
  188.             heap = p;

  189.           /* See if can join with block to right. */
  190.           if (rover && (ADDADR(p, size) == rover))
  191.             {
  192.               p->size += rover->size;
  193.               p->next = rover->next;
  194.             }

  195.           /* See if can join with block to left. */
  196.           if (prev && ADDADR(prev, prev->size) == p)
  197.             {
  198.               prev->size += p->size;
  199.               prev->next = p->next;
  200.             }
  201.         }
  202.     }
  203.   __heap_unlock();
  204. }

  205. void *
  206. realloc(void *p, size_t size)
  207. {
  208.   /* Allocate area of requested size. */
  209.   void *pp = malloc(size);
  210.   
  211.   /* If no memory, keep existing block and indicate failure to reallocate. */
  212.   if (pp == 0)
  213.     return pp;

  214.   /* Copy existing block if we were given one. */
  215.   if (p)
  216.     {
  217.       /* Recover size */
  218.       size_t existing_size = ((unsigned *)p)[-1];

  219.       /* Limit size to copy. */
  220.       if (existing_size < size)
  221.         size = existing_size;

  222.       /* Make copy of data. */
  223.       memcpy(pp, p, size);

  224.       /* And we're done with the original block. */
  225.       free(p);
  226.     }

  227.   /* Return newly allocated block. */
  228.   return pp;
  229. }
复制代码


回复

使用道具 举报

1

主题

94

回帖

97

积分

初级会员

积分
97
发表于 2020-8-24 21:51:58 | 显示全部楼层
这个有单独下载的地方吗?想把它移植到自己的项目中,又不想安装Segger的Embedded Sutudio
回复

使用道具 举报

609

主题

3050

回帖

4897

积分

至尊会员

积分
4897
发表于 2020-9-2 16:08:54 | 显示全部楼层
你好,请问下,这个内存管理的实际使用效果如何啊 ?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106738
QQ
 楼主| 发表于 2020-9-2 16:59:53 | 显示全部楼层
hpdell 发表于 2020-9-2 16:08
你好,请问下,这个内存管理的实际使用效果如何啊 ?

实际用的是这个,貌似还可以

Embedded Studio带的malloc,使用的buddy算法
http://www.armbbs.cn/forum.php?m ... 9463&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 07:21 , Processed in 0.208628 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表