ARM-software / CMSIS_5

CMSIS Version 5 Development Repository
http://arm-software.github.io/CMSIS_5/index.html
Apache License 2.0
1.31k stars 1.08k forks source link

RTOS2 - memory block pools vs byte pools? #1652

Open apullin opened 9 months ago

apullin commented 9 months ago

It seems like the RTOS2 interface does not have a way to make a distinction between alloc from block pools (currently covered) and byte pools? Many RTOS's do treat these objects differently. For example, ThreadX provides both.

I presently have to port something that extensively uses both. Maybe there already is a known workaround for this? Hopefully, I am not overlooking something obvious ... ?

(although the one public implementation for CMSIS-RTOS2 for ThreadX I can find appears to just not implement any of the osMemoryPool* functions )

For now, my plan is to add some extensions to a cmsis_os2_ex.h header with a naming like osMemoryBytePool....

JonatanAntoni commented 9 months ago

Hi @apullin,

I'd like to point you to the new locations:

In fact, RTOS2 does not cover byte pools because these have memory fragmentation issues. The only safe way to use byte heap is in a allocate-once-never-free manner. We decided not to expose the implementation's byte allocation mechanism (e.g., https://github.com/ARM-software/CMSIS-RTX/blob/571219ac1b4bdd601c8763f2cb0d2d9bc2cd16c8/Source/rtx_lib.h#L305-L306).

Instead a user wanting to use C/C++ heap can use it via the standard library calls, such as malloc/free or new/delete. In order to make those calls thread safe, we map the library's stubs to RTOS, see https://github.com/ARM-software/CMSIS-Compiler/blob/main/source/armcc/retarget_os_rtos2.c.

apullin commented 9 months ago

There are plenty of ways to mitigate issues with byte pools, and they are still used extensively with the understood limitations. As stated: several major RTOS's support them as first-class features, and they are used extensively in embedded code, with thread-safe interfaces provided, e.g. in ThreadX and Green Hills uVelosity.

malloc and free run on the CRT heap. A byte pool is an RTOS object that can be created statically or dynamically and allocated from. Separate topics.

This is a design shortfall, unfortunately. It looks like I will have to make those extensions to properly support & port this code.

Hope to see them get added in CMSIS6 / CMSIS-RTOS3 interface.

JonatanAntoni commented 9 months ago

There are plenty of ways to mitigate issues with byte pools, and they are still used extensively with the understood limitations.

Of course, if you use them with care. I don't want to devalue it.

malloc and free run on the CRT heap. A byte pool is an RTOS object that can be created statically or dynamically and allocated from. Separate topics.

Well, yes, of course there is some difference. But, given the CRT heap is properly protected for thread safety, what would be other drawbacks compared to an RTOS object? One I can think of is CRT heap is singular while RTOS byte pools can be created multiple times.

As I pointed out above, in RTX5 (which is our reference implementation for CMSIS-RTOS2 API) we have such kind of memory pools as well. But they are not exposed via CMSIS-RTOS2 API. May I ask you to review the API (https://github.com/ARM-software/CMSIS-RTX/blob/c281b5ccf24efc16d37be495e5cbdfe241fef621/Source/rtx_lib.h#L304-L306) if this is what you are after?

apullin commented 9 months ago

Yes, I can see those functions. But that is an RTX implementation.

My observation stands that CMSIS-RTOS2 has a fundamental limitation as an RTOS abstraction layer or a common interface because it has no way of representing a byte pool or a variable-length block pool API, which is a common RTOS feature.

Looking at it again: maybe the workaround is to consider block_size == 0 (and possibly some attr_bits in attr arg to osMemoryPoolNew) to be the case that maps to "byte pool" functionality, instead of "block pool".

However, that is not good design as it pushes a bunch of implicit requirements onto the shim implementation.

JonatanAntoni commented 9 months ago

Yes, I can see those functions. But that is an RTX implementation.

Yes, this is RTX implementation. Would it be sufficient if we would level up todays RTX API to become part of CMSIS-RTOS2 API?

apullin commented 9 months ago

Yes, that probably would be a good idea. But you will need to have separate naming, of course.

Given that the existing osMemoryPool... interface is understood to be block pools, probably introducing just a new set of functions such as osMemoryBytePool... .

And then aliasing osMemoryBlockPool... to osMemoryPool... for the sake of completeness could also be done.

Should be a pretty simple PR - I can submit if you want.

JonatanAntoni commented 9 months ago

Thanks for sharing your opinion. We need to think this carefully. Please mind CMSIS 5 is not under active development any longer. Instead, we can think about adding such a feature as part of CMSIS 6.