[PATCH 19/38] Optional POSIX Cleanup initialization

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Jan 26 15:37:45 UTC 2016


Update #2408.
---
 cpukit/posix/Makefile.am                     |  4 +-
 cpukit/posix/include/rtems/posix/cancel.h    | 13 -----
 cpukit/posix/include/rtems/posix/threadsup.h |  4 --
 cpukit/posix/src/cancelrun.c                 | 50 ------------------
 cpukit/posix/src/cleanuppop.c                | 44 ----------------
 cpukit/posix/src/cleanuppush.c               | 79 +++++++++++++++++++++++++---
 cpukit/posix/src/pthread.c                   | 16 +-----
 cpukit/score/include/rtems/score/percpu.h    |  7 +++
 cpukit/score/include/rtems/score/thread.h    |  7 +++
 cpukit/score/include/rtems/sysinit.h         |  1 +
 testsuites/sptests/spsysinit01/init.c        | 26 +++++++++
 11 files changed, 115 insertions(+), 136 deletions(-)
 delete mode 100644 cpukit/posix/src/cancelrun.c
 delete mode 100644 cpukit/posix/src/cleanuppop.c

diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am
index ad9d29f..54a298a 100644
--- a/cpukit/posix/Makefile.am
+++ b/cpukit/posix/Makefile.am
@@ -78,8 +78,8 @@ 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 src/cancelrun.c \
-    src/cleanuppop.c src/cleanuppush.c src/setcancelstate.c \
+libposix_a_SOURCES += src/cancel.c src/canceleval.c \
+    src/cleanuppush.c src/setcancelstate.c \
     src/setcanceltype.c src/testcancel.c
 
 ## CONDITION_VARIABLE_C_FILES
diff --git a/cpukit/posix/include/rtems/posix/cancel.h b/cpukit/posix/include/rtems/posix/cancel.h
index 9e60c26..52bbcbc 100644
--- a/cpukit/posix/include/rtems/posix/cancel.h
+++ b/cpukit/posix/include/rtems/posix/cancel.h
@@ -22,19 +22,6 @@
 #include <rtems/posix/threadsup.h>
 
 /**
- * @brief POSIX run thread cancelation.
- *
- * This support routine runs through the chain of cancel handlers that
- * have been registered and executes them.
- *
- * @param[in] the_thread is a pointer to the thread whose cancelation handlers
- *            should be run
- */
-void _POSIX_Threads_cancel_run(
-  Thread_Control *the_thread
-);
-
-/**
  * @brief POSIX evaluate thread cancelation and enable dispatch. 
  *
  * This routine separates a piece of code that existed as part of
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
index bf80c63..55db35d 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -85,10 +85,6 @@ typedef struct {
   int                     cancelability_type;
   /** This indicates if a cancelation has been requested. */
   int                     cancelation_requested;
-  /**
-   * @brief LIFO list of cleanup contexts.
-   */
-  struct _pthread_cleanup_context *last_cleanup_context;
 } POSIX_API_Control;
 
 /**
diff --git a/cpukit/posix/src/cancelrun.c b/cpukit/posix/src/cancelrun.c
deleted file mode 100644
index 3e93b3d..0000000
--- a/cpukit/posix/src/cancelrun.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file
- *
- * @brief Executes a thread's cancellation handlers
- * @ingroup POSIXAPI
- */
-
-/*
- *  COPYRIGHT (c) 1989-2008.
- *  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/score/thread.h>
-#include <rtems/score/threaddispatch.h>
-#include <rtems/posix/cancel.h>
-#include <rtems/posix/threadsup.h>
-
-void _POSIX_Threads_cancel_run(
-  Thread_Control *the_thread
-)
-{
-  struct _pthread_cleanup_context *context;
-  POSIX_API_Control               *thread_support;
-
-  _Thread_Disable_dispatch();
-
-  thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
-  thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE;
-
-  context = thread_support->last_cleanup_context;
-  thread_support->last_cleanup_context = NULL;
-
-  _Thread_Enable_dispatch();
-
-  while ( context != NULL ) {
-    ( *context->_routine )( context->_arg );
-
-    context = context->_previous;
-  }
-}
diff --git a/cpukit/posix/src/cleanuppop.c b/cpukit/posix/src/cleanuppop.c
deleted file mode 100644
index 081c97a..0000000
--- a/cpukit/posix/src/cleanuppop.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file
- *
- * @brief Removes Routine from Top of Calling Thread's stack and Invoke it 
- * @ingroup POSIXAPI
- */
-
-/*
- *  COPYRIGHT (c) 1989-2008.
- *  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/score/thread.h>
-#include <rtems/score/threaddispatch.h>
-#include <rtems/posix/threadsup.h>
-
-void _pthread_cleanup_pop(
-  struct _pthread_cleanup_context *context,
-  int                              execute
-)
-{
-  POSIX_API_Control *thread_support;
-
-  if ( execute != 0 ) {
-    ( *context->_routine )( context->_arg );
-  }
-
-  _Thread_Disable_dispatch();
-
-  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
-  thread_support->last_cleanup_context = context->_previous;
-
-  _Thread_Enable_dispatch();
-}
diff --git a/cpukit/posix/src/cleanuppush.c b/cpukit/posix/src/cleanuppush.c
index bf99b06..0e55458 100644
--- a/cpukit/posix/src/cleanuppush.c
+++ b/cpukit/posix/src/cleanuppush.c
@@ -1,7 +1,7 @@
 /**
  * @file
  *
- * @brief Establishing Cancellation Handlers
+ * @brief POSIX Cleanup Support
  * @ingroup POSIXAPI
  */
 
@@ -20,9 +20,10 @@
 
 #include <pthread.h>
 
+#include <rtems/sysinit.h>
 #include <rtems/score/thread.h>
 #include <rtems/score/threaddispatch.h>
-#include <rtems/posix/threadsup.h>
+#include <rtems/score/userextimpl.h>
 
 void _pthread_cleanup_push(
   struct _pthread_cleanup_context   *context,
@@ -30,7 +31,8 @@ void _pthread_cleanup_push(
   void                              *arg
 )
 {
-  POSIX_API_Control *thread_support;
+  Per_CPU_Control *cpu_self;
+  Thread_Control  *executing;
 
   context->_routine = routine;
   context->_arg = arg;
@@ -38,11 +40,72 @@ void _pthread_cleanup_push(
   /* This value is unused, just provide a deterministic value */
   context->_canceltype = -1;
 
-  _Thread_Disable_dispatch();
+  cpu_self = _Thread_Dispatch_disable();
 
-  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
-  context->_previous = thread_support->last_cleanup_context;
-  thread_support->last_cleanup_context = context;
+  executing = _Per_CPU_Get_executing( cpu_self );
+  context->_previous = executing->last_cleanup_context;
+  executing->last_cleanup_context = context;
 
-  _Thread_Enable_dispatch();
+  _Thread_Dispatch_enable( cpu_self );
 }
+
+void _pthread_cleanup_pop(
+  struct _pthread_cleanup_context *context,
+  int                              execute
+)
+{
+  Per_CPU_Control *cpu_self;
+  Thread_Control  *executing;
+
+  if ( execute != 0 ) {
+    ( *context->_routine )( context->_arg );
+  }
+
+  cpu_self = _Thread_Dispatch_disable();
+
+  executing = _Per_CPU_Get_executing( cpu_self );
+  executing->last_cleanup_context = context->_previous;
+
+  _Thread_Dispatch_enable( cpu_self );
+}
+
+static void _POSIX_Cleanup_terminate_extension( Thread_Control *the_thread )
+{
+  struct _pthread_cleanup_context *context;
+
+  context = the_thread->last_cleanup_context;
+  the_thread->last_cleanup_context = NULL;
+
+  while ( context != NULL ) {
+    ( *context->_routine )( context->_arg );
+
+    context = context->_previous;
+  }
+}
+
+static void _POSIX_Cleanup_restart_extension(
+  Thread_Control *executing,
+  Thread_Control *the_thread
+)
+{
+  (void) executing;
+  _POSIX_Cleanup_terminate_extension( the_thread );
+}
+
+static User_extensions_Control _POSIX_Cleanup_extensions = {
+  .Callouts = {
+    .thread_restart = _POSIX_Cleanup_restart_extension,
+    .thread_terminate = _POSIX_Cleanup_terminate_extension
+  }
+};
+
+static void _POSIX_Cleanup_initialization( void )
+{
+  _User_extensions_Add_API_set( &_POSIX_Cleanup_extensions );
+}
+
+RTEMS_SYSINIT_ITEM(
+  _POSIX_Cleanup_initialization,
+  RTEMS_SYSINIT_POSIX_CLEANUP,
+  RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 691dfc3..6c4ea5c 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -240,15 +240,6 @@ static bool _POSIX_Threads_Create_extension(
   return true;
 }
 
-static void _POSIX_Threads_Restart_extension(
-  Thread_Control *executing,
-  Thread_Control *restarted
-)
-{
-  (void) executing;
-  _POSIX_Threads_cancel_run( restarted );
-}
-
 static void _POSIX_Threads_Terminate_extension(
   Thread_Control *executing
 )
@@ -259,11 +250,6 @@ static void _POSIX_Threads_Terminate_extension(
 
   api = executing->API_Extensions[ THREAD_API_POSIX ];
 
-  /*
-   *  Run the POSIX cancellation handlers
-   */
-  _POSIX_Threads_cancel_run( executing );
-
   _Thread_Disable_dispatch();
 
   /*
@@ -326,7 +312,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = {
   { { NULL, NULL }, NULL },
   { _POSIX_Threads_Create_extension,          /* create */
     NULL,                                     /* start */
-    _POSIX_Threads_Restart_extension,         /* restart */
+    NULL,                                     /* restart */
     NULL,                                     /* delete */
     NULL,                                     /* switch */
     NULL,                                     /* begin */
diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
index 806c290..4ad530f 100644
--- a/cpukit/score/include/rtems/score/percpu.h
+++ b/cpukit/score/include/rtems/score/percpu.h
@@ -516,6 +516,13 @@ static inline uint32_t _Per_CPU_Get_index( const Per_CPU_Control *cpu )
   return ( uint32_t ) ( per_cpu_envelope - &_Per_CPU_Information[ 0 ] );
 }
 
+static inline struct _Thread_Control *_Per_CPU_Get_executing(
+  const Per_CPU_Control *cpu
+)
+{
+  return cpu->executing;
+}
+
 static inline bool _Per_CPU_Is_processor_started(
   const Per_CPU_Control *cpu
 )
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index f4d76d8..69caef1 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -39,6 +39,8 @@
   #include <rtems/score/cpuset.h>
 #endif
 
+struct _pthread_cleanup_context;
+
 struct Per_CPU_Control;
 
 struct Scheduler_Control;
@@ -851,6 +853,11 @@ struct _Thread_Control {
   Thread_Capture_control                Capture;
 
   /**
+   * @brief LIFO list of POSIX cleanup contexts.
+   */
+  struct _pthread_cleanup_context *last_cleanup_context;
+
+  /**
    * @brief Variable length array of user extension pointers.
    *
    * The length is defined by the application via <rtems/confdefs.h>.
diff --git a/cpukit/score/include/rtems/sysinit.h b/cpukit/score/include/rtems/sysinit.h
index 1da3b30..dcd0e18 100644
--- a/cpukit/score/include/rtems/sysinit.h
+++ b/cpukit/score/include/rtems/sysinit.h
@@ -44,6 +44,7 @@ extern "C" {
 #define RTEMS_SYSINIT_CLASSIC_BARRIER            00034a
 #define RTEMS_SYSINIT_POSIX_SIGNALS              000360
 #define RTEMS_SYSINIT_POSIX_THREADS              000361
+#define RTEMS_SYSINIT_POSIX_CLEANUP              00036a
 #define RTEMS_SYSINIT_IDLE_THREADS               000380
 #define RTEMS_SYSINIT_BSP_LIBC                   000400
 #define RTEMS_SYSINIT_BEFORE_DRIVERS             000500
diff --git a/testsuites/sptests/spsysinit01/init.c b/testsuites/sptests/spsysinit01/init.c
index 3bbea9c..8925099 100644
--- a/testsuites/sptests/spsysinit01/init.c
+++ b/testsuites/sptests/spsysinit01/init.c
@@ -17,6 +17,7 @@
 #endif
 
 #include <assert.h>
+#include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -40,6 +41,7 @@
 #include <rtems/rtems/tasksimpl.h>
 #include <rtems/rtems/timerimpl.h>
 #include <rtems/score/apimutex.h>
+#include <rtems/score/chainimpl.h>
 #include <rtems/score/sysstate.h>
 #include <rtems/score/userextimpl.h>
 #include <rtems/score/wkspace.h>
@@ -84,6 +86,8 @@ typedef enum {
   POSIX_SIGNALS_POST,
   POSIX_THREADS_PRE,
   POSIX_THREADS_POST,
+  POSIX_CLEANUP_PRE,
+  POSIX_CLEANUP_POST,
 #endif /* RTEMS_POSIX_API */
   IDLE_THREADS_PRE,
   IDLE_THREADS_POST,
@@ -358,6 +362,24 @@ LAST(RTEMS_SYSINIT_POSIX_THREADS)
   next_step(POSIX_THREADS_POST);
 }
 
+static size_t user_extensions_pre_posix_cleanup;
+
+FIRST(RTEMS_SYSINIT_POSIX_CLEANUP)
+{
+  user_extensions_pre_posix_cleanup =
+    _Chain_Node_count_unprotected(&_User_extensions_List);
+  next_step(POSIX_CLEANUP_PRE);
+}
+
+LAST(RTEMS_SYSINIT_POSIX_CLEANUP)
+{
+  assert(
+    user_extensions_pre_posix_cleanup + 1 ==
+      _Chain_Node_count_unprotected(&_User_extensions_List)
+  );
+  next_step(POSIX_CLEANUP_POST);
+}
+
 #endif /* RTEMS_POSIX_API */
 
 FIRST(RTEMS_SYSINIT_IDLE_THREADS)
@@ -435,6 +457,10 @@ LAST(RTEMS_SYSINIT_BSP_POST_DRIVERS)
 
 static void Init(rtems_task_argument arg)
 {
+#ifdef RTEMS_POSIX_API
+  pthread_cleanup_push(NULL, NULL);
+  pthread_cleanup_pop(0);
+#endif /* RTEMS_POSIX_API */
   next_step(INIT_TASK);
   rtems_test_endk();
   exit(0);
-- 
1.8.4.5




More information about the devel mailing list