Add task terminate hook

Add an RTX hook which gets called when a thread terminates. Add
the function Thread::attach_terminate_hook() to allow users to attach
a hook to this event at runtime.
pull/2642/head
Russ Butler 2016-09-07 00:19:48 -05:00 committed by Russ Butler
parent c319296692
commit 6fd9154d75
6 changed files with 49 additions and 4 deletions

View File

@ -30,6 +30,15 @@
extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
static void (*terminate_hook)(osThreadId id) = 0;
extern "C" void thread_terminate_hook(osThreadId id)
{
if (terminate_hook != (void (*)(osThreadId))NULL) {
terminate_hook(id);
}
}
namespace rtos {
void Thread::constructor(osPriority priority,
@ -336,6 +345,10 @@ void Thread::attach_idle_hook(void (*fptr)(void)) {
rtos_attach_idle_hook(fptr);
}
void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
terminate_hook = fptr;
}
Thread::~Thread() {
// terminate is thread safe
terminate();

View File

@ -320,6 +320,11 @@ public:
*/
static void attach_idle_hook(void (*fptr)(void));
/** Attach a function to be called when a task is killed
@param fptr pointer to the function to be called
*/
static void attach_terminate_hook(void (*fptr)(osThreadId id));
virtual ~Thread();
private:

View File

@ -320,6 +320,14 @@ void os_error (uint32_t err_code) {
for (;;);
}
/*----------------------------------------------------------------------------
* RTX Hooks
*---------------------------------------------------------------------------*/
extern void thread_terminate_hook(osThreadId id);
void sysThreadTerminate(osThreadId id) {
thread_terminate_hook(id);
}
/*----------------------------------------------------------------------------
* RTX Configuration Functions

View File

@ -479,9 +479,10 @@ extern osMessageQId osMessageQId_osTimerMessageQ;
extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR. */
// Thread creation and destruction mutex
// Thread creation and destruction
osMutexDef(osThreadMutex);
osMutexId osMutexId_osThreadMutex;
void sysThreadTerminate(osThreadId id);
// ==== Helper Functions ====
@ -956,6 +957,7 @@ osStatus osThreadTerminate (osThreadId thread_id) {
osStatus status;
if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
osMutexWait(osMutexId_osThreadMutex, osWaitForever);
sysThreadTerminate(thread_id);
// Thread mutex must be held when a thread is created or terminated
status = __svcThreadTerminate(thread_id);
osMutexRelease(osMutexId_osThreadMutex);
@ -983,11 +985,14 @@ osPriority osThreadGetPriority (osThreadId thread_id) {
/// INTERNAL - Not Public
/// Auto Terminate Thread on exit (used implicitly when thread exists)
__NO_RETURN void osThreadExit (void) {
osThreadId id;
// Thread mutex must be held when a thread is created or terminated
// Note - the mutex will be released automatically by the os when
// the thread is terminated
osMutexWait(osMutexId_osThreadMutex, osWaitForever);
__svcThreadTerminate(__svcThreadGetId());
id = __svcThreadGetId();
sysThreadTerminate(id);
__svcThreadTerminate(id);
for (;;); // Should never come here
}

View File

@ -407,6 +407,15 @@ void sysThreadError(osStatus status) {
}
}
/*----------------------------------------------------------------------------
* RTX Hooks
*---------------------------------------------------------------------------*/
extern void thread_terminate_hook(osThreadId id);
void sysThreadTerminate(osThreadId id) {
thread_terminate_hook(id);
}
/*----------------------------------------------------------------------------
* RTX Configuration Functions
*---------------------------------------------------------------------------*/

View File

@ -392,9 +392,10 @@ extern osThreadId osThreadId_osTimerThread;
extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
extern osMessageQId osMessageQId_osTimerMessageQ;
// Thread creation and destruction mutex
// Thread creation and destruction
osMutexDef(osThreadMutex);
osMutexId osMutexId_osThreadMutex;
void sysThreadTerminate(osThreadId id);
// ==== Helper Functions ====
@ -897,6 +898,7 @@ osStatus osThreadTerminate (osThreadId thread_id) {
return osErrorISR; // Not allowed in ISR
}
osMutexWait(osMutexId_osThreadMutex, osWaitForever);
sysThreadTerminate(thread_id);
// Thread mutex must be held when a thread is created or terminated
status = __svcThreadTerminate(thread_id);
osMutexRelease(osMutexId_osThreadMutex);
@ -930,11 +932,14 @@ osPriority osThreadGetPriority (osThreadId thread_id) {
/// INTERNAL - Not Public
/// Auto Terminate Thread on exit (used implicitly when thread exists)
__NO_RETURN void osThreadExit (void) {
osThreadId id;
// Thread mutex must be held when a thread is created or terminated
// Note - the mutex will be released automatically by the os when
// the thread is terminated
osMutexWait(osMutexId_osThreadMutex, osWaitForever);
__svcThreadTerminate(__svcThreadGetId());
id = __svcThreadGetId();
sysThreadTerminate(id);
__svcThreadTerminate(id);
for (;;); // Should never come here
}