此问题与嵌入式系统上的编程有关。 我正在研究嵌入式设备上的实验性通信堆栈。 堆栈从底层通道接收流数据,检测离散数据包,重组碎片数据等...
每个功能都在单独的层中实现。 某些层延迟了数据包的处理(因为数据到达了中断处理程序,并且进一步 处理被转移到主上下文上)。 某些层将多个传入数据包合并到转发到下一个上层的单个数据包中(即重组分段数据)。 因此,一些层将一个进入的分组分成转发到下一个较低层的多个分组。 当然,任何层都可以在任何时候丢弃数据包而无需另行通知,因为例如校验和与数据不匹配。
我的问题是关于这些数据包的内存分配。
当前,我在每层上使用malloc。具体来说,我为要转发到下一层的数据包分配了内存, 将指针传递给下一层的处理程序,并在调用后再次释放内存。这是下一层处理者的责任 复制所需的数据。因此,每一层都保持对已分配数据的所有权,并且很难忘记释放已分配的内存。 效果很好,但是会导致很多不必要的副本。
或者,我可以将缓冲区的所有权转发到下一层。然后,下一层可以直接在缓冲区上进行工作并转发 与下一层相同的缓冲区,依此类推。我想这有点棘手,因为没有内存泄漏。
最终,因为它是嵌入式设备,所以我想找到一种无需动态内存分配的解决方案。如果每一层都拥有自己的内存所有权,那么没有malloc的实现应该很容易。但是,如果所有权转移了,那就显得更加复杂了。
您有输入吗?
答案 0 :(得分:1)
查看LwIP数据包缓冲区(pbuf),它可以解决您的方案中提到的情况。 http://www.nongnu.org/lwip/2_0_x/group__pbuf.html 为了增强由ISR执行的代码,可以实现内存池而不是malloc。
答案 1 :(得分:0)
在一个位置分配内存。由于它是嵌入式系统,因此必须使用静态内存池。就像以不透明类型实现的经典ADT一样:
// buffer.h
typedef struct buffer_t buffer_t;
buffer_t* buffer_create (/*params*/);
/* setter & getter functions here */
// buffer.c
#include "buffer.h"
struct buffer_t
{
/* private contents */
};
static buffer_t mempool [MEMPOOL_SIZE];
static size_t mempool_size = 0;
buffer_t* buffer_create (/*params*/)
{
if(mempool_size == MEMPOOL_SIZE)
{ /* out of memory, handle error */ }
buffer_t* obj = &mempool[mempool_size];
mempool_size++;
/* initialize obj here */
return obj;
}
/* setter & getter functions here */
现在,所有各种应用程序层和进程都只能传递指针的副本。如果确实需要进行硬拷贝,则可以在上述ADT中实现buffer_copy
函数。
对于多进程系统,如果允许多个进程同时分配缓冲区,则必须考虑重新进入。