硬汉嵌入式论坛

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

[ThreadX全家桶] 借助Threadx强大性能,编写自己的内存管理malloc/free

  [复制链接]

4

主题

25

回帖

37

积分

新手上路

积分
37
发表于 2022-9-25 19:01:54 | 显示全部楼层 |阅读模式
咱们就直接上代码吧
mymalloc.c文件源码:
[C] 纯文本查看 复制代码
static void AppTaskMsgPro(ULONG thread_input)
{
	(void)thread_input;
  void *pvTest1 =NULL;
	void *pvTest2 =NULL;

	unsigned int count = 0;
	while(1)
	{
		count = HAL_GetTick()%1024;
		pvTest1 = my_malloc(count);
		printf("pvTest1:%p count:%d\r\n",pvTest1,count);

		count = HAL_GetTick()%1024;
		pvTest2 = my_malloc(count);
		printf("pvTest2:%p count:%d\r\n",pvTest2,count);
		my_free(pvTest1);
		my_free(pvTest2);

		bsp_LedToggle(2);
		tx_thread_sleep(1000);        
	}   
}





跑一个线程测试一下:
[C] 纯文本查看 复制代码
static void AppTaskMsgPro(ULONG thread_input)
{
	(void)thread_input;
  void *pvTest1 =NULL;
	void *pvTest2 =NULL;

	unsigned int count = 0;
	while(1)
	{
		count = HAL_GetTick()%1024;
		pvTest1 = my_malloc(count);
		printf("pvTest1:%p count:%d\r\n",pvTest1,count);

		count = HAL_GetTick()%1024;
		pvTest2 = my_malloc(count);
		printf("pvTest2:%p count:%d\r\n",pvTest2,count);
		my_free(pvTest1);
		my_free(pvTest2);

		bsp_LedToggle(2);
		tx_thread_sleep(1000);        
	}   
}


效果:

Snipaste_2022-09-25_19-01-23.png
回复

使用道具 举报

4

主题

25

回帖

37

积分

新手上路

积分
37
 楼主| 发表于 2022-9-25 23:04:32 | 显示全部楼层
之前上传重复的代码了,以下是my_malloc.c
[C] 纯文本查看 复制代码
static TX_BYTE_POOL malloc_pool_ = {0};

int init_malloc(uintptr_t heap_start, size_t heap_size)	
{
	uint8_t r;
    r = tx_byte_pool_create(&malloc_pool_, "Heap Memory Pool",
            (void *)heap_start,
            heap_size);
    return (r == TX_SUCCESS) ? 0 : -1;
}

void * my_malloc(size_t size)
{
    void * ptr = NULL;
    if(size > 0)
    {
        // We simply wrap the threadX call into a standard form
        uint8_t r = tx_byte_allocate(&malloc_pool_, &ptr, size,
            TX_WAIT_FOREVER);

        if(r != TX_SUCCESS)
        {
            ptr = NULL;
        }
    } 
    //else NULL if there was no size
    return ptr;
}

void my_free(void * ptr)
{
    if(ptr) {
        //We simply wrap the threadX call into a standard form
        uint8_t r = tx_byte_release(ptr);
    }
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116767
QQ
发表于 2022-9-26 02:14:59 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

10

主题

100

回帖

130

积分

初级会员

积分
130
发表于 2022-9-26 09:50:39 | 显示全部楼层
只可惜它有个致命缺点,无法realloc。
回复

使用道具 举报

4

主题

1455

回帖

1467

积分

至尊会员

积分
1467
发表于 2022-9-26 10:13:04 | 显示全部楼层
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2022-9-26 11:16:44 | 显示全部楼层
`dc2018 发表于 2022-9-26 09:50
只可惜它有个致命缺点,无法realloc。

自己写一个就是了,先分配一个,然后把就内存的数据复制过来,然后删除旧内存。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116767
QQ
发表于 2022-9-26 11:19:10 | 显示全部楼层
`dc2018 发表于 2022-9-26 09:50
只可惜它有个致命缺点,无法realloc。

[C] 纯文本查看 复制代码
void *
realloc(void *p, size_t size)
{
  /* Allocate area of requested size. */
  void *pp = malloc(size);
  
  /* If no memory, keep existing block and indicate failure to reallocate. */
  if (pp == 0)
    return pp;

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

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

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

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

  /* Return newly allocated block. */
  return pp;
}
回复

使用道具 举报

10

主题

100

回帖

130

积分

初级会员

积分
130
发表于 2022-9-26 19:49:07 | 显示全部楼层
eric2013 发表于 2022-9-26 11:19
[mw_shl_code=c,true]void *
realloc(void *p, size_t size)
{

老大,这个我还是知道的!是只这么做效率比较低,因为任何情况下都需要从新拷贝。
也许tx没有提供就是为了提高速度,剩下了从新拼接的时间。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116767
QQ
发表于 2022-9-27 12:44:44 | 显示全部楼层
`dc2018 发表于 2022-9-26 19:49
老大,这个我还是知道的!是只这么做效率比较低,因为任何情况下都需要从新拷贝。
也许tx没有提供就是为 ...

realloc一直都这样,没有特别高效的,后面大家有好的方案了,欢迎分享下。

所以一般安全关键,时间关键项目禁用动态内存分配。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2023-8-23 18:07:56 | 显示全部楼层
小白想请教一下,threadX申请动态内存都需要提供起始地址,这个起始地址怎么选啊,怎么知道当前程序哪些sram空着没用可以拿来申请内存呢?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116767
QQ
发表于 2023-8-24 01:22:51 | 显示全部楼层
qwq 发表于 2023-8-23 18:07
小白想请教一下,threadX申请动态内存都需要提供起始地址,这个起始地址怎么选啊,怎么知道当前程序哪些sra ...

直接定义个大数组,将数组地址给他就行。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2023-8-24 14:15:37 | 显示全部楼层
eric2013 发表于 2023-8-24 01:22
直接定义个大数组,将数组地址给他就行。

噢噢,明白了,谢谢硬哥
回复

使用道具 举报

14

主题

60

回帖

102

积分

初级会员

积分
102
发表于 2025-6-16 22:04:57 | 显示全部楼层
本帖最后由 Superusrss 于 2025-6-17 00:24 编辑
eric2013 发表于 2022-9-26 11:19
[mw_shl_code=c,true]void *
realloc(void *p, size_t size)
{

若malloc也使用threadx的内存管理方式 size_t existing_size = ((unsigned *)p)[-1]; 这行就没有用了吧?threadx不能保证内存地址头放块大小,也不能保证块大小变量是uint8类型

我尝试实现了下,代价太大,会内存泄漏,还是算了,有高手试下能不能改好。不使用柔性数组存储内存块大小的话,都是没有问题的,稳如老狗,贴不了代码,直接传附件了,附件自己改后缀.cpp,论坛传不了cpp文件

memory_allocate.c (5.9 KB, 下载次数: 0)

avalible ram 1568
avalible ram 1456
avalible ram 1344
avalible ram 1232
avalible ram 1120
avalible ram 1008
avalible ram 896
avalible ram 784
avalible ram 672
avalible ram 560
avalible ram 448
avalible ram 336
avalible ram 224
avalible ram 112
assert failed at ../App/memory_allocate.cpp 184

回复

使用道具 举报

14

主题

60

回帖

102

积分

初级会员

积分
102
发表于 2025-6-19 23:53:48 | 显示全部楼层
Superusrss 发表于 2025-6-16 22:04
若malloc也使用threadx的内存管理方式 size_t existing_size = ((unsigned *)p)[-1]; 这行就没有用了吧? ...

可以了,原有代码不变,调用realloc错了。
不过还有一个问题,若使用此方法重载new new[] delete delete[]后,使用std::vector对象的resize方法会引入非常多的编译器自定义实现,和我做的不兼容
所以这个使用c代码还行,cpp的重载要慎重
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-6 07:01 , Processed in 0.523268 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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