summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/objectimpl.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-27 14:16:12 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-31 08:29:44 +0200
commit23fec9f0e18dc4913fab818118f836af150b98f3 (patch)
tree66228f23bbf654117a33e28db7a017eea21fb785 /cpukit/score/include/rtems/score/objectimpl.h
parentscore: Use thread life protection for API mutexes (diff)
downloadrtems-23fec9f0e18dc4913fab818118f836af150b98f3.tar.bz2
score: PR2152: Use allocator mutex for objects
Use allocator mutex for objects allocate/free. This prevents that the thread dispatch latency depends on the workspace/heap fragmentation.
Diffstat (limited to 'cpukit/score/include/rtems/score/objectimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/objectimpl.h147
1 files changed, 137 insertions, 10 deletions
diff --git a/cpukit/score/include/rtems/score/objectimpl.h b/cpukit/score/include/rtems/score/objectimpl.h
index 119f11d829..383f0a738b 100644
--- a/cpukit/score/include/rtems/score/objectimpl.h
+++ b/cpukit/score/include/rtems/score/objectimpl.h
@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_OBJECTIMPL_H
#include <rtems/score/object.h>
+#include <rtems/score/apimutex.h>
#include <rtems/score/isrlevel.h>
#include <rtems/score/threaddispatch.h>
@@ -264,25 +265,120 @@ unsigned int _Objects_API_maximum_class(
);
/**
- * @brief Allocate an object.
+ * @brief Allocates an object without locking the allocator mutex.
*
- * This function allocates an object control block from
- * the inactive chain of free object control blocks.
+ * This function can be called in two contexts
+ * - the executing thread is the owner of the object allocator mutex, or
+ * - in case the system state is not up, e.g. during sequential system
+ * initialization.
*
- * @param[in] information points to an object class information block.
+ * @param[in] information The object information block.
+ *
+ * @retval NULL No object available.
+ * @retval object The allocated object.
+ *
+ * @see _Objects_Allocate() and _Objects_Free().
*/
-Objects_Control *_Objects_Allocate(
+Objects_Control *_Objects_Allocate_unprotected(
Objects_Information *information
);
/**
- * @brief Free an object.
+ * @brief Allocates an object.
*
- * This function frees an object control block to the
- * inactive chain of free object control blocks.
+ * This function locks the object allocator mutex via
+ * _Objects_Allocator_lock(). The caller must later unlock the object
+ * allocator mutex via _Objects_Allocator_unlock(). The caller must unlock the
+ * mutex in any case, even if the allocation failed due to resource shortage.
*
- * @param[in] information points to an object class information block.
- * @param[in] the_object points to the object to deallocate.
+ * A typical object allocation code looks like this:
+ * @code
+ * rtems_status_code some_create( rtems_id *id )
+ * {
+ * rtems_status_code sc;
+ * Some_Control *some;
+ *
+ * // The object allocator mutex protects the executing thread from
+ * // asynchronous thread restart and deletion.
+ * some = (Some_Control *) _Objects_Allocate( &_Some_Information );
+ *
+ * if ( some != NULL ) {
+ * _Some_Initialize( some );
+ * sc = RTEMS_SUCCESSFUL;
+ * } else {
+ * sc = RTEMS_TOO_MANY;
+ * }
+ *
+ * _Objects_Allocator_unlock();
+ *
+ * return sc;
+ * }
+ * @endcode
+ *
+ * @param[in] information The object information block.
+ *
+ * @retval NULL No object available.
+ * @retval object The allocated object.
+ *
+ * @see _Objects_Free().
+ */
+Objects_Control *_Objects_Allocate( Objects_Information *information );
+
+/**
+ * @brief Frees an object.
+ *
+ * Appends the object to the chain of inactive objects.
+ *
+ * @param[in] information The object information block.
+ * @param[in] the_object The object to free.
+ *
+ * @see _Objects_Allocate().
+ *
+ * A typical object deletion code looks like this:
+ * @code
+ * rtems_status_code some_delete( rtems_id id )
+ * {
+ * rtems_status_code sc;
+ * Some_Control *some;
+ * Objects_Locations location;
+ *
+ * // The object allocator mutex protects the executing thread from
+ * // asynchronous thread restart and deletion.
+ * _Objects_Allocator_lock();
+ *
+ * // This will disable thread dispatching, so this starts a thread dispatch
+ * // critical section.
+ * some = (Semaphore_Control *)
+ * _Objects_Get( &_Some_Information, id, &location );
+ *
+ * switch ( location ) {
+ * case OBJECTS_LOCAL:
+ * // After the object close an object get with this identifier will
+ * // fail.
+ * _Objects_Close( &_Some_Information, &some->Object );
+ *
+ * _Some_Delete( some );
+ *
+ * // This enables thread dispatching, so the thread dispatch critical
+ * // section ends here.
+ * _Objects_Put( &some->Object );
+ *
+ * // Thread dispatching is enabled. The object free is only protected
+ * // by the object allocator mutex.
+ * _Objects_Free( &_Some_Information, &some->Object );
+ *
+ * sc = RTEMS_SUCCESSFUL;
+ * break;
+ * default:
+ * sc = RTEMS_INVALID_ID;
+ * break;
+ * }
+ *
+ * _Objects_Allocator_unlock();
+ *
+ * return sc;
+ * }
+ * @endcode
*/
void _Objects_Free(
Objects_Information *information,
@@ -892,6 +988,37 @@ RTEMS_INLINE_ROUTINE void _Objects_Put_for_get_isr_disable(
#endif
}
+/**
+ * @brief Locks the object allocator mutex.
+ *
+ * While holding the allocator mutex the executing thread is protected from
+ * asynchronous thread restart and deletion.
+ *
+ * The usage of the object allocator mutex with the thread life protection
+ * makes it possible to allocate and free objects without thread dispatching
+ * disabled. The usage of a unified workspace and unlimited objects may lead
+ * to heap fragmentation. Thus the execution time of the _Objects_Allocate()
+ * function may increase during system run-time.
+ *
+ * @see _Objects_Allocator_unlock() and _Objects_Allocate().
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Allocator_lock( void )
+{
+ _RTEMS_Lock_allocator();
+}
+
+/**
+ * @brief Unlocks the object allocator mutex.
+ *
+ * In case the mutex is fully unlocked, then this function restores the
+ * previous thread life protection state and thus may not return if the
+ * executing thread was restarted or deleted in the mean-time.
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Allocator_unlock( void )
+{
+ _RTEMS_Unlock_allocator();
+}
+
/** @} */
#ifdef __cplusplus