Changeset a38ced2 in rtems


Ignore:
Timestamp:
10/10/14 07:09:19 (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
2faaf4b
Parents:
ef4c461
git-author:
Sebastian Huber <sebastian.huber@…> (10/10/14 07:09:19)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/13/14 12:30:22)
Message:

score: Rework global construction

Ensure that the global construction is performed in the context of the
first initialization thread. On SMP this was not guaranteed in the
previous implementation.

Files:
13 added
10 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/src/pthreadinitthreads.c

    ref4c461 ra38ced2  
    3535#include <rtems/posix/config.h>
    3636#include <rtems/posix/time.h>
     37#include <rtems/rtems/config.h>
    3738
    3839void _POSIX_Threads_Initialize_user_threads_body(void)
     
    4445  pthread_t                           thread_id;
    4546  pthread_attr_t                      attr;
     47  bool                                register_global_construction;
     48  void                             *(*thread_entry)(void *);
    4649
    4750  user_threads = Configuration_POSIX_API.User_initialization_threads_table;
    4851  maximum      = Configuration_POSIX_API.number_of_initialization_threads;
    4952
    50   if ( !user_threads || maximum == 0 )
     53  if ( !user_threads )
    5154    return;
     55
     56  register_global_construction =
     57    Configuration_RTEMS_API.number_of_initialization_tasks == 0;
    5258
    5359  /*
     
    6975    _Assert( eno == 0 );
    7076
     77    thread_entry = user_threads[ index ].thread_entry;
     78
     79    if ( register_global_construction && thread_entry != NULL ) {
     80      register_global_construction = false;
     81      thread_entry = (void *(*)(void *)) _Thread_Global_construction;
     82    }
     83
    7184    eno = pthread_create(
    7285      &thread_id,
    7386      &attr,
    74       user_threads[ index ].thread_entry,
     87      thread_entry,
    7588      NULL
    7689    );
  • cpukit/rtems/src/taskinitusers.c

    ref4c461 ra38ced2  
    4949  rtems_status_code                 return_value;
    5050  rtems_initialization_tasks_table *user_tasks;
     51  bool                              register_global_construction;
     52  rtems_task_entry                  entry_point;
    5153
    5254  /*
     
    6163  if ( !user_tasks )
    6264    return;
     65
     66  register_global_construction = true;
    6367
    6468  /*
     
    7781      _Terminate( INTERNAL_ERROR_RTEMS_API, true, return_value );
    7882
     83    entry_point = user_tasks[ index ].entry_point;
     84
     85    if ( register_global_construction && entry_point != NULL ) {
     86      register_global_construction = false;
     87      entry_point = (rtems_task_entry) _Thread_Global_construction;
     88    }
     89
    7990    return_value = rtems_task_start(
    8091      id,
    81       user_tasks[ index ].entry_point,
     92      entry_point,
    8293      user_tasks[ index ].argument
    8394    );
  • cpukit/score/Makefile.am

    ref4c461 ra38ced2  
    290290    src/threadstartmultitasking.c src/iterateoverthreads.c \
    291291    src/threadblockingoperationcancel.c
     292libscore_a_SOURCES += src/threadglobalconstruction.c
    292293libscore_a_SOURCES += src/threadyield.c
    293294
  • cpukit/score/include/rtems/score/threadimpl.h

    ref4c461 ra38ced2  
    306306
    307307/**
     308 * @brief Executes the global constructors and then restarts itself as the
     309 * first initialization thread.
     310 *
     311 * The first initialization thread is the first RTEMS initialization task or
     312 * the first POSIX initialization thread in case no RTEMS initialization tasks
     313 * are present.
     314 */
     315void *_Thread_Global_construction( void );
     316
     317/**
    308318 *  @brief Ended the delay of a thread.
    309319 *
  • cpukit/score/src/threadhandler.c

    ref4c461 ra38ced2  
    2525#include <rtems/score/userextimpl.h>
    2626
    27 /*
    28  *  Conditional magic to determine what style of C++ constructor
    29  *  initialization this target and compiler version uses.
    30  */
    31 #if defined(__USE_INIT_FINI__)
    32   #if defined(__M32R__)
    33     #define INIT_NAME __init
    34   #elif defined(__ARM_EABI__)
    35     #define INIT_NAME __libc_init_array
    36   #else
    37     #define INIT_NAME _init
    38   #endif
    39 
    40   extern void INIT_NAME(void);
    41   #define EXECUTE_GLOBAL_CONSTRUCTORS
    42 #endif
    43 
    44 #if defined(__USE__MAIN__)
    45   extern void __main(void);
    46   #define INIT_NAME __main
    47   #define EXECUTE_GLOBAL_CONSTRUCTORS
    48 #endif
    49 
    50 #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    51   static bool _Thread_Handler_is_constructor_execution_required(
    52     Thread_Control *executing
    53   )
    54   {
    55     static bool doneConstructors;
    56     bool doCons = false;
    57 
    58     #if defined(RTEMS_SMP)
    59       static SMP_lock_Control constructor_lock =
    60         SMP_LOCK_INITIALIZER("constructor");
    61 
    62       SMP_lock_Context lock_context;
    63 
    64       if ( !doneConstructors ) {
    65         _SMP_lock_Acquire( &constructor_lock, &lock_context );
    66     #endif
    67 
    68     #if defined(RTEMS_MULTIPROCESSING)
    69       doCons = !doneConstructors
    70         && _Objects_Get_API( executing->Object.id ) != OBJECTS_INTERNAL_API;
    71       if (doCons)
    72         doneConstructors = true;
    73     #else
    74       (void) executing;
    75       doCons = !doneConstructors;
    76       doneConstructors = true;
    77     #endif
    78 
    79     #if defined(RTEMS_SMP)
    80         _SMP_lock_Release( &constructor_lock, &lock_context );
    81       }
    82     #endif
    83 
    84     return doCons;
    85   }
    86 #endif
    87 
    8827void _Thread_Handler( void )
    8928{
    90   ISR_Level  level;
    91   Thread_Control *executing;
    92   #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    93     bool doCons;
    94   #endif
     29  Thread_Control *executing = _Thread_Executing;
     30  ISR_Level       level;
    9531
    96   executing = _Thread_Executing;
    9732
    9833  /*
     
    11045    level = executing->Start.isr_level;
    11146    _ISR_Set_level( level );
    112   #endif
    113 
    114   #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    115     doCons = _Thread_Handler_is_constructor_execution_required( executing );
    11647  #endif
    11748
     
    172103  #endif
    173104
    174   #if defined(EXECUTE_GLOBAL_CONSTRUCTORS)
    175     /*
    176      *  _init could be a weak symbol and we SHOULD test it but it isn't
    177      *  in any configuration I know of and it generates a warning on every
    178      *  RTEMS target configuration.  --joel (12 May 2007)
    179      */
    180     if (doCons) /* && (volatile void *)_init) */ {
    181       INIT_NAME ();
    182     }
    183  #endif
    184 
    185105  /*
    186106   *  RTEMS supports multiple APIs and each API can define a different
  • testsuites/psxtests/Makefile.am

    ref4c461 ra38ced2  
    1616    psxintrcritical01 psxstack01 psxstack02 \
    1717    psxeintr_join psxgetattrnp01
     18if HAS_CPLUSPLUS
     19_SUBDIRS += psxglobalcon01
     20_SUBDIRS += psxglobalcon02
     21endif
    1822endif
    1923
  • testsuites/psxtests/configure.ac

    ref4c461 ra38ced2  
    1212AM_MAINTAINER_MODE
    1313
     14RTEMS_ENABLE_CXX
     15
    1416RTEMS_ENV_RTEMSBSP
    1517
     
    1719
    1820RTEMS_PROG_CC_FOR_TARGET
     21RTEMS_PROG_CXX_FOR_TARGET
    1922
    2023RTEMS_CANONICALIZE_TOOLS
    2124
    2225RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
    23 
    24 AM_CONDITIONAL([HAS_NETWORKING],[test "$HAS_NETWORKING" = "yes"])
     26RTEMS_CHECK_CXX(RTEMS_BSP)
     27
     28AM_CONDITIONAL([HAS_NETWORKING],[test x"$HAS_NETWORKING" = x"yes"])
     29AM_CONDITIONAL([HAS_CPLUSPLUS],[test x"$HAS_CPLUSPLUS" = x"yes"])
    2530
    2631RTEMS_CHECK_CPUOPTS([RTEMS_POSIX_API])
     
    146151psxgetattrnp01/Makefile
    147152psxgetrusage01/Makefile
     153psxglobalcon01/Makefile
     154psxglobalcon02/Makefile
    148155psxhdrs/Makefile
    149156psxid01/Makefile
  • testsuites/sptests/Makefile.am

    ref4c461 ra38ced2  
    5151_SUBDIRS += spcpucounter01
    5252if HAS_CPLUSPLUS
     53_SUBDIRS += spglobalcon01
    5354_SUBDIRS += sptls02
    5455endif
  • testsuites/sptests/configure.ac

    ref4c461 ra38ced2  
    4141# Explicitly list all Makefiles here
    4242AC_CONFIG_FILES([Makefile
     43spglobalcon01/Makefile
    4344spintrcritical22/Makefile
    4445spsem03/Makefile
  • testsuites/sptests/spthreadlife01/init.c

    ref4c461 ra38ced2  
    137137
    138138  rtems_test_assert(executing == restarted);
    139   rtems_test_assert(ctx->worker_task_id == rtems_task_self());
    140139
    141140  switch (ctx->current) {
    142141    case RESTART_0:
     142      rtems_test_assert(ctx->worker_task_id == rtems_task_self());
    143143      ctx->current = RESTART_1;
    144144      sc = rtems_task_restart(RTEMS_SELF, 0);
     
    146146      break;
    147147    case RESTART_1:
     148      rtems_test_assert(ctx->worker_task_id == rtems_task_self());
    148149      ctx->current = RESTART_2;
     150      break;
     151    case INIT:
     152      /* Restart via _Thread_Global_construction() */
    149153      break;
    150154    default:
Note: See TracChangeset for help on using the changeset viewer.