2013-02-18 15:32:11 +00:00
/* mbed Microcontroller Library
2019-07-11 15:23:39 +00:00
* Copyright ( c ) 2006 - 2019 ARM Limited
2020-02-20 08:45:04 +00:00
* SPDX - License - Identifier : MIT
*
2013-02-18 15:32:11 +00:00
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*/
# ifndef MEMORYPOOL_H
# define MEMORYPOOL_H
# include <stdint.h>
# include <string.h>
2019-03-14 11:36:02 +00:00
# include "rtos/mbed_rtos_types.h"
# include "rtos/mbed_rtos1_types.h"
# include "rtos/mbed_rtos_storage.h"
2017-06-20 12:00:20 +00:00
# include "platform/NonCopyable.h"
2019-07-11 15:23:39 +00:00
# include "platform/mbed_assert.h"
# include "Kernel.h"
2013-02-18 15:32:11 +00:00
2019-03-14 11:36:02 +00:00
# if MBED_CONF_RTOS_PRESENT || defined(DOXYGEN_ONLY)
2013-02-18 15:32:11 +00:00
namespace rtos {
2019-07-11 15:23:39 +00:00
/** \addtogroup rtos-public-api */
2016-10-04 20:02:44 +00:00
/** @{*/
2019-09-06 21:58:57 +00:00
2017-10-24 15:05:45 +00:00
/**
* \ defgroup rtos_MemoryPool MemoryPool class
* @ {
*/
2018-10-09 19:59:02 +00:00
2013-02-18 15:32:11 +00:00
/** Define and manage fixed-size memory pools of objects of a given type.
@ tparam T data type of a single object ( element ) .
@ tparam queue_sz maximum number of objects ( elements ) in the memory pool .
2017-05-15 14:55:45 +00:00
@ note
Memory considerations : The memory pool data store and control structures will be created on current thread ' s stack ,
both for the mbed OS and underlying RTOS objects ( static or dynamic RTOS memory pools are not being used ) .
2020-04-16 14:11:09 +00:00
@ note
Bare metal profile : This class is not supported .
2013-02-18 15:32:11 +00:00
*/
template < typename T , uint32_t pool_sz >
2017-06-20 12:00:20 +00:00
class MemoryPool : private mbed : : NonCopyable < MemoryPool < T , pool_sz > > {
2018-10-09 19:59:02 +00:00
MBED_STATIC_ASSERT ( pool_sz > 0 , " Invalid memory pool size. Must be greater than 0. " ) ;
2013-02-18 15:32:11 +00:00
public :
2017-12-27 14:46:00 +00:00
/** Create and Initialize a memory pool.
*
2018-01-08 23:43:45 +00:00
* @ note You cannot call this function from ISR context .
2017-12-27 14:46:00 +00:00
*/
2018-10-09 19:59:02 +00:00
MemoryPool ( )
{
2017-05-15 14:55:45 +00:00
memset ( _pool_mem , 0 , sizeof ( _pool_mem ) ) ;
2017-11-03 13:15:57 +00:00
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 ) ;
2017-05-15 14:55:45 +00:00
MBED_ASSERT ( _id ) ;
2013-02-18 15:32:11 +00:00
}
2014-05-29 13:36:51 +00:00
2017-12-27 14:46:00 +00:00
/** Destroy a memory pool
*
2018-01-08 23:43:45 +00:00
* @ note You cannot call this function from ISR context .
2017-12-27 14:46:00 +00:00
*/
2018-10-09 19:59:02 +00:00
~ MemoryPool ( )
{
2017-06-21 10:14:50 +00:00
osMemoryPoolDelete ( _id ) ;
}
2019-03-26 08:48:58 +00:00
/** Allocate a memory block from a memory pool, without blocking.
2019-07-04 12:37:47 +00:00
@ return address of the allocated memory block or nullptr in case of no memory available .
2017-12-27 14:46:00 +00:00
2018-01-08 23:43:45 +00:00
@ note You may call this function from ISR context .
2013-02-18 15:32:11 +00:00
*/
2018-10-09 19:59:02 +00:00
T * alloc ( void )
{
return ( T * ) osMemoryPoolAlloc ( _id , 0 ) ;
2013-02-18 15:32:11 +00:00
}
2014-05-29 13:36:51 +00:00
2020-02-13 09:07:12 +00:00
/** Allocate a memory block from a memory pool, without blocking.
@ return address of the allocated memory block or nullptr in case of no memory available .
@ note You may call this function from ISR context .
*/
T * try_alloc ( void )
{
return ( T * ) osMemoryPoolAlloc ( _id , 0 ) ;
}
2019-03-26 08:48:58 +00:00
/** Allocate a memory block from a memory pool, optionally blocking.
@ param millisec timeout value ( osWaitForever to wait forever )
2019-07-04 12:37:47 +00:00
@ return address of the allocated memory block or nullptr in case of no memory available .
2019-03-26 08:48:58 +00:00
@ note You may call this function from ISR context if the millisec parameter is set to 0.
2020-02-13 09:07:12 +00:00
@ deprecated Pass a chrono duration , not an integer millisecond count . For example use ` 5 s ` rather than ` 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. " )
2019-03-26 08:48:58 +00:00
T * alloc_for ( uint32_t millisec )
{
2020-02-13 09:07:12 +00:00
return alloc_for ( std : : chrono : : duration < uint32_t , std : : milli > ( millisec ) ) ;
}
/** Allocate a memory block from a memory pool, optionally blocking.
@ param rel_time timeout value ( Kernel : : wait_for_u32_forever to wait forever )
@ return address of the allocated memory block or nullptr in case of no memory available .
@ note You may call this function from ISR context if the rel_time parameter is set to 0.
*/
T * alloc_for ( Kernel : : Clock : : duration_u32 rel_time )
{
return ( T * ) osMemoryPoolAlloc ( _id , rel_time . count ( ) ) ;
2019-03-26 08:48:58 +00:00
}
/** Allocate a memory block from a memory pool, blocking.
@ param millisec absolute timeout time , referenced to Kernel : : get_ms_count ( ) .
2019-07-04 12:37:47 +00:00
@ return address of the allocated memory block or nullptr in case of no memory available .
2019-03-26 08:48:58 +00:00
@ note You cannot call this function from ISR context .
@ note the underlying RTOS may have a limit to the maximum wait time
due to internal 32 - bit computations , but this is guaranteed to work if the
wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
the wait will time out earlier than specified .
2020-02-13 09:07:12 +00:00
@ deprecated Pass a chrono time_point , not an integer millisecond count . For example use ` Kernel : : Clock : : now ( ) + 5 s `
rather than ` Kernel : : get_ms_count ( ) + 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`. " )
2019-03-26 08:48:58 +00:00
T * alloc_until ( uint64_t millisec )
{
2020-02-13 09:07:12 +00:00
return alloc_until ( Kernel : : Clock : : time_point ( std : : chrono : : duration < uint64_t , std : : milli > ( millisec ) ) ) ;
}
/** Allocate a memory block from a memory pool, blocking.
@ param abs_time absolute timeout time , referenced to Kernel : : Clock .
@ return address of the allocated memory block or nullptr in case of no memory available .
@ note You cannot call this function from ISR context .
@ note the underlying RTOS may have a limit to the maximum wait time
due to internal 32 - bit computations , but this is guaranteed to work if the
wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
the wait will time out earlier than specified .
*/
T * alloc_until ( Kernel : : Clock : : time_point abs_time )
{
Kernel : : Clock : : time_point now = Kernel : : Clock : : now ( ) ;
Kernel : : Clock : : duration_u32 rel_time ;
if ( now > = abs_time ) {
rel_time = rel_time . zero ( ) ;
} else if ( abs_time - now > Kernel : : wait_for_u32_max ) {
rel_time = Kernel : : wait_for_u32_max ;
2019-03-26 08:48:58 +00:00
} else {
2020-02-13 09:07:12 +00:00
rel_time = abs_time - now ;
2019-03-26 08:48:58 +00:00
}
2020-02-13 09:07:12 +00:00
return alloc_for ( rel_time ) ;
2019-03-26 08:48:58 +00:00
}
/** Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
2019-07-04 12:37:47 +00:00
@ return address of the allocated memory block or nullptr in case of no memory available .
2017-12-27 14:46:00 +00:00
2018-01-08 23:43:45 +00:00
@ note You may call this function from ISR context .
2013-02-18 15:32:11 +00:00
*/
2018-10-09 19:59:02 +00:00
T * calloc ( void )
{
2019-03-26 08:48:58 +00:00
T * item = alloc ( ) ;
2019-07-04 12:37:47 +00:00
if ( item ! = nullptr ) {
2019-03-26 08:48:58 +00:00
memset ( item , 0 , sizeof ( T ) ) ;
}
return item ;
}
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
@ param millisec timeout value ( osWaitForever to wait forever )
2019-07-04 12:37:47 +00:00
@ return address of the allocated memory block or nullptr in case of no memory available .
2019-03-26 08:48:58 +00:00
@ note You may call this function from ISR context if the millisec parameter is set to 0.
2020-02-13 09:07:12 +00:00
@ deprecated Pass a chrono duration , not an integer millisecond count . For example use ` 5 s ` rather than ` 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`. " )
2019-03-26 08:48:58 +00:00
T * calloc_for ( uint32_t millisec )
{
2020-02-13 09:07:12 +00:00
return calloc_for ( std : : chrono : : duration < uint32_t , std : : milli > ( millisec ) ) ;
}
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
@ param rel_time timeout value ( Kernel : : wait_for_u32_forever to wait forever )
@ return address of the allocated memory block or nullptr in case of no memory available .
@ note You may call this function from ISR context if the rel_time parameter is set to 0.
*/
T * calloc_for ( Kernel : : Clock : : duration_u32 rel_time )
{
T * item = alloc_for ( rel_time ) ;
2019-07-04 12:37:47 +00:00
if ( item ! = nullptr ) {
2019-03-26 08:48:58 +00:00
memset ( item , 0 , sizeof ( T ) ) ;
}
return item ;
}
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
@ param millisec absolute timeout time , referenced to Kernel : : get_ms_count ( ) .
2019-07-04 12:37:47 +00:00
@ return address of the allocated memory block or nullptr in case of no memory available .
2019-03-26 08:48:58 +00:00
@ note You cannot call this function from ISR context .
@ note the underlying RTOS may have a limit to the maximum wait time
due to internal 32 - bit computations , but this is guaranteed to work if the
wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
the wait will time out earlier than specified .
2020-02-13 09:07:12 +00:00
@ deprecated Pass a chrono time_point , not an integer millisecond count . For example use ` Kernel : : Clock : : now ( ) + 5 s `
rather than ` Kernel : : get_ms_count ( ) + 5000 ` .
2019-03-26 08:48:58 +00:00
*/
2020-02-13 09:07:12 +00:00
MBED_DEPRECATED_SINCE ( " mbed-os-6.0.0 " , " Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`. " )
2019-03-26 08:48:58 +00:00
T * calloc_until ( uint64_t millisec )
{
2020-02-13 09:07:12 +00:00
return alloc_until ( Kernel : : Clock : : time_point ( std : : chrono : : duration < uint64_t , std : : milli > ( millisec ) ) ) ;
}
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
@ param abs_time absolute timeout time , referenced to Kernel : : Clock .
@ return address of the allocated memory block or nullptr in case of no memory available .
@ note You cannot call this function from ISR context .
@ note the underlying RTOS may have a limit to the maximum wait time
due to internal 32 - bit computations , but this is guaranteed to work if the
wait is < = 0x7fffffff milliseconds ( ~ 24 days ) . If the limit is exceeded ,
the wait will time out earlier than specified .
*/
T * calloc_until ( Kernel : : Clock : : time_point abs_time )
{
T * item = alloc_until ( abs_time ) ;
2019-07-04 12:37:47 +00:00
if ( item ! = nullptr ) {
2017-05-15 14:55:45 +00:00
memset ( item , 0 , sizeof ( T ) ) ;
}
return item ;
2013-02-18 15:32:11 +00:00
}
2014-05-29 13:36:51 +00:00
2017-05-15 14:55:45 +00:00
/** Free a memory block.
2017-06-06 01:51:37 +00:00
@ param block address of the allocated memory block to be freed .
2017-08-21 08:40:49 +00:00
@ return osOK on successful deallocation , osErrorParameter if given memory block id
2019-07-04 12:37:47 +00:00
is nullptr or invalid , or osErrorResource if given memory block is in an
2017-08-21 08:40:49 +00:00
invalid memory pool state .
2018-01-08 23:43:45 +00:00
@ note You may call this function from ISR context .
2013-02-18 15:32:11 +00:00
*/
2018-10-09 19:59:02 +00:00
osStatus free ( T * block )
{
2019-03-26 08:48:58 +00:00
return osMemoryPoolFree ( _id , block ) ;
2013-02-18 15:32:11 +00:00
}
private :
2017-05-15 14:55:45 +00:00
osMemoryPoolId_t _id ;
2019-05-29 14:03:38 +00:00
char _pool_mem [ MBED_RTOS_STORAGE_MEM_POOL_MEM_SIZE ( pool_sz , sizeof ( T ) ) ] ;
2017-05-15 14:55:45 +00:00
mbed_rtos_storage_mem_pool_t _obj_mem ;
2013-02-18 15:32:11 +00:00
} ;
2017-10-24 15:05:45 +00:00
/** @}*/
/** @}*/
2013-02-18 15:32:11 +00:00
}
# endif
2019-03-14 11:36:02 +00:00
# endif