The attached patches are a starting point for discussions for adding capture support to core objects. We started to write notes based on our discussions but the text was harder to follow than just writing some code and commenting on it. It is hard to see the impact of "word changes" versus real changes.
The initial cut has one method call per Score Handler with an enumerated parameter indicating points of interest. Most take a thread pointer and an object id as arguments which can be interpreted based on the event indicated by the enumerated first argument. Some of the items we would like to discuss: 1) Should the number of methods be expanded to one method per point of interest? Having one method per "event" or doing it this way is a no-win choice. The callout table will grow larger with more entries if we go to one function per event. More methods will be in the capture engine. But if we stick this way, there is a smaller callout table, fewer capture methods, but the capture methods likely will have some decode logic. 2) This design focuses on pass paths for points of interest and ignores failure paths, is this the direction we wish to follow? There are potentially LOTS of failure points and the errors will be in the supercore level. Worse, a "try lock" which doesn't get the mutex could end up in a busy loop swamping the capture engine. 3) We think the callout table should be completely populated. The table is either full of methods or not. It is an error not to install a handler for every event. This simplified checks at run-time. 4) We discussed having the Score own a table with stubs so the calls are always present but that could negatively impact minimum footprint. This only puts a single pointer and code to call. This point is arguable if we stick to the small number of handlers approach. Eliminating the "if table installed" check and always making the subroutine call to a stub MIGHT be better. But we thought avoiding a subroutine call in critical paths was best. So this is basically some code using one approach for discussion purposes. It Is only known to compile and this may not be enough for you to compile it. :) We want to discuss the design approach and see where to take this. Jennifer Averett On-Line Applications Research
From 5714fc8121c2c1b7ce821a9f0a3e24f844aba2fa Mon Sep 17 00:00:00 2001 From: Jennifer Averett <jennifer.aver...@oarcorp.com> Date: Wed, 2 Jul 2014 08:28:27 -0500 Subject: [PATCH 1/7] score: core capture initial start point. --- cpukit/score/include/rtems/score/corecapture.h | 190 +++++++++++++++++++++ cpukit/score/include/rtems/score/corecaptureimpl.h | 57 +++++++ cpukit/score/src/corecapture.c | 54 ++++++ 3 files changed, 301 insertions(+) create mode 100644 cpukit/score/include/rtems/score/corecapture.h create mode 100644 cpukit/score/include/rtems/score/corecaptureimpl.h create mode 100644 cpukit/score/src/corecapture.c diff --git a/cpukit/score/include/rtems/score/corecapture.h b/cpukit/score/include/rtems/score/corecapture.h new file mode 100644 index 0000000..be3eb8b --- /dev/null +++ b/cpukit/score/include/rtems/score/corecapture.h @@ -0,0 +1,190 @@ +/** + * @file rtems/score/corecapture.h + * + * @brief Data Associated with the Core Capture options + * + */ + +/* + * COPYRIGHT (c) 2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_SCORE_CORECAPTURE_H +#define _RTEMS_SCORE_CORECAPTURE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/thread.h> + +/** + * @defgroup ScoreCoreCapture Supercore Capture Handler + * + * @ingroup Score + * + * This handler encapsulates functionality which provides the foundation + * for capture of core information to be used in debugging. + */ +/**@{*/ + + +/** + * List of core object handler events of interest + */ +typedef enum { + /** + * Indicates when an object is allocated (e.g. created). + * When the capture method is invoked, + * + * @a id will indicate the object allocated + * @a thread will be the thread executing + */ + CORE_CAPTURE_OBJECT_ALLOCATE, + + /** + * Indicates when an object is freed (e.g. deleted). + * When the capture method is invoked, + * + * @a id will indicate the object to be freed + * @a thread will be the thread executing + */ + CORE_CAPTURE_OBJECT_FREE +} CORE_capture_Core_object_event; + +/** + * Method invoked by Core Object Handler on events + * of interest. + */ +typedef void (*CORE_capture_Object_event_f)( + CORE_capture_Core_object_event event, + Objects_Id id, + Thread_Control *thread +); + +/** + * List of core object handler events of interest + */ +typedef enum { + + /** + * Indicates when a mutex is acquired + * When the capture method is invoked, + * + * @a id will indicate the object id of the mutex + * @a thread will be the thread executing + */ + CORE_CAPTURE_MUTEX_ACQUIRE, + + /** + * Indicates when a mutex is released + * When the capture method is invoked, + * + * @a id will indicate the object id of the mutex + * @a thread will be the thread executing + */ + CORE_CAPTURE_MUTEX_RELEASE, + + /** + * Indicates when a mutex causes the thread to block + * When the capture method is invoked, + * + * @a return_code will will be unused + * @a id will indicate the object id of the mutex + * @a thread will be the thread executing + */ + CORE_CAPTURE_MUTEX_BLOCK, + + /** + * Indicates when a mutex is unblocked + * When the capture method is invoked, + * + * @a id will indicate the object id of the mutex + * @a thread will be the thread executing + * + * @note The reason for the unblock is stored in + * executing->Wait.return_code. This will be used + * to determine if an acquire, or a timeout occured. + */ + CORE_CAPTURE_MUTEX_UNBLOCK, + +} CORE_capture_Core_mutex_event; + + +/** + * Method invoked by Core Mutex Handler on events + * of interest. + */ +typedef void (*CORE_capture_Mutex_event_f)( + CORE_capture_Core_mutex_event event, + Objects_Id id, + Thread_Control *thread +); + +typedef enum { + + /** + * Indicates when a semaphore is acquire + * When the capture method is invoked, + * + * @a id will indicate the object id of the semaphore + * @a thread will be the thread executing + */ + CORE_CAPTURE_SEMAPHORE_ACQUIRE, + + /** + * Indicates when a semaphore is released + * When the capture method is invoked, + * + * @a id will indicate the object id of the semaphore + * @a thread will be the thread executing + */ + CORE_CAPTURE_SEMAPHORE_RELEASE, + + /** + * Indicates when a semaphore causes the thread to block + * When the capture method is invoked, + * + * @a id will indicate the object id of the semaphore + * @a thread will be the thread executing + */ + CORE_CAPTURE_SEMAPHORE_BLOCK, + + /** + * Indicates when a semaphore is unblocked + * When the capture method is invoked, + * + * @a id will indicate the object id of the semaphore + * @a thread will be the thread executing + * + * @note The reason for the unblock is stored in + * executing->Wait.return_code. This will be used + * to determine if an acquire, or a timeout occured. + */ + CORE_CAPTURE_SEMAPHORE_UNBLOCK, + +} CORE_capture_Core_semaphore_event; + +/** + * Method invoked by Core Semaphore Handler on events + * of interest. + */ +typedef void (*CORE_capture_Semaphore_event_f)( + CORE_capture_Core_semaphore_event event, + Objects_Id semaphore, + Thread_Control *thread +); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/corecaptureimpl.h b/cpukit/score/include/rtems/score/corecaptureimpl.h new file mode 100644 index 0000000..27aec25 --- /dev/null +++ b/cpukit/score/include/rtems/score/corecaptureimpl.h @@ -0,0 +1,57 @@ +/** + * @file rtems/score/corecapture.h + * + * @brief Data Associated with the Core Capture options + * + */ + +/* + * COPYRIGHT (c) 2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifndef _RTEMS_SCORE_CORECAPTUREIMPL_H +#define _RTEMS_SCORE_CORECAPTUREIMPL_H + +#include <rtems/score/corecapture.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ScoreCoreCapture + */ +/**@{**/ + +typedef struct { + CORE_capture_Object_event_f object_capture_f; + CORE_capture_Mutex_event_f mutex_capture_f; + CORE_capture_Semaphore_event_f semaphore_capture_f; +} CORE_capture_Control; + +extern CORE_capture_Control *CORE_capture_Functions; + +/** + * Method which registers handlers for all core events + * of intrest. + * + * For simplicity, we should be able to assume that all handlers + * will be present. Otherwise, the run-time code will have to check + * that a handler set is installed AND that a particular handler + * is installed. + */ +int _CORE_capture_Register( CORE_capture_Control *handlers ); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/src/corecapture.c b/cpukit/score/src/corecapture.c new file mode 100644 index 0000000..89c174a --- /dev/null +++ b/cpukit/score/src/corecapture.c @@ -0,0 +1,54 @@ +/** + * @file + * + * @brief + * @ingroup ScoreCoreCapture + */ + +/* + * COPYRIGHT (c) 2014. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/score/corecaptureimpl.h> + +CORE_capture_Control *CORE_capture_Functions = NULL; + +/* + * This way if debug is enabled, this turns into an assertion and + * should be easier to debug. + * + * If this is changed, update the comment in the .h file stating + * this assumption. + */ +#define CORE_CAPTURE_CHECK_METHOD( _method ) \ + do { \ + _Assert( _method != NULL ); \ + if ( _method == NULL) \ + return -1; \ + } while (0) + +/* + * Register all of the capture engine handlers for the super core. + * + */ +int _CORE_capture_Register( CORE_capture_Control *handlers ) +{ + CORE_CAPTURE_CHECK_METHOD(handlers->object_capture_f); + + CORE_CAPTURE_CHECK_METHOD(handlers->mutex_capture_f); + + CORE_CAPTURE_CHECK_METHOD(handlers->semaphore_capture_f); + + *CORE_capture_Functions = *handlers; + + return 0; +} -- 1.8.1.4
From e7e7139a3e24fac78e1884497c1262dfff03b9b9 Mon Sep 17 00:00:00 2001 From: Jennifer Averett <jennifer.aver...@oarcorp.com> Date: Mon, 7 Jul 2014 11:54:35 -0500 Subject: [PATCH 2/7] score: core mutex - Add core capture. --- cpukit/score/include/rtems/score/coremutex.h | 1 + cpukit/score/include/rtems/score/coremuteximpl.h | 9 +++++++++ cpukit/score/src/apimutex.c | 2 +- cpukit/score/src/coremutex.c | 2 ++ cpukit/score/src/coremutexseize.c | 15 +++++++++++++++ cpukit/score/src/coremutexsurrender.c | 8 ++++++++ 6 files changed, 36 insertions(+), 1 deletion(-) diff --git a/cpukit/score/include/rtems/score/coremutex.h b/cpukit/score/include/rtems/score/coremutex.h index ccf6066..f8b8df4 100644 --- a/cpukit/score/include/rtems/score/coremutex.h +++ b/cpukit/score/include/rtems/score/coremutex.h @@ -169,6 +169,7 @@ typedef struct { CORE_mutex_order_list queue; #endif + Objects_Id id; } CORE_mutex_Control; /**@}*/ diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h index cf327e8..aaa5af7 100644 --- a/cpukit/score/include/rtems/score/coremuteximpl.h +++ b/cpukit/score/include/rtems/score/coremuteximpl.h @@ -23,6 +23,7 @@ #include <rtems/score/sysstate.h> #include <rtems/score/threadimpl.h> #include <rtems/score/threadqimpl.h> +#include <rtems/score/corecaptureimpl.h> #ifdef __cplusplus extern "C" { @@ -114,6 +115,7 @@ typedef enum { */ CORE_mutex_Status _CORE_mutex_Initialize( CORE_mutex_Control *the_mutex, + Objects_Id id, Thread_Control *executing, const CORE_mutex_Attributes *the_mutex_attributes, bool initially_locked @@ -268,6 +270,13 @@ RTEMS_INLINE_ROUTINE void _CORE_mutex_Seize_body( _ISR_Enable( level ); _CORE_mutex_Seize_interrupt_blocking( the_mutex, executing, timeout ); } + } else { + if (CORE_capture_Functions) + CORE_capture_Functions->mutex_capture_f( + CORE_CAPTURE_MUTEX_ACQUIRE, + the_mutex->id, + _Thread_Get_executing() + ); } } diff --git a/cpukit/score/src/apimutex.c b/cpukit/score/src/apimutex.c index ec2fbdc..b9708eb 100644 --- a/cpukit/score/src/apimutex.c +++ b/cpukit/score/src/apimutex.c @@ -61,7 +61,7 @@ void _API_Mutex_Allocate( mutex = (API_Mutex_Control *) _Objects_Allocate_unprotected( &_API_Mutex_Information ); - _CORE_mutex_Initialize( &mutex->Mutex, NULL, &attr, false ); + _CORE_mutex_Initialize( &mutex->Mutex, mutex->Object.id, NULL, &attr, false ); _Objects_Open_u32( &_API_Mutex_Information, &mutex->Object, 1 ); diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c index e13c7aa..2402852 100644 --- a/cpukit/score/src/coremutex.c +++ b/cpukit/score/src/coremutex.c @@ -25,6 +25,7 @@ CORE_mutex_Status _CORE_mutex_Initialize( CORE_mutex_Control *the_mutex, + Objects_Id id, Thread_Control *executing, const CORE_mutex_Attributes *the_mutex_attributes, bool initially_locked @@ -37,6 +38,7 @@ CORE_mutex_Status _CORE_mutex_Initialize( */ the_mutex->Attributes = *the_mutex_attributes; + the_mutex->id = id; if ( initially_locked ) { the_mutex->nest_count = 1; diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index 2f9c8da..00bd2b8 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -23,6 +23,7 @@ #include <rtems/score/coremuteximpl.h> #include <rtems/score/schedulerimpl.h> #include <rtems/score/thread.h> +#include <rtems/score/corecaptureimpl.h> #if defined(__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__) void _CORE_mutex_Seize( @@ -63,8 +64,22 @@ void _CORE_mutex_Seize_interrupt_blocking( ); } + if (CORE_capture_Functions) + CORE_capture_Functions->mutex_capture_f( + CORE_CAPTURE_MUTEX_BLOCK, + the_mutex->id, + executing + ); + _Thread_queue_Enqueue( &the_mutex->Wait_queue, executing, timeout ); _Thread_Enable_dispatch(); + + if (CORE_capture_Functions) + CORE_capture_Functions->mutex_capture_f( + CORE_CAPTURE_MUTEX_UNBLOCK, + the_mutex->id, + executing + ); } diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c index 7a7a047..094b859 100644 --- a/cpukit/score/src/coremutexsurrender.c +++ b/cpukit/score/src/coremutexsurrender.c @@ -22,6 +22,7 @@ #include <rtems/score/isr.h> #include <rtems/score/coremuteximpl.h> #include <rtems/score/thread.h> +#include <rtems/score/corecaptureimpl.h> #ifdef __RTEMS_STRICT_ORDER_MUTEX__ static inline void _CORE_mutex_Push_priority( @@ -118,6 +119,13 @@ CORE_mutex_Status _CORE_mutex_Surrender( /* XXX already unlocked -- not right status */ + if (CORE_capture_Functions) + CORE_capture_Functions->mutex_capture_f( + CORE_CAPTURE_MUTEX_RELEASE, + the_mutex->id, + _Thread_Get_executing() + ); + if ( !the_mutex->nest_count ) return CORE_MUTEX_STATUS_SUCCESSFUL; -- 1.8.1.4
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel