[rtems commit] score: Introduce Thread_Entry_information

Sebastian Huber sebh at rtems.org
Mon Jan 11 07:47:07 UTC 2016


Module:    rtems
Branch:    master
Commit:    ccd54344d904b657123e4e4ba795a32212382be2
Changeset: http://git.rtems.org/rtems/commit/?id=ccd54344d904b657123e4e4ba795a32212382be2

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Jan  7 09:55:45 2016 +0100

score: Introduce Thread_Entry_information

This avoids potential dead code in _Thread_Handler().  It gets rid of
the dangerous function pointer casts.

Update #2514.

---

 c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h       |  2 +-
 .../lib/libbsp/epiphany/epiphany_sim/include/bsp.h |  2 +-
 c/src/lib/libbsp/i386/pc386/include/bsp.h          |  2 +-
 c/src/lib/libbsp/m32c/m32cbsp/include/bsp.h        |  2 +-
 c/src/lib/libbsp/moxie/moxiesim/include/bsp.h      |  2 +-
 c/src/lib/libbsp/sh/shsim/include/bsp.h            |  2 +-
 c/src/lib/libbsp/shared/clock_driver_simidle.c     |  2 +-
 c/src/lib/libbsp/shared/clockdrv_shell.h           |  4 +-
 c/src/lib/libbsp/sparc64/niagara/include/bsp.h     |  2 +-
 c/src/lib/libbsp/sparc64/usiii/include/bsp.h       |  2 +-
 c/src/lib/libbsp/v850/gdbv850sim/include/bsp.h     |  2 +-
 c/src/lib/libcpu/bfin/clock/clock.c                |  4 +-
 c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c    |  4 +-
 cpukit/libmisc/cpuuse/cpuusagetop.c                |  2 +-
 cpukit/libmisc/monitor/mon-task.c                  |  3 +-
 cpukit/libmisc/monitor/monitor.h                   |  3 +-
 cpukit/posix/src/pthreadcreate.c                   | 18 +++--
 cpukit/posix/src/pthreadinitthreads.c              |  7 +-
 cpukit/rtems/src/taskinitusers.c                   |  7 +-
 cpukit/rtems/src/taskrestart.c                     |  5 +-
 cpukit/rtems/src/taskstart.c                       | 24 +++---
 cpukit/sapi/include/rtems/config.h                 |  2 +-
 cpukit/score/Makefile.am                           |  3 +
 cpukit/score/include/rtems/score/thread.h          | 90 +++++++++++-----------
 cpukit/score/include/rtems/score/threadimpl.h      | 34 ++++----
 cpukit/score/src/threadcreateidle.c                | 17 ++--
 cpukit/score/src/threadentryadaptoridle.c          | 26 +++++++
 cpukit/score/src/threadentryadaptornumeric.c       | 26 +++++++
 cpukit/score/src/threadentryadaptorpointer.c       | 26 +++++++
 cpukit/score/src/threadglobalconstruction.c        | 19 ++---
 cpukit/score/src/threadhandler.c                   | 37 +--------
 cpukit/score/src/threadrestart.c                   | 10 +--
 cpukit/score/src/threadstart.c                     | 17 +---
 testsuites/samples/minimum/init.c                  | 11 +--
 testsuites/sptests/sp54/init.c                     |  9 +--
 .../sptests/spintrcritical_support/intrcritical.c  |  4 +-
 36 files changed, 234 insertions(+), 198 deletions(-)

diff --git a/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h b/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h
index be69b6c..ccf3250 100644
--- a/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h
+++ b/c/src/lib/libbsp/arm/gdbarmsim/include/bsp.h
@@ -45,7 +45,7 @@ extern "C" {
 /**
  * @brief Support for simulated clock tick
  */
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 
 /*
diff --git a/c/src/lib/libbsp/epiphany/epiphany_sim/include/bsp.h b/c/src/lib/libbsp/epiphany/epiphany_sim/include/bsp.h
index e9c5b55..b9e7fea 100644
--- a/c/src/lib/libbsp/epiphany/epiphany_sim/include/bsp.h
+++ b/c/src/lib/libbsp/epiphany/epiphany_sim/include/bsp.h
@@ -56,7 +56,7 @@ extern "C" {
  *
  * @{
  */
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 /** @} */
 
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index d9f24e4..d68af4d 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -198,7 +198,7 @@ void rtems_irq_mngt_init(void);          /* from 'irq_init.c' */
    *
    *  @brief Clock Tick Support Package
    */
-   Thread clock_driver_sim_idle_body(uintptr_t);
+   void *clock_driver_sim_idle_body(uintptr_t);
    #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
   /*  
    * hack to kill some time. Hopefully hitting a hardware register is slower
diff --git a/c/src/lib/libbsp/m32c/m32cbsp/include/bsp.h b/c/src/lib/libbsp/m32c/m32cbsp/include/bsp.h
index 2889808..e5c0137 100644
--- a/c/src/lib/libbsp/m32c/m32cbsp/include/bsp.h
+++ b/c/src/lib/libbsp/m32c/m32cbsp/include/bsp.h
@@ -42,7 +42,7 @@ extern "C" {
   *  @brief Clock Tick Support Package
   */
 
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 
 #ifdef __cplusplus
diff --git a/c/src/lib/libbsp/moxie/moxiesim/include/bsp.h b/c/src/lib/libbsp/moxie/moxiesim/include/bsp.h
index 7ccc072..599ce18 100644
--- a/c/src/lib/libbsp/moxie/moxiesim/include/bsp.h
+++ b/c/src/lib/libbsp/moxie/moxiesim/include/bsp.h
@@ -28,7 +28,7 @@ extern "C" {
 #endif
 
 /* support for simulated clock tick */
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 
 #ifdef __cplusplus
diff --git a/c/src/lib/libbsp/sh/shsim/include/bsp.h b/c/src/lib/libbsp/sh/shsim/include/bsp.h
index 65b55fa..d814148 100644
--- a/c/src/lib/libbsp/sh/shsim/include/bsp.h
+++ b/c/src/lib/libbsp/sh/shsim/include/bsp.h
@@ -44,7 +44,7 @@ extern "C" {
 
 /* Constants */
 
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 
 /*
diff --git a/c/src/lib/libbsp/shared/clock_driver_simidle.c b/c/src/lib/libbsp/shared/clock_driver_simidle.c
index ee4b116..0954411 100644
--- a/c/src/lib/libbsp/shared/clock_driver_simidle.c
+++ b/c/src/lib/libbsp/shared/clock_driver_simidle.c
@@ -46,7 +46,7 @@ volatile bool clock_driver_enabled;
  *  fake time passing.  This will not let preemption from an
  *  interrupt work but is enough for many tests.
  */
-Thread clock_driver_sim_idle_body(
+void *clock_driver_sim_idle_body(
   uintptr_t   ignored
 )
 {
diff --git a/c/src/lib/libbsp/shared/clockdrv_shell.h b/c/src/lib/libbsp/shared/clockdrv_shell.h
index d546fb8..ee4cf9c 100644
--- a/c/src/lib/libbsp/shared/clockdrv_shell.h
+++ b/c/src/lib/libbsp/shared/clockdrv_shell.h
@@ -105,8 +105,8 @@ rtems_isr Clock_isr(
 
       while (
         _Thread_Heir == _Thread_Executing
-          && _Thread_Executing->Start.entry_point
-            == (Thread_Entry) rtems_configuration_get_idle_task()
+          && _Thread_Executing->Start.Entry.Kinds.Idle.entry
+            == rtems_configuration_get_idle_task()
       ) {
         _Timecounter_Tick_simple(interval, (*tc->tc_get_timecount)(tc));
       }
diff --git a/c/src/lib/libbsp/sparc64/niagara/include/bsp.h b/c/src/lib/libbsp/sparc64/niagara/include/bsp.h
index 0eb3130..90f633a 100644
--- a/c/src/lib/libbsp/sparc64/niagara/include/bsp.h
+++ b/c/src/lib/libbsp/sparc64/niagara/include/bsp.h
@@ -26,7 +26,7 @@ extern "C" {
 
 /* support for simulated clock tick */
 /*
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 */
 
diff --git a/c/src/lib/libbsp/sparc64/usiii/include/bsp.h b/c/src/lib/libbsp/sparc64/usiii/include/bsp.h
index 3db442a..f07e469 100644
--- a/c/src/lib/libbsp/sparc64/usiii/include/bsp.h
+++ b/c/src/lib/libbsp/sparc64/usiii/include/bsp.h
@@ -27,7 +27,7 @@ extern "C" {
 
 /* support for simulated clock tick */
 /*
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 */
 
diff --git a/c/src/lib/libbsp/v850/gdbv850sim/include/bsp.h b/c/src/lib/libbsp/v850/gdbv850sim/include/bsp.h
index 6942eef..1da9435 100644
--- a/c/src/lib/libbsp/v850/gdbv850sim/include/bsp.h
+++ b/c/src/lib/libbsp/v850/gdbv850sim/include/bsp.h
@@ -28,7 +28,7 @@ extern "C" {
 #endif
 
 /* support for simulated clock tick */
-Thread clock_driver_sim_idle_body(uintptr_t);
+void *clock_driver_sim_idle_body(uintptr_t);
 #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
 
 #ifdef __cplusplus
diff --git a/c/src/lib/libcpu/bfin/clock/clock.c b/c/src/lib/libcpu/bfin/clock/clock.c
index 5660f2a..9798d05 100644
--- a/c/src/lib/libcpu/bfin/clock/clock.c
+++ b/c/src/lib/libcpu/bfin/clock/clock.c
@@ -37,8 +37,8 @@ static rtems_isr clockISR(rtems_vector_number vector) {
     rtems_clock_tick();
   } while (
     _Thread_Heir == _Thread_Executing
-      && _Thread_Executing->Start.entry_point
-        == (Thread_Entry) rtems_configuration_get_idle_task()
+      && _Thread_Executing->Start.Entry.Kinds.Idle.entry
+        == rtems_configuration_get_idle_task()
   );
 #else
   rtems_clock_tick();
diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c
index e8dd30e..17a6653 100644
--- a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c
+++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c
@@ -107,8 +107,8 @@ static void clockHandler(void)
 
     while (
       _Thread_Heir == _Thread_Executing
-        && _Thread_Executing->Start.entry_point
-          == (Thread_Entry) rtems_configuration_get_idle_task()
+        && _Thread_Executing->Start.Entry.Kinds.Idle.entry
+          == rtems_configuration_get_idle_task()
     ) {
       tb += Clock_Decrementer_value;
       ppc_set_time_base( tb );
diff --git a/cpukit/libmisc/cpuuse/cpuusagetop.c b/cpukit/libmisc/cpuuse/cpuusagetop.c
index eaa192a..811a8bf 100644
--- a/cpukit/libmisc/cpuuse/cpuusagetop.c
+++ b/cpukit/libmisc/cpuuse/cpuusagetop.c
@@ -484,7 +484,7 @@ rtems_cpuusage_top_thread (rtems_task_argument arg)
        */
       rtems_object_get_name(thread->Object.id, sizeof(name), name);
       if (name[0] == '\0')
-        snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.entry_point);
+        snprintf(name, sizeof(name) - 1, "(%p)", thread->Start.Entry.Kinds.Numeric.entry);
 
       (*data->plugin.print)(data->plugin.context,
                             " 0x%08" PRIx32 " | %-19s |  %3" PRId32 " |  %3" PRId32 "   | ",
diff --git a/cpukit/libmisc/monitor/mon-task.c b/cpukit/libmisc/monitor/mon-task.c
index 910dd9d..341a403 100644
--- a/cpukit/libmisc/monitor/mon-task.c
+++ b/cpukit/libmisc/monitor/mon-task.c
@@ -25,8 +25,7 @@ rtems_monitor_task_canonical(
 
     api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ];
 
-    canonical_task->entry = rtems_thread->Start.entry_point;
-    canonical_task->argument = rtems_thread->Start.numeric_argument;
+    canonical_task->entry = rtems_thread->Start.Entry;
     canonical_task->stack = rtems_thread->Start.Initial_stack.area;
     canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
     canonical_task->cpu = _Per_CPU_Get_index( _Thread_Get_CPU( rtems_thread ) );
diff --git a/cpukit/libmisc/monitor/monitor.h b/cpukit/libmisc/monitor/monitor.h
index ccd907b..e2575cc 100644
--- a/cpukit/libmisc/monitor/monitor.h
+++ b/cpukit/libmisc/monitor/monitor.h
@@ -95,8 +95,7 @@ typedef struct {
     rtems_id                   id;
     rtems_name                 name;
   /* end of common portion */
-    Thread_Entry               entry;
-    Thread_Entry_numeric_type  argument;
+    Thread_Entry_information   entry;
     void                      *stack;
     uint32_t                   stack_size;
     uint32_t                   cpu;
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index 59c4e66..611477e 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -52,6 +52,15 @@ int pthread_create(
   void                   *arg
 )
 {
+  Thread_Entry_information entry = {
+    .adaptor = _Thread_Entry_adaptor_pointer,
+    .Kinds = {
+      .Pointer = {
+        .entry = start_routine,
+        .argument = arg
+      }
+    }
+  };
   const pthread_attr_t               *the_attr;
   Priority_Control                    core_priority;
   Thread_CPU_budget_algorithms        budget_algorithm;
@@ -219,14 +228,7 @@ int pthread_create(
   /*
    *  POSIX threads are allocated and started in one operation.
    */
-  status = _Thread_Start(
-    the_thread,
-    THREAD_START_POINTER,
-    start_routine,
-    arg,
-    0,                    /* unused */
-    NULL
-  );
+  status = _Thread_Start( the_thread, &entry, NULL );
 
   #if defined(RTEMS_DEBUG)
     /*
diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c
index 5accf39..c1f9340 100644
--- a/cpukit/posix/src/pthreadinitthreads.c
+++ b/cpukit/posix/src/pthreadinitthreads.c
@@ -37,11 +37,14 @@
 
 static void *_POSIX_Global_construction( void *arg )
 {
-  Thread_Entry entry_point = (Thread_Entry) Configuration_POSIX_API
+  Thread_Control           *executing = _Thread_Get_executing();
+  Thread_Entry_information  entry = executing->Start.Entry;
+
+  entry.Kinds.Pointer.entry = Configuration_POSIX_API
     .User_initialization_threads_table[ 0 ].thread_entry;
 
   (void) arg;
-  _Thread_Global_construction( entry_point );
+  _Thread_Global_construction( executing, &entry );
 }
 
 void _POSIX_Threads_Initialize_user_threads_body(void)
diff --git a/cpukit/rtems/src/taskinitusers.c b/cpukit/rtems/src/taskinitusers.c
index f5c2f82..aeed5b4 100644
--- a/cpukit/rtems/src/taskinitusers.c
+++ b/cpukit/rtems/src/taskinitusers.c
@@ -33,11 +33,14 @@
 
 static void _RTEMS_Global_construction( rtems_task_argument arg )
 {
-  Thread_Entry entry_point = (Thread_Entry)
+  Thread_Control           *executing = _Thread_Get_executing();
+  Thread_Entry_information  entry = executing->Start.Entry;
+
+  entry.Kinds.Numeric.entry =
     Configuration_RTEMS_API.User_initialization_tasks_table[ 0 ].entry_point;
 
   (void) arg;
-  _Thread_Global_construction( entry_point );
+  _Thread_Global_construction( executing, &entry );
 }
 
 /*
diff --git a/cpukit/rtems/src/taskrestart.c b/cpukit/rtems/src/taskrestart.c
index 0b56ed5..8aa7c73 100644
--- a/cpukit/rtems/src/taskrestart.c
+++ b/cpukit/rtems/src/taskrestart.c
@@ -28,12 +28,15 @@ rtems_status_code rtems_task_restart(
 {
   Thread_Control          *the_thread;
   Objects_Locations        location;
+  Thread_Entry_information entry;
 
   the_thread = _Thread_Get( id, &location );
   switch ( location ) {
 
     case OBJECTS_LOCAL:
-      if ( _Thread_Restart( the_thread, _Thread_Executing, NULL, argument ) ) {
+      entry = the_thread->Start.Entry;
+      entry.Kinds.Numeric.argument = argument;
+      if ( _Thread_Restart( the_thread, _Thread_Executing, &entry ) ) {
         _Objects_Put( &the_thread->Object );
         return RTEMS_SUCCESSFUL;
       }
diff --git a/cpukit/rtems/src/taskstart.c b/cpukit/rtems/src/taskstart.c
index d6f15d8..39b3e9c 100644
--- a/cpukit/rtems/src/taskstart.c
+++ b/cpukit/rtems/src/taskstart.c
@@ -44,9 +44,18 @@ rtems_status_code rtems_task_start(
   rtems_task_argument	argument
 )
 {
-  Thread_Control          *the_thread;
-  Objects_Locations        location;
-  bool                     successfully_started;
+  Thread_Entry_information entry = {
+    .adaptor = _Thread_Entry_adaptor_numeric,
+    .Kinds = {
+      .Numeric = {
+        .entry = entry_point,
+        .argument = argument
+      }
+    }
+  };
+  Thread_Control    *the_thread;
+  Objects_Locations  location;
+  bool               successfully_started;
 
   if ( entry_point == NULL )
     return RTEMS_INVALID_ADDRESS;
@@ -55,14 +64,7 @@ rtems_status_code rtems_task_start(
   switch ( location ) {
 
     case OBJECTS_LOCAL:
-      successfully_started = _Thread_Start(
-        the_thread,
-        THREAD_START_NUMERIC,
-        entry_point,
-        NULL,
-        argument,
-        NULL
-      );
+      successfully_started = _Thread_Start( the_thread, &entry, NULL );
 
       _Objects_Put( &the_thread->Object );
 
diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h
index 9a9d0a3..d73e9b8 100644
--- a/cpukit/sapi/include/rtems/config.h
+++ b/cpukit/sapi/include/rtems/config.h
@@ -181,7 +181,7 @@ typedef struct {
    * This element points to the BSP's optional idle task which may override
    * the default one provided with RTEMS.
    */
-  Thread                       (*idle_task)( uintptr_t );
+  void                        *(*idle_task)( uintptr_t );
 
   /** 
    * This field specifies the size of the IDLE task's stack.  If less than or
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 04c5c87..6593805 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -301,6 +301,9 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
     src/threadsetstate.c \
     src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \
     src/threadstartmultitasking.c src/iterateoverthreads.c
+libscore_a_SOURCES += src/threadentryadaptoridle.c
+libscore_a_SOURCES += src/threadentryadaptornumeric.c
+libscore_a_SOURCES += src/threadentryadaptorpointer.c
 libscore_a_SOURCES += src/threadglobalconstruction.c
 libscore_a_SOURCES += src/threadtimeout.c
 libscore_a_SOURCES += src/threadyield.c
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 6e937e3..f4d76d8 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -88,15 +88,11 @@ extern "C" {
 
 typedef Timestamp_Control Thread_CPU_usage_t;
 
-/**
- *  The following defines the "return type" of a thread.
- *
- *  @note  This cannot always be right.  Some APIs have void
- *         tasks/threads, others return pointers, others may
- *         return a numeric value.  Hopefully a pointer is
- *         always at least as big as an uint32_t  . :)
+/*
+ * Only provided for backward compatiblity to not break application
+ * configurations.
  */
-typedef void *Thread;
+typedef void *Thread RTEMS_DEPRECATED;
 
 /**
  *  @brief Type of the numeric argument of a thread entry function with at
@@ -110,44 +106,52 @@ typedef void *Thread;
 typedef CPU_Uint32ptr Thread_Entry_numeric_type;
 
 /**
- *  The following defines the ways in which the entry point for a
- *  thread can be invoked.  Basically, it can be passed any
- *  combination/permutation of a pointer and an uint32_t   value.
- *
- *  @note For now, we are ignoring the return type.
+ * @brief Data for idle thread entry.
  */
-typedef enum {
-  THREAD_START_NUMERIC,
-  THREAD_START_POINTER,
-  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
-    THREAD_START_BOTH_POINTER_FIRST,
-    THREAD_START_BOTH_NUMERIC_FIRST
-  #endif
-} Thread_Start_types;
-
-/** This type corresponds to a very simple style thread entry point. */
-typedef Thread ( *Thread_Entry )( void );   /* basic type */
+typedef struct {
+  void *( *entry )( uintptr_t argument );
+} Thread_Entry_idle;
 
-/** This type corresponds to a thread entry point which takes a single
- *  unsigned thirty-two bit integer as an argument.
+/**
+ * @brief Data for thread entry with one numeric argument and no return value.
  */
-typedef Thread ( *Thread_Entry_numeric )( Thread_Entry_numeric_type );
+typedef struct {
+  void ( *entry )( Thread_Entry_numeric_type argument );
+  Thread_Entry_numeric_type argument;
+} Thread_Entry_numeric;
 
-/** This type corresponds to a thread entry point which takes a single
- *  untyped pointer as an argument.
+/**
+ * @brief Data for thread entry with one pointer argument and a pointer return
+ * value.
  */
-typedef Thread ( *Thread_Entry_pointer )( void * );
+typedef struct {
+  void *( *entry )( void *argument  );
+  void *argument;
+} Thread_Entry_pointer;
 
-/** This type corresponds to a thread entry point which takes a single
- *  untyped pointer and an unsigned thirty-two bit integer as arguments.
+/**
+ * @brief Thread entry information.
  */
-typedef Thread ( *Thread_Entry_both_pointer_first )( void *, Thread_Entry_numeric_type );
+typedef struct {
+  /**
+   * @brief Thread entry adaptor.
+   *
+   * Calls the corresponding thread entry with the right parameters.
+   *
+   * @param executing The executing thread.
+   */
+  void ( *adaptor )( Thread_Control *executing );
 
-/** This type corresponds to a thread entry point which takes a single
- *  unsigned thirty-two bit integer and an untyped pointer and an
- *  as arguments.
- */
-typedef Thread ( *Thread_Entry_both_numeric_first )( Thread_Entry_numeric_type, void * );
+  /**
+   * @brief Thread entry data used by the adaptor to call the thread entry
+   * function with the right parameters.
+   */
+  union {
+    Thread_Entry_idle Idle;
+    Thread_Entry_numeric Numeric;
+    Thread_Entry_pointer Pointer;
+  } Kinds;
+} Thread_Entry_information;
 
 /**
  *  The following lists the algorithms used to manage the thread cpu budget.
@@ -206,14 +210,8 @@ typedef struct {
  *  the starting state of a thread.
  */
 typedef struct {
-  /** This field is the starting address for the thread. */
-  Thread_Entry                         entry_point;
-  /** This field indicates the how task is invoked. */
-  Thread_Start_types                   prototype;
-  /** This field is the pointer argument passed at thread start. */
-  void                                *pointer_argument;
-  /** This field is the numeric argument passed at thread start. */
-  Thread_Entry_numeric_type            numeric_argument;
+  /** This field contains the thread entry information. */
+  Thread_Entry_information             Entry;
   /*-------------- initial execution modes ----------------- */
   /** This field indicates whether the thread was preemptible when
     * it started.
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index abdd7e6..f212e23 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -185,29 +185,22 @@ bool _Thread_Initialize(
  *  and makes it ready to execute.  After this routine executes, the
  *  thread competes with all other threads for CPU time.
  *
- *  @param the_thread is the thread to be initialized
- *  @param the_prototype
- *  @param entry_point
- *  @param pointer_argument
- *  @param numeric_argument
+ *  @param the_thread The thread to be started.
+ *  @param entry The thread entry information.
  *  @param[in,out] cpu The processor if used to start an idle thread
  *  during system initialization.  Must be set to @c NULL to start a normal
  *  thread.
  */
 bool _Thread_Start(
-  Thread_Control            *the_thread,
-  Thread_Start_types         the_prototype,
-  void                      *entry_point,
-  void                      *pointer_argument,
-  Thread_Entry_numeric_type  numeric_argument,
-  Per_CPU_Control           *cpu
+  Thread_Control                 *the_thread,
+  const Thread_Entry_information *entry,
+  Per_CPU_Control                *cpu
 );
 
 bool _Thread_Restart(
-  Thread_Control            *the_thread,
-  Thread_Control            *executing,
-  void                      *pointer_argument,
-  Thread_Entry_numeric_type  numeric_argument
+  Thread_Control                 *the_thread,
+  Thread_Control                 *executing,
+  const Thread_Entry_information *entry
 );
 
 void _Thread_Yield( Thread_Control *executing );
@@ -300,6 +293,12 @@ void _Thread_Load_environment(
   Thread_Control *the_thread
 );
 
+void _Thread_Entry_adaptor_idle( Thread_Control *executing );
+
+void _Thread_Entry_adaptor_numeric( Thread_Control *executing );
+
+void _Thread_Entry_adaptor_pointer( Thread_Control *executing );
+
 /**
  *  @brief Wrapper function for all threads.
  *
@@ -325,7 +324,10 @@ void _Thread_Handler( void );
  * the first POSIX initialization thread in case no RTEMS initialization tasks
  * are present.
  */
-void _Thread_Global_construction( Thread_Entry entry_point ) RTEMS_NO_RETURN;
+void _Thread_Global_construction(
+  Thread_Control                 *executing,
+  const Thread_Entry_information *entry
+) RTEMS_NO_RETURN;
 
 /**
  *  @brief Ended the delay of a thread.
diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c
index 8a5812f..e9d12dc 100644
--- a/cpukit/score/src/threadcreateidle.c
+++ b/cpukit/score/src/threadcreateidle.c
@@ -25,6 +25,14 @@
 
 static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
 {
+  Thread_Entry_information entry = {
+    .adaptor = _Thread_Entry_adaptor_idle,
+    .Kinds = {
+      .Idle = {
+        .entry = rtems_configuration_get_idle_task()
+      }
+    }
+  };
   Objects_Name    name;
   Thread_Control *idle;
 
@@ -59,14 +67,7 @@ static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
   cpu->heir      =
   cpu->executing = idle;
 
-  _Thread_Start(
-    idle,
-    THREAD_START_NUMERIC,
-    rtems_configuration_get_idle_task(),
-    NULL,
-    0,
-    cpu
-  );
+  _Thread_Start( idle, &entry, cpu );
 }
 
 void _Thread_Create_idle( void )
diff --git a/cpukit/score/src/threadentryadaptoridle.c b/cpukit/score/src/threadentryadaptoridle.c
new file mode 100644
index 0000000..e98f562
--- /dev/null
+++ b/cpukit/score/src/threadentryadaptoridle.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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/threadimpl.h>
+
+void _Thread_Entry_adaptor_idle( Thread_Control *executing )
+{
+  const Thread_Entry_idle *idle = &executing->Start.Entry.Kinds.Idle;
+
+  ( *idle->entry )( 0 );
+}
diff --git a/cpukit/score/src/threadentryadaptornumeric.c b/cpukit/score/src/threadentryadaptornumeric.c
new file mode 100644
index 0000000..acc06f0
--- /dev/null
+++ b/cpukit/score/src/threadentryadaptornumeric.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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/threadimpl.h>
+
+void _Thread_Entry_adaptor_numeric( Thread_Control *executing )
+{
+  const Thread_Entry_numeric *numeric = &executing->Start.Entry.Kinds.Numeric;
+
+  ( *numeric->entry )( numeric->argument );
+}
diff --git a/cpukit/score/src/threadentryadaptorpointer.c b/cpukit/score/src/threadentryadaptorpointer.c
new file mode 100644
index 0000000..65866d8
--- /dev/null
+++ b/cpukit/score/src/threadentryadaptorpointer.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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/threadimpl.h>
+
+void _Thread_Entry_adaptor_pointer( Thread_Control *executing )
+{
+  const Thread_Entry_pointer *pointer = &executing->Start.Entry.Kinds.Pointer;
+
+  executing->Wait.return_argument = ( *pointer->entry )( pointer->argument );
+}
diff --git a/cpukit/score/src/threadglobalconstruction.c b/cpukit/score/src/threadglobalconstruction.c
index 56a6df1..1e84124 100644
--- a/cpukit/score/src/threadglobalconstruction.c
+++ b/cpukit/score/src/threadglobalconstruction.c
@@ -44,10 +44,11 @@
   #define EXECUTE_GLOBAL_CONSTRUCTORS
 #endif
 
-void _Thread_Global_construction( Thread_Entry entry_point )
+void _Thread_Global_construction(
+  Thread_Control                 *executing,
+  const Thread_Entry_information *entry
+)
 {
-  Thread_Control *executing;
-
 #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
   /*
    *  _init could be a weak symbol and we SHOULD test it but it isn't
@@ -58,17 +59,7 @@ void _Thread_Global_construction( Thread_Entry entry_point )
 #endif
 
   _Thread_Disable_dispatch();
-
-  executing = _Thread_Executing;
-  executing->Start.entry_point = entry_point;
-
-  _Thread_Restart(
-    executing,
-    executing,
-    executing->Start.pointer_argument,
-    executing->Start.numeric_argument
-  );
-
+  _Thread_Restart( executing, executing, entry );
   _Thread_Enable_dispatch();
 
   _Assert_Not_reached();
diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c
index fd828a2..2429de5 100644
--- a/cpukit/score/src/threadhandler.c
+++ b/cpukit/score/src/threadhandler.c
@@ -90,41 +90,12 @@ void _Thread_Handler( void )
    *  thread/task prototype. The following code supports invoking the
    *  user thread entry point using the prototype expected.
    */
-  if ( executing->Start.prototype == THREAD_START_NUMERIC ) {
-    executing->Wait.return_argument =
-      (*(Thread_Entry_numeric) executing->Start.entry_point)(
-        executing->Start.numeric_argument
-      );
-  }
-  #if defined(RTEMS_POSIX_API)
-    else if ( executing->Start.prototype == THREAD_START_POINTER ) {
-      executing->Wait.return_argument =
-        (*(Thread_Entry_pointer) executing->Start.entry_point)(
-          executing->Start.pointer_argument
-        );
-    }
-  #endif
-  #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
-    else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) {
-      executing->Wait.return_argument =
-         (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)(
-           executing->Start.pointer_argument,
-           executing->Start.numeric_argument
-         );
-    }
-    else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) {
-      executing->Wait.return_argument =
-       (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)(
-         executing->Start.numeric_argument,
-         executing->Start.pointer_argument
-       );
-    }
-  #endif
+  ( *executing->Start.Entry.adaptor )( executing );
 
   /*
-   *  In the switch above, the return code from the user thread body
-   *  was placed in return_argument.  This assumed that if it returned
-   *  anything (which is not supporting in all APIs), then it would be
+   *  In the call above, the return code from the user thread body which return
+   *  something was placed in return_argument.  This assumed that if it
+   *  returned anything (which is not supporting in all APIs), then it would be
    *  able to fit in a (void *).
    */
 
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 2b1fef9..03b1fba 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -356,15 +356,13 @@ void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing )
 }
 
 bool _Thread_Restart(
-  Thread_Control            *the_thread,
-  Thread_Control            *executing,
-  void                      *pointer_argument,
-  Thread_Entry_numeric_type  numeric_argument
+  Thread_Control                 *the_thread,
+  Thread_Control                 *executing,
+  const Thread_Entry_information *entry
 )
 {
   if ( !_States_Is_dormant( the_thread->current_state ) ) {
-    the_thread->Start.pointer_argument = pointer_argument;
-    the_thread->Start.numeric_argument = numeric_argument;
+    the_thread->Start.Entry = *entry;
 
     _Thread_Request_life_change(
       the_thread,
diff --git a/cpukit/score/src/threadstart.c b/cpukit/score/src/threadstart.c
index dda9495..97399ba 100644
--- a/cpukit/score/src/threadstart.c
+++ b/cpukit/score/src/threadstart.c
@@ -25,22 +25,13 @@
 #include <rtems/score/userextimpl.h>
 
 bool _Thread_Start(
-  Thread_Control            *the_thread,
-  Thread_Start_types         the_prototype,
-  void                      *entry_point,
-  void                      *pointer_argument,
-  Thread_Entry_numeric_type  numeric_argument,
-  Per_CPU_Control           *cpu
+  Thread_Control                 *the_thread,
+  const Thread_Entry_information *entry,
+  Per_CPU_Control                *cpu
 )
 {
   if ( _States_Is_dormant( the_thread->current_state ) ) {
-
-    the_thread->Start.entry_point      = (Thread_Entry) entry_point;
-
-    the_thread->Start.prototype        = the_prototype;
-    the_thread->Start.pointer_argument = pointer_argument;
-    the_thread->Start.numeric_argument = numeric_argument;
-
+    the_thread->Start.Entry = *entry;
     _Thread_Load_environment( the_thread );
 
     if ( cpu == NULL ) {
diff --git a/testsuites/samples/minimum/init.c b/testsuites/samples/minimum/init.c
index 0823a73..65efad2 100644
--- a/testsuites/samples/minimum/init.c
+++ b/testsuites/samples/minimum/init.c
@@ -20,18 +20,15 @@
 #include <bsp.h>
 #include <rtems/score/thread.h>
 
-/* forward declarations to avoid warnings */
-rtems_task Init(rtems_task_argument argument);
-
-rtems_task Init(
-  rtems_task_argument ignored
-)
+static void *Init( uintptr_t ignored )
 {
   /* initialize application */
 
   /* Real application would call idle loop functionality */
 
   /* but in this case, just return and fall into a fatal error */
+
+  return NULL;
 }
 
 /* configuration information */
@@ -98,7 +95,7 @@ rtems_task Init(
  *  In this application, the initialization task performs the system
  *  initialization and then transforms itself into the idle task.
  */
-#define CONFIGURE_IDLE_TASK_BODY (Thread_Entry_numeric) Init
+#define CONFIGURE_IDLE_TASK_BODY Init
 #define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
 
 /*
diff --git a/testsuites/sptests/sp54/init.c b/testsuites/sptests/sp54/init.c
index 97dffa2..3b0d458 100644
--- a/testsuites/sptests/sp54/init.c
+++ b/testsuites/sptests/sp54/init.c
@@ -22,12 +22,7 @@
 
 const char rtems_test_name[] = "SP 54";
 
-/* forward declarations to avoid warnings */
-rtems_task Init(rtems_task_argument argument);
-
-rtems_task Init(
-  rtems_task_argument ignored
-)
+static void *Init( uintptr_t ignored )
 {
   rtems_status_code    status;
   rtems_task_priority  pri;
@@ -68,7 +63,7 @@ rtems_task Init(
  *  In this application, the initialization task performs the system
  *  initialization and then transforms itself into the idle task.
  */
-#define CONFIGURE_IDLE_TASK_BODY (Thread_Entry_numeric) Init
+#define CONFIGURE_IDLE_TASK_BODY Init
 #define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
 
 /*
diff --git a/testsuites/sptests/spintrcritical_support/intrcritical.c b/testsuites/sptests/spintrcritical_support/intrcritical.c
index 7cea9ad..b831cf1 100644
--- a/testsuites/sptests/spintrcritical_support/intrcritical.c
+++ b/testsuites/sptests/spintrcritical_support/intrcritical.c
@@ -175,8 +175,8 @@ bool interrupt_critical_section_test_support_delay(void)
 
 static bool is_idle( const Thread_Control *thread )
 {
-  return thread->Start.entry_point
-    == (Thread_Entry) rtems_configuration_get_idle_task();
+  return thread->Start.Entry.Kinds.Idle.entry
+    == rtems_configuration_get_idle_task();
 }
 
 static void thread_switch( Thread_Control *executing, Thread_Control *heir )




More information about the vc mailing list