Changeset 03acc59 in rtems


Ignore:
Timestamp:
Aug 14, 2013, 12:21:41 AM (6 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.11, master
Children:
b7f2060
Parents:
40398c4
Message:

posix: Change pthread_once to be SMP safe.

Change pthread_once from using disabled pre-emption to using a
pthread mutex making it SMP safe. GCC using a posix threading
model uses pthread_once.

The pthread mutex requires at least 1 mutex is configured so
confdefs.h has been updated to account for the internal
mutex.

Location:
cpukit
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/posix/Makefile.am

    r40398c4 r03acc59  
    3434include_rtems_posix_HEADERS += include/rtems/posix/mutex.h
    3535include_rtems_posix_HEADERS += include/rtems/posix/muteximpl.h
     36include_rtems_posix_HEADERS += include/rtems/posix/onceimpl.h
    3637include_rtems_posix_HEADERS += include/rtems/posix/posixapi.h
    3738include_rtems_posix_HEADERS += include/rtems/posix/priorityimpl.h
     
    116117    src/mutextranslatereturncode.c src/mutextrylock.c src/mutexunlock.c
    117118
     119## ONCE_C_FILES
     120libposix_a_SOURCES += src/once.c src/pthreadonce.c
     121
    118122## PTHREAD_C_FILES
    119123libposix_a_SOURCES += src/pthreadatfork.c src/pthreadattrdestroy.c \
     
    132136    src/pthreadgetschedparam.c \
    133137    src/pthreadinitthreads.c src/pthreadjoin.c src/pthreadkill.c \
    134     src/pthreadonce.c src/pthreadself.c \
     138    src/pthreadself.c \
    135139    src/pthreadsetschedparam.c src/pthreadsigmask.c \
    136140    src/psxpriorityisvalid.c src/psxtransschedparam.c
  • cpukit/posix/preinstall.am

    r40398c4 r03acc59  
    8585PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/muteximpl.h
    8686
     87$(PROJECT_INCLUDE)/rtems/posix/onceimpl.h: include/rtems/posix/onceimpl.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
     88        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/onceimpl.h
     89PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/onceimpl.h
     90
    8791$(PROJECT_INCLUDE)/rtems/posix/posixapi.h: include/rtems/posix/posixapi.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
    8892        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/posixapi.h
  • cpukit/posix/src/pthreadonce.c

    r40398c4 r03acc59  
    2626#include <rtems.h>
    2727#include <rtems/system.h>
    28 #include <rtems/score/thread.h>
     28#include <rtems/posix/onceimpl.h>
     29
     30#define PTHREAD_ONCE_INIT_NOT_RUN  0
     31#define PTHREAD_ONCE_INIT_RUNNING  1
     32#define PTHREAD_ONCE_INIT_RUN      2
    2933
    3034int pthread_once(
     
    3337)
    3438{
     39  int r = 0;
     40
    3541  if ( !once_control || !init_routine )
    3642    return EINVAL;
    3743
    38   if ( !once_control->init_executed ) {
    39     rtems_mode saveMode;
    40     rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode);
    41     if ( !once_control->init_executed ) {
    42       once_control->is_initialized = true;
    43       once_control->init_executed = true;
    44       (*init_routine)();
     44  if ( once_control->is_initialized != 1 )
     45    return EINVAL;
     46
     47  if ( once_control->init_executed != PTHREAD_ONCE_INIT_RUN ) {
     48    r = pthread_mutex_lock( &_POSIX_Once_Lock );
     49    if ( r == 0 ) {
     50      int rr;
     51
     52      /*
     53       * Getting to here means the once_control is locked so we have:
     54       *  1. The init has not run and the state is PTHREAD_ONCE_INIT_NOT_RUN.
     55       *  2. The init has finished and the state is PTHREAD_ONCE_INIT_RUN.
     56       *  3. The init is being run by this thread and the state
     57       *     PTHREAD_ONCE_INIT_RUNNING so we are nesting. This is an error.
     58       */
     59
     60      switch ( once_control->init_executed ) {
     61        case PTHREAD_ONCE_INIT_NOT_RUN:
     62          once_control->init_executed = PTHREAD_ONCE_INIT_RUNNING;
     63          (*init_routine)();
     64          once_control->init_executed = PTHREAD_ONCE_INIT_RUN;
     65          break;
     66        case PTHREAD_ONCE_INIT_RUNNING:
     67          r = EINVAL;
     68          break;
     69        default:
     70          break;
     71      }
     72      rr = pthread_mutex_unlock( &_POSIX_Once_Lock );
     73      if ( r == 0 )
     74        r = rr;
    4575    }
    46     rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode);
    4776  }
    48   return 0;
     77
     78  return r;
    4979}
  • cpukit/sapi/include/confdefs.h

    r40398c4 r03acc59  
    16961696
    16971697  /**
     1698   * POSIX Once support uses a single mutex.
     1699   */
     1700  #define CONFIGURE_MAXIMUM_POSIX_INTERNAL_MUTEXES 1
     1701
     1702  /**
    16981703   * Account for the object control structures plus the name
    16991704   * of the object to be duplicated.
     
    18571862  #define CONFIGURE_MEMORY_FOR_POSIX \
    18581863    ( CONFIGURE_MEMORY_FOR_POSIX_MUTEXES( CONFIGURE_MAXIMUM_POSIX_MUTEXES + \
     1864          CONFIGURE_MAXIMUM_POSIX_INTERNAL_MUTEXES + \
    18591865          CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_MUTEXES) + \
    18601866      CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( \
     
    23052311        CONFIGURE_MAXIMUM_GOROUTINES,
    23062312      CONFIGURE_MAXIMUM_POSIX_MUTEXES + CONFIGURE_GNAT_MUTEXES +
     2313        CONFIGURE_MAXIMUM_POSIX_INTERNAL_MUTEXES +
    23072314        CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS +
    23082315        CONFIGURE_GO_INIT_MUTEXES + CONFIGURE_MAXIMUM_GO_CHANNELS,
  • cpukit/sapi/src/posixapi.c

    r40398c4 r03acc59  
    3434#include <rtems/posix/mqueueimpl.h>
    3535#include <rtems/posix/muteximpl.h>
     36#include <rtems/posix/onceimpl.h>
    3637#include <rtems/posix/posixapi.h>
    3738#include <rtems/posix/priorityimpl.h>
     
    6768  _POSIX_Mutex_Manager_initialization();
    6869  _POSIX_Message_queue_Manager_initialization();
     70  _POSIX_Once_Manager_initialization();
    6971  _POSIX_Semaphore_Manager_initialization();
    7072  _POSIX_Timer_Manager_initialization();
Note: See TracChangeset for help on using the changeset viewer.