summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-13 10:28:14 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-20 07:49:39 +0200
commitda82656065d09f7b6aa411ba361287afdd787204 (patch)
tree3a17cae7059c89d111642cb27a1cf55ded61f604
parent33829ce155069462ba410d396da431386369ed08 (diff)
downloadrtems-da82656065d09f7b6aa411ba361287afdd787204.tar.bz2
posix: Rework thread cancellation
Add Thread_Life_state::THREAD_LIFE_CHANGE_DEFERRED and rework the POSIX thread cancellation to use the thread life states. Update #2555. Update #2626.
-rw-r--r--cpukit/posix/Makefile.am3
-rw-r--r--cpukit/posix/include/rtems/posix/cancel.h37
-rw-r--r--cpukit/posix/include/rtems/posix/threadsup.h33
-rw-r--r--cpukit/posix/preinstall.am4
-rw-r--r--cpukit/posix/src/cancel.c45
-rw-r--r--cpukit/posix/src/canceleval.c45
-rw-r--r--cpukit/posix/src/pthread.c7
-rw-r--r--cpukit/posix/src/pthreadcreate.c2
-rw-r--r--cpukit/posix/src/pthreadexit.c29
-rw-r--r--cpukit/posix/src/pthreadinitthreads.c1
-rw-r--r--cpukit/posix/src/setcancelstate.c51
-rw-r--r--cpukit/posix/src/setcanceltype.c54
-rw-r--r--cpukit/posix/src/testcancel.c36
-rw-r--r--cpukit/score/include/rtems/score/thread.h1
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h9
-rw-r--r--cpukit/score/src/threadrestart.c6
16 files changed, 93 insertions, 270 deletions
diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am
index d354f7ec52..a7632a04cc 100644
--- a/cpukit/posix/Makefile.am
+++ b/cpukit/posix/Makefile.am
@@ -31,7 +31,6 @@ endif
# include/rtems/posix
include_rtems_posix_HEADERS += include/rtems/posix/aio_misc.h
-include_rtems_posix_HEADERS += include/rtems/posix/cancel.h
include_rtems_posix_HEADERS += include/rtems/posix/cond.h
include_rtems_posix_HEADERS += include/rtems/posix/condimpl.h
include_rtems_posix_HEADERS += include/rtems/posix/mqueue.h
@@ -78,7 +77,7 @@ libposix_a_SOURCES += src/barrierattrdestroy.c src/barrierattrgetpshared.c \
src/pbarriertranslatereturncode.c src/pbarrierwait.c
## CANCEL_C_FILES
-libposix_a_SOURCES += src/cancel.c src/canceleval.c \
+libposix_a_SOURCES += src/cancel.c \
src/cleanuppush.c src/setcancelstate.c \
src/setcanceltype.c src/testcancel.c
diff --git a/cpukit/posix/include/rtems/posix/cancel.h b/cpukit/posix/include/rtems/posix/cancel.h
deleted file mode 100644
index 52bbcbccec..0000000000
--- a/cpukit/posix/include/rtems/posix/cancel.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file
- *
- * @brief POSIX Thread Cancelation Support
- *
- * This file contains the prototypes and data types used to implement
- * POSIX thread cancelation.
- */
-
-/*
- * COPYRIGHT (c) 1989-2009.
- * 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_POSIX_CANCEL_H
-#define _RTEMS_POSIX_CANCEL_H
-
-#include <rtems/posix/threadsup.h>
-
-/**
- * @brief POSIX evaluate thread cancelation and enable dispatch.
- *
- * This routine separates a piece of code that existed as part of
- * another routine, but had to be separated to improve coverage.
- *
- * @param[in] the_thread is a pointer to the thread to evaluate canceling
- */
-void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch (
- Thread_Control *the_thread
-);
-
-#endif
-/* end of include file */
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
index 3a7cfbc6dc..51c9564c64 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -71,41 +71,8 @@ typedef struct {
* @brief Signal post-switch action in case signals are pending.
*/
Thread_Action Signal_action;
-
- /*******************************************************************/
- /*******************************************************************/
- /*************** POSIX Cancelability ***************/
- /*******************************************************************/
- /*******************************************************************/
-
- /** This is the cancelability state. */
- int cancelability_state;
- /** This is the cancelability type. */
- int cancelability_type;
- /** This indicates if a cancelation has been requested. */
- int cancelation_requested;
} POSIX_API_Control;
-/**
- * @brief POSIX thread exit shared helper.
- *
- * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150
- *
- * This method is a helper routine which ensures that all
- * POSIX thread calls which result in a thread exiting will
- * do so in the same manner.
- *
- * @param[in] the_thread is a pointer to the thread exiting or being canceled
- * @param[in] value_ptr is a pointer the value to be returned by the thread
- *
- * NOTE: Key destructors are executed in the POSIX api delete extension.
- *
- */
-void _POSIX_Thread_Exit(
- Thread_Control *the_thread,
- void *value_ptr
-);
-
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am
index cf1303c954..6fc6b4cc47 100644
--- a/cpukit/posix/preinstall.am
+++ b/cpukit/posix/preinstall.am
@@ -61,10 +61,6 @@ $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h: include/rtems/posix/aio_misc.h $(PROJ
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h
-$(PROJECT_INCLUDE)/rtems/posix/cancel.h: include/rtems/posix/cancel.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cancel.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cancel.h
-
$(PROJECT_INCLUDE)/rtems/posix/cond.h: include/rtems/posix/cond.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.h
diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c
index f103d6574b..9519c45e52 100644
--- a/cpukit/posix/src/cancel.c
+++ b/cpukit/posix/src/cancel.c
@@ -9,6 +9,8 @@
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
* 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.
@@ -23,46 +25,43 @@
#include <rtems/score/isr.h>
#include <rtems/score/threadimpl.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/threadsup.h>
/*
* 18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181
*/
-int pthread_cancel(
- pthread_t thread
-)
+int pthread_cancel( pthread_t thread )
{
- Thread_Control *the_thread;
- POSIX_API_Control *thread_support;
- Objects_Locations location;
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+ Thread_Control *executing;
+ Per_CPU_Control *cpu_self;
/*
* Don't even think about deleting a resource from an ISR.
*/
- if ( _ISR_Is_in_progress() )
+ if ( _ISR_Is_in_progress() ) {
return EPROTO;
+ }
- the_thread = _Thread_Get( thread, &location );
- switch ( location ) {
+ the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
- case OBJECTS_LOCAL:
- thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ if ( the_thread == NULL ) {
+ return ESRCH;
+ }
- thread_support->cancelation_requested = 1;
+ cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+ _ISR_lock_ISR_enable( &lock_context );
- /* This enables dispatch implicitly */
- _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( the_thread );
- return 0;
+ executing = _Per_CPU_Get_executing( cpu_self );
-#if defined(RTEMS_MULTIPROCESSING)
- case OBJECTS_REMOTE:
-#endif
- case OBJECTS_ERROR:
- break;
+ if ( the_thread == executing ) {
+ _Thread_Exit( executing, THREAD_LIFE_TERMINATING, PTHREAD_CANCELED );
+ } else {
+ _Thread_Cancel( the_thread, executing, PTHREAD_CANCELED );
}
- return ESRCH;
+ _Thread_Dispatch_enable( cpu_self );
+ return 0;
}
diff --git a/cpukit/posix/src/canceleval.c b/cpukit/posix/src/canceleval.c
deleted file mode 100644
index 9e02c92375..0000000000
--- a/cpukit/posix/src/canceleval.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file
- *
- * @brief POSIX Function Evaluates Thread Cancellation and Enables Dispatch
- * @ingroup POSIXAPI
- */
-
-/*
- * COPYRIGHT (c) 1989-2009.
- * 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 <pthread.h>
-#include <rtems/system.h>
-#include <rtems/score/thread.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-
-void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch(
- Thread_Control *the_thread
-)
-{
- POSIX_API_Control *thread_support;
-
- thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
- if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
- thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
- thread_support->cancelation_requested ) {
- /* FIXME: This path is broken on SMP */
- _Thread_Unnest_dispatch();
- /* FIXME: Cancelability state may change here */
- _POSIX_Thread_Exit( the_thread, PTHREAD_CANCELED );
- } else
- _Objects_Put( &the_thread->Object );
-
-}
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 12c5ace537..766ac01e5f 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -33,7 +33,6 @@
#include <rtems/score/userextimpl.h>
#include <rtems/score/watchdogimpl.h>
#include <rtems/score/wkspace.h>
-#include <rtems/posix/cancel.h>
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/priorityimpl.h>
#include <rtems/posix/psignalimpl.h>
@@ -209,12 +208,6 @@ static bool _POSIX_Threads_Create_extension(
_POSIX_Priority_From_core( created->current_priority );
/*
- * POSIX 1003.1 1996, 18.2.2.2
- */
- RTEMS_STATIC_ASSERT( PTHREAD_CANCEL_ENABLE == 0, cancelability_state );
- RTEMS_STATIC_ASSERT( PTHREAD_CANCEL_DEFERRED == 0, cancelability_type );
-
- /*
* If the thread is not a posix thread, then all posix signals are blocked
* by default.
*
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index 33fae37776..7f95898b62 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -205,6 +205,8 @@ int pthread_create(
the_thread->Life.state |= THREAD_LIFE_DETACHED;
}
+ the_thread->Life.state |= THREAD_LIFE_CHANGE_DEFERRED;
+
#if defined(RTEMS_SMP) && __RTEMS_HAVE_SYS_CPUSET_H__
_ISR_lock_ISR_disable( &lock_context );
status = _Scheduler_Set_affinity(
diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c
index 3c4d3ebaaf..53c42ff3d0 100644
--- a/cpukit/posix/src/pthreadexit.c
+++ b/cpukit/posix/src/pthreadexit.c
@@ -9,6 +9,8 @@
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
* 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.
@@ -20,41 +22,18 @@
#include <pthread.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/score/assert.h>
-#include <rtems/score/apimutex.h>
#include <rtems/score/threadimpl.h>
-#include <rtems/score/threadqimpl.h>
-void _POSIX_Thread_Exit(
- Thread_Control *the_thread,
- void *value_ptr
-)
+void pthread_exit( void *value_ptr )
{
Thread_Control *executing;
Per_CPU_Control *cpu_self;
- _Assert( _Debug_Is_thread_dispatching_allowed() );
-
cpu_self = _Thread_Dispatch_disable();
executing = _Per_CPU_Get_executing( cpu_self );
- /*
- * Now shut down the thread
- */
- if ( the_thread == executing ) {
- _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr );
- } else {
- _Thread_Cancel( the_thread, executing, value_ptr );
- }
+ _Thread_Exit( executing, THREAD_LIFE_TERMINATING, value_ptr );
_Thread_Dispatch_enable( cpu_self );
-}
-
-void pthread_exit(
- void *value_ptr
-)
-{
- _POSIX_Thread_Exit( _Thread_Get_executing(), value_ptr );
RTEMS_UNREACHABLE();
}
diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c
index 05ceda2120..ff11e8a6b0 100644
--- a/cpukit/posix/src/pthreadinitthreads.c
+++ b/cpukit/posix/src/pthreadinitthreads.c
@@ -27,7 +27,6 @@
#include <rtems/score/stack.h>
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
-#include <rtems/posix/cancel.h>
#include <rtems/posix/posixapi.h>
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/priorityimpl.h>
diff --git a/cpukit/posix/src/setcancelstate.c b/cpukit/posix/src/setcancelstate.c
index a451c2c4b4..b0a42e86b8 100644
--- a/cpukit/posix/src/setcancelstate.c
+++ b/cpukit/posix/src/setcancelstate.c
@@ -9,6 +9,8 @@
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
* 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.
@@ -21,13 +23,8 @@
#include <pthread.h>
#include <errno.h>
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
#include <rtems/score/isr.h>
-#include <rtems/score/thread.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/threadimpl.h>
/*
* 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
@@ -38,36 +35,30 @@ int pthread_setcancelstate(
int *oldstate
)
{
- POSIX_API_Control *thread_support;
- Thread_Control *executing;
-
- /*
- * Don't even think about deleting a resource from an ISR.
- * Besides this request is supposed to be for _Thread_Executing
- * and the ISR context is not a thread.
- */
+ Thread_Life_state new_life_protection;
+ Thread_Life_state previous_life_state;
- if ( _ISR_Is_in_progress() )
+ if ( _ISR_Is_in_progress() ) {
return EPROTO;
+ }
- if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE )
+ if ( state == PTHREAD_CANCEL_DISABLE ) {
+ new_life_protection = THREAD_LIFE_PROTECTED;
+ } else if ( state == PTHREAD_CANCEL_ENABLE ) {
+ new_life_protection = 0;
+ } else {
return EINVAL;
+ }
- _Thread_Disable_dispatch();
-
- executing = _Thread_Executing;
- thread_support = executing ->API_Extensions[ THREAD_API_POSIX ];
-
- if (oldstate != NULL)
- *oldstate = thread_support->cancelability_state;
-
- thread_support->cancelability_state = state;
-
- _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( executing );
+ previous_life_state = _Thread_Set_life_protection( new_life_protection );
- /*
- * _Thread_Enable_dispatch is invoked by above call.
- */
+ if ( oldstate != NULL ) {
+ if ( ( previous_life_state & THREAD_LIFE_PROTECTED ) != 0 ) {
+ *oldstate = PTHREAD_CANCEL_DISABLE;
+ } else {
+ *oldstate = PTHREAD_CANCEL_ENABLE;
+ }
+ }
return 0;
}
diff --git a/cpukit/posix/src/setcanceltype.c b/cpukit/posix/src/setcanceltype.c
index 8c4687a981..701317f1d6 100644
--- a/cpukit/posix/src/setcanceltype.c
+++ b/cpukit/posix/src/setcanceltype.c
@@ -9,6 +9,8 @@
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
* 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.
@@ -21,13 +23,8 @@
#include <pthread.h>
#include <errno.h>
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
#include <rtems/score/isr.h>
-#include <rtems/score/thread.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/threadimpl.h>
/*
* 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
@@ -38,35 +35,34 @@ int pthread_setcanceltype(
int *oldtype
)
{
- POSIX_API_Control *thread_support;
- Thread_Control *executing;
-
- /*
- * Don't even think about deleting a resource from an ISR.
- * Besides this request is supposed to be for _Thread_Executing
- * and the ISR context is not a thread.
- */
+ Thread_Life_state set_life_state;
+ Thread_Life_state previous_life_state;
- if ( _ISR_Is_in_progress() )
+ if ( _ISR_Is_in_progress() ) {
return EPROTO;
+ }
- if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS )
+ if ( type == PTHREAD_CANCEL_DEFERRED ) {
+ set_life_state = THREAD_LIFE_CHANGE_DEFERRED;
+ } else if ( type == PTHREAD_CANCEL_ASYNCHRONOUS ) {
+ set_life_state = 0;
+ } else {
return EINVAL;
+ }
- _Thread_Disable_dispatch();
-
- executing = _Thread_Executing;
- thread_support = executing ->API_Extensions[ THREAD_API_POSIX ];
-
- if ( oldtype != NULL )
- *oldtype = thread_support->cancelability_type;
-
- thread_support->cancelability_type = type;
+ previous_life_state = _Thread_Change_life(
+ THREAD_LIFE_CHANGE_DEFERRED,
+ set_life_state,
+ 0
+ );
- _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( executing );
+ if ( oldtype != NULL ) {
+ if ( ( previous_life_state & THREAD_LIFE_CHANGE_DEFERRED ) != 0 ) {
+ *oldtype = PTHREAD_CANCEL_DEFERRED;
+ } else {
+ *oldtype = PTHREAD_CANCEL_ASYNCHRONOUS;
+ }
+ }
- /*
- * _Thread_Enable_dispatch is invoked by above call.
- */
return 0;
}
diff --git a/cpukit/posix/src/testcancel.c b/cpukit/posix/src/testcancel.c
index c78f26a62b..f50c7782ed 100644
--- a/cpukit/posix/src/testcancel.c
+++ b/cpukit/posix/src/testcancel.c
@@ -9,6 +9,8 @@
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
* 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.
@@ -19,16 +21,9 @@
#endif
#include <pthread.h>
-#include <errno.h>
-#include <rtems/system.h>
-#include <rtems/score/chain.h>
#include <rtems/score/isr.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/wkspace.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/threadimpl.h>
/*
* 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
@@ -36,28 +31,9 @@
void pthread_testcancel( void )
{
- POSIX_API_Control *thread_support;
- Thread_Control *executing;
- bool cancel = false;
-
- /*
- * Don't even think about deleting a resource from an ISR.
- * Besides this request is supposed to be for _Thread_Executing
- * and the ISR context is not a thread.
- */
-
- if ( _ISR_Is_in_progress() )
+ if ( _ISR_Is_in_progress() ) {
return;
+ }
- _Thread_Disable_dispatch();
- executing = _Thread_Executing;
- thread_support = executing->API_Extensions[ THREAD_API_POSIX ];
-
- if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
- thread_support->cancelation_requested )
- cancel = true;
- _Thread_Enable_dispatch();
-
- if ( cancel )
- _POSIX_Thread_Exit( executing, PTHREAD_CANCELED );
+ _Thread_Change_life( 0, 0, THREAD_LIFE_CHANGE_DEFERRED );
}
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 352fb2e434..8672fddfd2 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -526,6 +526,7 @@ typedef enum {
THREAD_LIFE_PROTECTED = 0x1,
THREAD_LIFE_RESTARTING = 0x2,
THREAD_LIFE_TERMINATING = 0x4,
+ THREAD_LIFE_CHANGE_DEFERRED = 0x8,
THREAD_LIFE_DETACHED = 0x10
} Thread_Life_state;
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 6f97ca9866..549ca7ac35 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -205,6 +205,12 @@ bool _Thread_Restart_other(
void _Thread_Yield( Thread_Control *executing );
+Thread_Life_state _Thread_Change_life(
+ Thread_Life_state clear,
+ Thread_Life_state set,
+ Thread_Life_state ignore
+);
+
Thread_Life_state _Thread_Set_life_protection( Thread_Life_state state );
/**
@@ -933,7 +939,8 @@ RTEMS_INLINE_ROUTINE bool _Thread_Is_life_change_allowed(
Thread_Life_state life_state
)
{
- return ( life_state & THREAD_LIFE_PROTECTED ) == 0;
+ return ( life_state
+ & ( THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ) ) == 0;
}
RTEMS_INLINE_ROUTINE bool _Thread_Is_life_changing(
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index fbda7adbb8..33c56e023c 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -558,7 +558,7 @@ void _Thread_Exit(
executing,
0,
set,
- THREAD_LIFE_PROTECTED
+ THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
);
_Thread_State_release( executing, &lock_context );
}
@@ -630,7 +630,7 @@ void _Thread_Restart_self(
executing,
0,
THREAD_LIFE_RESTARTING,
- THREAD_LIFE_PROTECTED
+ THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
);
cpu_self = _Thread_Dispatch_disable_critical( lock_context );
@@ -647,7 +647,7 @@ void _Thread_Restart_self(
RTEMS_UNREACHABLE();
}
-static Thread_Life_state _Thread_Change_life(
+Thread_Life_state _Thread_Change_life(
Thread_Life_state clear,
Thread_Life_state set,
Thread_Life_state ignore