Oneway-Malloc

Hello,

I noticed that there is a “oneway-malloc” module in RIOT OS. It appears to be a thin wrapper around sbrk that only supports allocating memory, not freeing it.

I am doing some development using RIOT OS, and dynamic memory allocation would be useful to me. Is there already a module that implements dynamic memory allocation suitable for general-purpose use in the kernel and in user programs?

If such a module does not already exist, I am willing to contribute a lightweight implementation of malloc, realloc, calloc, and free to replace the oneway-malloc module.

Sam Kumar

https://twitter.com/c4bo/status/676393852798922752

:slight_smile:

Grüße, Carsten

Sam Kumar wrote:

Hey,

Carsten Bormann wrote:

https://twitter.com/c4bo/status/676393852798922752

OK, that may have been a bit opaque :slight_smile:

http://www.embedded.com/design/programming-languages-and-tools/4416457/EMB-tm-6-15-13-Dynamic-memory-and-heap-contiguity

http://www.nongnu.org/avr-libc/user-manual/malloc.html

If you really need dynamic memory for some algorithm, consider an arena allocator.

Grüße, Carsten

Hi Sam!

I noticed that there is a "oneway-malloc" module in RIOT OS. It appears to be a thin wrapper around sbrk that only supports allocating memory, not freeing it.

This is correct. It was originally introduced for MSP430 platforms.

I am doing some development using RIOT OS, and dynamic memory allocation would be useful to me. Is there already a module that implements dynamic memory allocation suitable for general-purpose use in the kernel and in user programs?

Dynamic memory allocation is usually a bad idea for embedded systems (see for instance https://www.quora.com/Why-is-malloc-harmful-in-embedded-systems). Within kernel context it MUST be completely avoided.

If you really need dynamic memory allocation, you can either use the TLSF package [1] or use a simple memory manager that uses a static memory pool like memmgr [2]. TLSF is O(1), but works only on 32 bit platforms.

If such a module does not already exist, I am willing to contribute a lightweight implementation of malloc, realloc, calloc, and free to replace the oneway-malloc module.

This could be a good idea indeed. :slight_smile: I once had the above cited memmgr as package in one of my private branches, but I guess I haven't pushed it to Github. However, creating this package didn't take longer than half an hour.

Cheers, Oleg

[1] RIOT/pkg/tlsf at master · RIOT-OS/RIOT · GitHub [2] code-for-blog/2008/memmgr at master · eliben/code-for-blog · GitHub

I didn’t realize that the reason that one-way malloc was left one-way was that dynamic memory allocation is discouraged. I suppose I should leave it that way if that is the case.

Let me give you some context for what I am working on. I am working on implementing a TCP stack for RIOT. I am aware of the work being done in Pull Request #4744. The work I am doing to be a more feature-complete alternative to the work being done in #4744, aimed at those platforms that have the resources to support it. It is port of the protocol logic in the FreeBSD operating system, and would have support for zero-window probing, out-of-order segment reassembly, TCP timestamps, New Reno congestion control, selective acknowlegements (SACK), etc. I’ve already done the work to port this to TinyOS, and found that the memory overhead was ~20KB of code memory total and ~550 bytes of RAM per socket, which can reasonably be supported on some platforms.

I am aware that other parts of RIOT OS use zone allocators. The allocator for file descriptors, and the packet buffer for allocating pktsnips, are two that I have been working with. In fact, I have already been trying to avoid dynamic memory allocation (I allocate the TCP state and SACK blocks from pools, for instance).

I was interested in using dynamic memory allocation for the send buffer on TCP sockets. It seems wasteful to statically allocate 1-2 KB buffers for each TCP socket when most applications won’t even need to use the whole thing. Rather, I wanted to make the send buffer grow as the user writes data to the socket–up to a limit, when writes start blocking. If I run out of heap space while doing this, I can just make the user block on the socket write, just as if they had filled the buffer. Using a pool or zone seems to defeat the purpose, in this case, since that would require me to allocate a static region large enough to accommodate the full size of all the send buffers upfront, which is precisely what I was trying to avoid.

Just wanted to explain where I am coming from. I suppose I could make do with a static pool of memory and allocate memory from it, if dynamic memory allocation really must be avoided anywhere in the kernel. Thanks for the advice.

Sam