Skip to content

make MemoryPool compatible with classes #14509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions rtos/include/rtos/MemoryPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,31 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
*/
MemoryPool()
{
if (!std::is_trivial<T>::value) {
_T_offset = sizeof(void *); // (T*) is behind free block pointer in block memory
} else {
_T_offset = 0; // no correction for trivial type
}

memset(_pool_mem, 0, sizeof(_pool_mem));
osMemoryPoolAttr_t attr = { 0 };
attr.mp_mem = _pool_mem;
attr.mp_size = sizeof(_pool_mem);
attr.cb_mem = &_obj_mem;
attr.cb_size = sizeof(_obj_mem);
_id = osMemoryPoolNew(pool_sz, sizeof(T), &attr);
_id = osMemoryPoolNew(pool_sz, sizeof(T) + _T_offset, &attr);
MBED_ASSERT(_id);

if (!std::is_trivial<T>::value) {
_T_offset = sizeof(void *); // (T*) is behind free block pointer in block memory
// initialize elements
uint32_t block_size = osMemoryPoolGetBlockSize(_id);
for (uint32_t i = 0; i < pool_sz; i++) {
void *addr = &_pool_mem[block_size * i + _T_offset];
// use displacement new to call constructor without memory allocaction
new (addr) T();
}
}
}

/** Destroy a memory pool
Expand All @@ -81,6 +98,14 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
*/
~MemoryPool()
{
if (!std::is_trivial<T>::value) {
uint32_t block_size = osMemoryPoolGetBlockSize(_id);
// call destructor for each element
for (uint32_t i = 0; i < pool_sz; i++) {
T *pT = (T *)(&_pool_mem[block_size * i + _T_offset]);
pT->~T();
}
}
osMemoryPoolDelete(_id);
}

Expand All @@ -103,7 +128,12 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
*/
T *try_alloc()
{
return (T *)osMemoryPoolAlloc(_id, 0);
char *pBlock = (char *)osMemoryPoolAlloc(_id, 0);
if (pBlock != nullptr) {
return (T *)(pBlock + _T_offset);
} else {
return nullptr;
}
}

/** Allocate a memory block from a memory pool, optionally blocking.
Expand All @@ -127,7 +157,12 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
*/
T *try_alloc_for(Kernel::Clock::duration_u32 rel_time)
{
return (T *)osMemoryPoolAlloc(_id, rel_time.count());
char *pBlock = (char *)osMemoryPoolAlloc(_id, rel_time.count());
if (pBlock != nullptr) {
return (T *)(pBlock + _T_offset);
} else {
return nullptr;
}
}

/** Allocate a memory block from a memory pool, blocking.
Expand Down Expand Up @@ -273,13 +308,18 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
*/
osStatus free(T *block)
{
return osMemoryPoolFree(_id, block);
if (block != nullptr) {
return osMemoryPoolFree(_id, ((char *)block) - _T_offset);
} else {
return osMemoryPoolFree(_id, block);
}
}

private:
osMemoryPoolId_t _id;
char _pool_mem[MBED_RTOS_STORAGE_MEM_POOL_MEM_SIZE(pool_sz, sizeof(T))];
char _pool_mem[MBED_RTOS_STORAGE_MEM_POOL_MEM_SIZE(pool_sz, sizeof(T) + sizeof(void *))];
mbed_rtos_storage_mem_pool_t _obj_mem;
uint16_t _T_offset;
};
/** @}*/
/** @}*/
Expand Down