Is there is recommandations, hints on do-do-not-do when ISR requires to allocate dynamic memory?
Thanks a lot, you cover it all.
Acctually, I totally agree with "allocating memory from interrupts is strictly forbidden"
In this case, there is rather a lot of accepted 100's bytes that allocating static buffers seems to be not so efficient.
Reading your suggestions, I think I will go with primitive memory allocation service routine.
a nice improvment I'm thinking, might be, that this service will use tresholds,
and will allocate (not as part of the interrupt) more memory chunks from the "normal" dynamic memory allocator library when low water mark pop out...
Thanks a lot!
If your blocks are always 100 bytes, I recommend making a simple super-quick allocator:
1: You make a memory variable (for instance a 32-bit variable), which contains a bit representing a free/used block. This variable will accomodate up to 32 blocks.
2: You make a fixed allocation of 32 x 100 bytes (or 32 x 128 bytes if you have enough memory).
Finding the first free block (for your allocator) can be done very quickly by using the following piece of code:
iBitMask = ~usedBlockMask;
firstFree = ~(iBitMask & ~(iBitMask - 1));
usedBlockMask |= firstFree;
offset = clz(rbit(firstFree));
return(&sFirstBlock[offset * blockSize]);
Above, the CLZ instruction (Count Leading Zeros) is used with the RBIT instruction to form a Count Trailing Zeros; this will give us the position of the first set bit (which in this case is the first cleared bit we've found).
Checking if a block is allocated (for your 'release block' routine) can be done by ...
bitMask = 1 << ((address - sFirstBlock) / blockSize);
if(usedBlockMask & bitMask)
{
usedBlockMask ^= bitMask;
}
else
// block was not previously allocated; report error somehow.
-The above is quick enough for an interrupt. It will be even quicker if you change the block size to 128 instead of 100 bytes, since bit-shifting can then be used.