Changeset 96c041c in rtems


Ignore:
Timestamp:
Nov 2, 1999, 5:19:23 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
ee979cd
Parents:
8a5f2ca
Message:

Split mutex.c into multiple files.

Files:
40 added
5 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/posix/include/rtems/posix/mutex.h

    r8a5f2ca r96c041c  
    4141 
    4242POSIX_EXTERN Objects_Information  _POSIX_Mutex_Information;
     43
     44/*
     45 *  The default mutex attributes structure.
     46 */
     47
     48extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
    4349 
    4450/*
     
    109115);
    110116
     117/*
     118 *  _POSIX_Mutex_Lock_support
     119 *
     120 *  DESCRIPTION:
     121 * 
     122 *  A support routine which implements guts of the blocking, non-blocking, and
     123 *  timed wait version of mutex lock.
     124 */
     125
     126int _POSIX_Mutex_Lock_support(
     127  pthread_mutex_t           *mutex,
     128  boolean                    blocking,
     129  Watchdog_Interval          timeout
     130);
     131
     132/*
     133 *  _POSIX_Mutex_From_core_mutex_status
     134 *
     135 *  DESCRIPTION:
     136 *
     137 *  A support routine which converts core mutex status codes into the
     138 *  appropriate POSIX status values.
     139 */
     140
     141int _POSIX_Mutex_From_core_mutex_status(
     142  CORE_mutex_Status  status
     143);
     144
     145
    111146#include <rtems/posix/mutex.inl>
    112147#if defined(RTEMS_MULTIPROCESSING)
  • c/src/exec/posix/src/Makefile.in

    r8a5f2ca r96c041c  
    2828    mqueuetimedreceive mqueuetimedsend mqueueunlink \
    2929
     30MUTEX_C_PIECES= mutex mutexattrdestroy mutexattrgetprioceiling \
     31    mutexattrgetprotocol mutexattrgetpshared mutexattrinit \
     32    mutexattrsetprioceiling mutexattrsetprotocol mutexattrsetpshared \
     33    mutexdefaultattributes mutexdestroy mutexfromcorestatus \
     34    mutexgetprioceiling mutexinit mutexlock mutexlocksupp mutexmp \
     35    mutexsetprioceiling mutextimedlock mutextrylock mutexunlock
     36
    3037PTHREAD_C_PIECES = pthread pthreadsetcputime pthreadgetcputime \
    3138    pthreadgetcpuclockid pthreadonce pthreadequal pthreadself pthreadexit \
     
    4552
    4653C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \
    47     mutex $(PTHREAD_C_PIECES) \
     54    $(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
    4855    $(PSIGNAL_C_PIECES) ptimer sched time types unistd $(ENOSYS_C_PIECES) \
    4956    $(BUILD_FOR_NOW_C_PIECES)
  • c/src/exec/posix/src/mutex.c

    r8a5f2ca r96c041c  
    1616#include <rtems/posix/priority.h>
    1717#include <rtems/posix/time.h>
    18 
    19 /*
    20  *  TEMPORARY
    21  */
    22 
    23 #if defined(RTEMS_MULTIPROCESSING)
    24 void _POSIX_Mutex_MP_Send_process_packet (
    25   POSIX_Mutex_MP_Remote_operations  operation,
    26   Objects_Id                        mutex_id,
    27   Objects_Name                      name,
    28   Objects_Id                        proxy_id
    29 )
    30 {
    31   (void) POSIX_MP_NOT_IMPLEMENTED();
    32 }
    33 
    34 void _POSIX_Mutex_MP_Send_object_was_deleted (
    35   Thread_Control *the_proxy
    36 )
    37 {
    38   (void) POSIX_MP_NOT_IMPLEMENTED();
    39 }
    40 
    41 int _POSIX_Mutex_MP_Send_request_packet (
    42   POSIX_Mutex_MP_Remote_operations  operation,
    43   Objects_Id                        mutex_id,
    44   boolean                           wait,  /* XXX options */
    45   Watchdog_Interval                 timeout
    46 )
    47 {
    48   return POSIX_MP_NOT_IMPLEMENTED();
    49 }
    50 
    51 void POSIX_Threads_mutex_MP_support(
    52   Thread_Control *the_thread,
    53   Objects_Id      id
    54 )
    55 {
    56   (void) POSIX_MP_NOT_IMPLEMENTED();   /* XXX: should never get here */
    57 }
    58 #endif
    59 
    60 /*
    61  *  END OF TEMPORARY
    62  */
    63 
    64 /*PAGE
    65  * 
    66  *  The default mutex attributes structure.
    67  */
    68 
    69 const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
    70   TRUE,                                    /* is_initialized */
    71   PTHREAD_PROCESS_PRIVATE,                 /* process_shared */
    72   POSIX_SCHEDULER_MAXIMUM_PRIORITY,        /* prio_ceiling   */
    73   PTHREAD_PRIO_NONE,                       /* protocol       */
    74   FALSE                                    /* recursive      */
    75 };
    76 
    77 /*PAGE
    78  *
    79  *  _POSIX_Mutex_From_core_mutex_status
    80  */
    81 
    82 int _POSIX_Mutex_From_core_mutex_status(
    83   CORE_mutex_Status  status
    84 )
    85 {
    86   switch ( status ) {
    87     case CORE_MUTEX_STATUS_SUCCESSFUL:
    88       return 0;
    89     case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
    90       return EBUSY;
    91     case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
    92       return EDEADLK;
    93     case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
    94       return EPERM;
    95     case CORE_MUTEX_WAS_DELETED:
    96       return EINVAL;
    97     case CORE_MUTEX_TIMEOUT:
    98       return EAGAIN;
    99     case CORE_MUTEX_STATUS_CEILING_VIOLATED:
    100       return EINVAL;
    101     default:
    102       break;
    103   }
    104   assert( 0 );
    105   return 0;
    106 }
    10718
    10819/*PAGE
     
    13344  );
    13445}
    135 
    136 /*PAGE
    137  *
    138  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    139  */
    140 
    141 int pthread_mutexattr_init(
    142   pthread_mutexattr_t *attr
    143 )
    144 {
    145   if ( !attr )
    146     return EINVAL;
    147 
    148   *attr = _POSIX_Mutex_Default_attributes;
    149   return 0;
    150 }
    151 
    152 /*PAGE
    153  *
    154  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    155  */
    156 
    157 int pthread_mutexattr_destroy(
    158   pthread_mutexattr_t *attr
    159 )
    160 {
    161   if ( !attr || !attr->is_initialized )
    162     return EINVAL;
    163 
    164   attr->is_initialized = FALSE;
    165   return 0;
    166 }
    167 
    168 /*PAGE
    169  *
    170  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    171  */
    172 
    173 int pthread_mutexattr_getpshared(
    174   const pthread_mutexattr_t *attr,
    175   int                       *pshared
    176 )
    177 {
    178   if ( !attr || !attr->is_initialized || !pshared )
    179     return EINVAL;
    180 
    181   *pshared = attr->process_shared;
    182   return 0;
    183 }
    184 
    185 /*PAGE
    186  *
    187  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    188  */
    189 
    190 int pthread_mutexattr_setpshared(
    191   pthread_mutexattr_t *attr,
    192   int                  pshared
    193 )
    194 {
    195   if ( !attr || !attr->is_initialized )
    196     return EINVAL;
    197 
    198   switch ( pshared ) {
    199     case PTHREAD_PROCESS_SHARED:
    200     case PTHREAD_PROCESS_PRIVATE:
    201       attr->process_shared = pshared;
    202       return 0;
    203 
    204     default:
    205       return EINVAL;
    206   }
    207 }
    208 
    209 /*PAGE
    210  *
    211  *  11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
    212  *
    213  *  NOTE:  XXX Could be optimized so all the attribute error checking
    214  *             is not performed when attr is NULL.
    215  */
    216 
    217 int pthread_mutex_init(
    218   pthread_mutex_t           *mutex,
    219   const pthread_mutexattr_t *attr
    220 )
    221 {
    222   POSIX_Mutex_Control          *the_mutex;
    223   CORE_mutex_Attributes        *the_mutex_attr;
    224   const pthread_mutexattr_t    *the_attr;
    225   CORE_mutex_Disciplines        the_discipline;
    226 #if 0
    227   register POSIX_Mutex_Control *mutex_in_use;
    228   Objects_Locations             location;
    229 #endif
    230 
    231   if ( attr ) the_attr = attr;
    232   else        the_attr = &_POSIX_Mutex_Default_attributes;
    233 
    234   /* Check for NULL mutex */
    235 
    236   if ( !mutex )
    237     return EINVAL;
    238 
    239   /*
    240    *  This code should eventually be removed. 
    241    *
    242    *  Although the POSIX specification says:
    243    *
    244    *  "Attempting to initialize an already initialized mutex results
    245    *  in undefined behavior."
    246    *
    247    *  Trying to keep the caller from doing the create when *mutex
    248    *  is actually a valid ID causes grief.  All it takes is the wrong
    249    *  value in an uninitialized variable to make this fail.  As best
    250    *  I can tell, RTEMS was the only pthread implementation to choose
    251    *  this option for "undefined behavior" and doing so has created
    252    *  portability problems.  In particular, Rosimildo DaSilva
    253    *  <rdasilva@connecttel.com> saw seemingly random failures in the
    254    *  RTEMS port of omniORB2 when this code was enabled.
    255    *
    256    *  Joel Sherrill <joel@OARcorp.com>     14 May 1999
    257    */
    258 
    259  
    260 #if 0
    261   /* avoid infinite recursion on call to this routine in _POSIX_Mutex_Get */
    262 
    263   if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) {
    264 
    265     /* EBUSY if *mutex is a valid id */
    266 
    267     mutex_in_use = _POSIX_Mutex_Get( mutex, &location );
    268     switch ( location ) {
    269       case OBJECTS_REMOTE:
    270       case OBJECTS_ERROR:
    271         break;
    272       case OBJECTS_LOCAL:
    273         _Thread_Enable_dispatch();
    274         return EBUSY;
    275     }
    276   }
    277 #endif
    278  
    279   if ( !the_attr->is_initialized )
    280     return EINVAL;
    281 
    282   /*
    283    *  XXX: Be careful about attributes when global!!!
    284    */
    285 
    286   assert( the_attr->process_shared == PTHREAD_PROCESS_PRIVATE );
    287 
    288 #if defined(RTEMS_MULTIPROCESSING)
    289   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    290     return POSIX_MP_NOT_IMPLEMENTED();
    291 #endif
    292  
    293   /*
    294    *  Determine the discipline of the mutex
    295    */
    296  
    297   switch ( the_attr->protocol ) {
    298     case PTHREAD_PRIO_NONE:
    299       the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
    300       break;
    301     case PTHREAD_PRIO_INHERIT:
    302       the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    303       break;
    304     case PTHREAD_PRIO_PROTECT:
    305       the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    306       break;
    307     default:
    308       return EINVAL;
    309   }
    310 
    311   if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) )
    312     return EINVAL;
    313 
    314   _Thread_Disable_dispatch();
    315 
    316   the_mutex = _POSIX_Mutex_Allocate();
    317  
    318   if ( !the_mutex ) {
    319     _Thread_Enable_dispatch();
    320     return EAGAIN;
    321   }
    322 
    323 #if defined(RTEMS_MULTIPROCESSING)
    324   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
    325        !( _Objects_MP_Allocate_and_open( &_POSIX_Mutex_Information, 0,
    326                             the_mutex->Object.id, FALSE ) ) ) {
    327     _POSIX_Mutex_Free( the_mutex );
    328     _Thread_Enable_dispatch();
    329     return EAGAIN;
    330   }
    331 #endif
    332 
    333   the_mutex->process_shared = the_attr->process_shared;
    334 
    335   the_mutex_attr = &the_mutex->Mutex.Attributes;
    336 
    337   the_mutex_attr->allow_nesting = the_attr->recursive;
    338   the_mutex_attr->priority_ceiling =
    339     _POSIX_Priority_To_core( the_attr->prio_ceiling );
    340   the_mutex_attr->discipline = the_discipline;
    341 
    342   /*
    343    *  Must be initialized to unlocked.
    344    */
    345 
    346   _CORE_mutex_Initialize(
    347     &the_mutex->Mutex,
    348     OBJECTS_POSIX_MUTEXES,
    349     the_mutex_attr,
    350     CORE_MUTEX_UNLOCKED,
    351     NULL                      /* proxy_extract_callout */
    352   );
    353 
    354   _Objects_Open( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
    355 
    356   *mutex = the_mutex->Object.id;
    357 
    358 #if defined(RTEMS_MULTIPROCESSING)
    359   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    360     _POSIX_Mutex_MP_Send_process_packet(
    361       POSIX_MUTEX_MP_ANNOUNCE_CREATE,
    362       the_mutex->Object.id,
    363       0,                         /* Name not used */
    364       0                          /* Not used */
    365     );
    366 #endif
    367 
    368   _Thread_Enable_dispatch();
    369   return 0;
    370 }
    371 
    372 /*PAGE
    373  *
    374  *  11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
    375  */
    376 
    377 int pthread_mutex_destroy(
    378   pthread_mutex_t           *mutex
    379 )
    380 {
    381   register POSIX_Mutex_Control *the_mutex;
    382   Objects_Locations             location;
    383  
    384   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    385   switch ( location ) {
    386     case OBJECTS_REMOTE:
    387 #if defined(RTEMS_MULTIPROCESSING)
    388       _Thread_Dispatch();
    389       return POSIX_MP_NOT_IMPLEMENTED();
    390       return EINVAL;
    391 #endif
    392     case OBJECTS_ERROR:
    393       return EINVAL;
    394     case OBJECTS_LOCAL:
    395        /*
    396         * XXX: There is an error for the mutex being locked
    397         *  or being in use by a condition variable.
    398         */
    399 
    400       if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
    401         _Thread_Enable_dispatch();
    402         return EBUSY;
    403       }
    404  
    405       _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
    406  
    407       _CORE_mutex_Flush(
    408         &the_mutex->Mutex,
    409 #if defined(RTEMS_MULTIPROCESSING)
    410         _POSIX_Mutex_MP_Send_object_was_deleted,
    411 #else
    412         NULL,
    413 #endif
    414         EINVAL
    415       );
    416  
    417       _POSIX_Mutex_Free( the_mutex );
    418  
    419 #if defined(RTEMS_MULTIPROCESSING)
    420       if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
    421  
    422         _Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
    423  
    424         _POSIX_Mutex_MP_Send_process_packet(
    425           POSIX_MUTEX_MP_ANNOUNCE_DELETE,
    426           the_mutex->Object.id,
    427           0,                         /* Not used */
    428           0                          /* Not used */
    429         );
    430       }
    431 #endif
    432       _Thread_Enable_dispatch();
    433       return 0;
    434   }
    435   return POSIX_BOTTOM_REACHED();
    436 }
    437 
    438 /*PAGE
    439  *
    440  *  _POSIX_Mutex_Lock_support
    441  *
    442  *  A support routine which implements guts of the blocking, non-blocking, and
    443  *  timed wait version of mutex lock.
    444  */
    445 
    446 int _POSIX_Mutex_Lock_support(
    447   pthread_mutex_t           *mutex,
    448   boolean                    blocking,
    449   Watchdog_Interval          timeout
    450 )
    451 {
    452   register POSIX_Mutex_Control *the_mutex;
    453   Objects_Locations             location;
    454  
    455   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    456   switch ( location ) {
    457     case OBJECTS_REMOTE:
    458 #if defined(RTEMS_MULTIPROCESSING)
    459       return _POSIX_Mutex_MP_Send_request_packet(
    460           POSIX_MUTEX_MP_OBTAIN_REQUEST,
    461           *mutex,
    462           0,   /* must define the option set */
    463           WATCHDOG_NO_TIMEOUT
    464       );
    465 #endif
    466     case OBJECTS_ERROR:
    467       return EINVAL;
    468     case OBJECTS_LOCAL:
    469       _CORE_mutex_Seize(
    470         &the_mutex->Mutex,
    471         the_mutex->Object.id,
    472         blocking,
    473         timeout
    474       );
    475       _Thread_Enable_dispatch();
    476       return _POSIX_Mutex_From_core_mutex_status(
    477         (CORE_mutex_Status) _Thread_Executing->Wait.return_code
    478       );
    479   }
    480   return POSIX_BOTTOM_REACHED();
    481 }
    482 
    483 /*PAGE
    484  *
    485  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    486  *       
    487  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    488  */
    489 
    490 int pthread_mutex_lock(
    491   pthread_mutex_t           *mutex
    492 )
    493 {
    494   return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
    495 }
    496 
    497 /*PAGE
    498  *
    499  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    500  *       
    501  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    502  */
    503 
    504 int pthread_mutex_trylock(
    505   pthread_mutex_t           *mutex
    506 )
    507 {
    508   return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
    509 }
    510 
    511 /*PAGE
    512  *
    513  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    514  *       
    515  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    516  */
    517 
    518 int pthread_mutex_unlock(
    519   pthread_mutex_t           *mutex
    520 )
    521 {
    522   register POSIX_Mutex_Control *the_mutex;
    523   Objects_Locations             location;
    524   CORE_mutex_Status             status;
    525  
    526   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    527   switch ( location ) {
    528     case OBJECTS_REMOTE:
    529 #if defined(RTEMS_MULTIPROCESSING)
    530       return _POSIX_Mutex_MP_Send_request_packet(
    531           POSIX_MUTEX_MP_RELEASE_REQUEST,
    532           *mutex,
    533           0,                    /* Not used */
    534           MPCI_DEFAULT_TIMEOUT
    535       );
    536 #endif
    537     case OBJECTS_ERROR:
    538       return EINVAL;
    539     case OBJECTS_LOCAL:
    540       status = _CORE_mutex_Surrender(
    541         &the_mutex->Mutex,
    542         the_mutex->Object.id,
    543 #if defined(RTEMS_MULTIPROCESSING)
    544         POSIX_Threads_mutex_MP_support
    545 #else
    546         NULL
    547 #endif
    548       );
    549       _Thread_Enable_dispatch();
    550       return _POSIX_Mutex_From_core_mutex_status( status );
    551       break;
    552   }
    553   return POSIX_BOTTOM_REACHED();
    554 }
    555 
    556 /*PAGE
    557  *
    558  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    559  *       
    560  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    561  */
    562 
    563 int pthread_mutex_timedlock(
    564   pthread_mutex_t       *mutex,
    565   const struct timespec *timeout
    566 )
    567 {
    568   return _POSIX_Mutex_Lock_support(
    569     mutex,
    570     TRUE,
    571     _POSIX_Timespec_to_interval( timeout )
    572   );
    573 }
    574 
    575 /*PAGE
    576  *
    577  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    578  */
    579  
    580 int pthread_mutexattr_setprotocol(
    581   pthread_mutexattr_t   *attr,
    582   int                    protocol
    583 )
    584 {
    585   if ( !attr || !attr->is_initialized )
    586     return EINVAL;
    587 
    588   switch ( protocol ) {
    589     case PTHREAD_PRIO_NONE:
    590     case PTHREAD_PRIO_INHERIT:
    591     case PTHREAD_PRIO_PROTECT:
    592       attr->protocol = protocol;
    593       return 0;
    594  
    595     default:
    596       return EINVAL;
    597   }
    598 }
    599 
    600 /*PAGE
    601  *
    602  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    603  */
    604  
    605 int pthread_mutexattr_getprotocol(
    606   const pthread_mutexattr_t   *attr,
    607   int                         *protocol
    608 )
    609 {
    610   if ( !attr || !attr->is_initialized || !protocol )
    611     return EINVAL;
    612 
    613   *protocol = attr->protocol;
    614   return 0;
    615 }
    616 
    617 /*PAGE
    618  *
    619  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    620  */
    621  
    622 int pthread_mutexattr_setprioceiling(
    623   pthread_mutexattr_t   *attr,
    624   int                    prioceiling
    625 )
    626 {
    627   if ( !attr || !attr->is_initialized )
    628     return EINVAL;
    629 
    630   if ( !_POSIX_Priority_Is_valid( prioceiling ) )
    631     return EINVAL;
    632 
    633   attr->prio_ceiling = prioceiling;
    634   return 0;
    635 }
    636 
    637 /*PAGE
    638  *
    639  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    640  */
    641  
    642 int pthread_mutexattr_getprioceiling(
    643   const pthread_mutexattr_t   *attr,
    644   int                         *prioceiling
    645 )
    646 {
    647   if ( !attr || !attr->is_initialized || !prioceiling )
    648     return EINVAL;
    649 
    650   *prioceiling = attr->prio_ceiling;
    651   return 0;
    652 }
    653 
    654 /*PAGE
    655  *
    656  *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    657  */
    658 
    659 int pthread_mutex_setprioceiling(
    660   pthread_mutex_t   *mutex,
    661   int                prioceiling,
    662   int               *old_ceiling
    663 )
    664 {
    665   register POSIX_Mutex_Control *the_mutex;
    666   Objects_Locations             location;
    667   Priority_Control              the_priority;
    668   int                           status;
    669 
    670   if ( !old_ceiling )
    671     return EINVAL;
    672 
    673   if ( !_POSIX_Priority_Is_valid( prioceiling ) )
    674     return EINVAL;
    675 
    676   the_priority = _POSIX_Priority_To_core( prioceiling );
    677 
    678   /*
    679    *  Must acquire the mutex before we can change it's ceiling
    680    */
    681 
    682   status = pthread_mutex_lock( mutex );
    683   if ( status )
    684     return status;
    685 
    686   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    687   switch ( location ) {
    688     case OBJECTS_REMOTE:
    689 #if defined(RTEMS_MULTIPROCESSING)
    690       /*  XXX It feels questionable to set the ceiling on a remote mutex. */
    691       return EINVAL;
    692 #endif
    693     case OBJECTS_ERROR:
    694       return EINVAL;        /* impossible to get here */
    695     case OBJECTS_LOCAL:
    696       *old_ceiling = _POSIX_Priority_From_core(
    697         the_mutex->Mutex.Attributes.priority_ceiling
    698       );
    699       the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
    700       _CORE_mutex_Surrender(
    701         &the_mutex->Mutex,
    702         the_mutex->Object.id,
    703 #if defined(RTEMS_MULTIPROCESSING)
    704         POSIX_Threads_mutex_MP_support
    705 #else
    706         NULL
    707 #endif
    708       );
    709       _Thread_Enable_dispatch();
    710       return 0;
    711   }
    712   return POSIX_BOTTOM_REACHED();
    713 }
    714  
    715 /*PAGE
    716  *
    717  *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    718  */
    719 
    720 int pthread_mutex_getprioceiling(
    721   pthread_mutex_t   *mutex,
    722   int               *prioceiling
    723 )
    724 {
    725   register POSIX_Mutex_Control *the_mutex;
    726   Objects_Locations             location;
    727 
    728   if ( !prioceiling )
    729     return EINVAL;
    730 
    731   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    732   switch ( location ) {
    733     case OBJECTS_REMOTE:
    734 #if defined(RTEMS_MULTIPROCESSING)
    735       return POSIX_MP_NOT_IMPLEMENTED();   /* XXX feels questionable */
    736 #endif
    737     case OBJECTS_ERROR:
    738       return EINVAL;
    739     case OBJECTS_LOCAL:
    740       *prioceiling = _POSIX_Priority_From_core(
    741         the_mutex->Mutex.Attributes.priority_ceiling
    742       );
    743       _Thread_Enable_dispatch();
    744       return 0;
    745   }
    746   return POSIX_BOTTOM_REACHED();
    747 }
  • cpukit/posix/include/rtems/posix/mutex.h

    r8a5f2ca r96c041c  
    4141 
    4242POSIX_EXTERN Objects_Information  _POSIX_Mutex_Information;
     43
     44/*
     45 *  The default mutex attributes structure.
     46 */
     47
     48extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
    4349 
    4450/*
     
    109115);
    110116
     117/*
     118 *  _POSIX_Mutex_Lock_support
     119 *
     120 *  DESCRIPTION:
     121 * 
     122 *  A support routine which implements guts of the blocking, non-blocking, and
     123 *  timed wait version of mutex lock.
     124 */
     125
     126int _POSIX_Mutex_Lock_support(
     127  pthread_mutex_t           *mutex,
     128  boolean                    blocking,
     129  Watchdog_Interval          timeout
     130);
     131
     132/*
     133 *  _POSIX_Mutex_From_core_mutex_status
     134 *
     135 *  DESCRIPTION:
     136 *
     137 *  A support routine which converts core mutex status codes into the
     138 *  appropriate POSIX status values.
     139 */
     140
     141int _POSIX_Mutex_From_core_mutex_status(
     142  CORE_mutex_Status  status
     143);
     144
     145
    111146#include <rtems/posix/mutex.inl>
    112147#if defined(RTEMS_MULTIPROCESSING)
  • cpukit/posix/src/mutex.c

    r8a5f2ca r96c041c  
    1616#include <rtems/posix/priority.h>
    1717#include <rtems/posix/time.h>
    18 
    19 /*
    20  *  TEMPORARY
    21  */
    22 
    23 #if defined(RTEMS_MULTIPROCESSING)
    24 void _POSIX_Mutex_MP_Send_process_packet (
    25   POSIX_Mutex_MP_Remote_operations  operation,
    26   Objects_Id                        mutex_id,
    27   Objects_Name                      name,
    28   Objects_Id                        proxy_id
    29 )
    30 {
    31   (void) POSIX_MP_NOT_IMPLEMENTED();
    32 }
    33 
    34 void _POSIX_Mutex_MP_Send_object_was_deleted (
    35   Thread_Control *the_proxy
    36 )
    37 {
    38   (void) POSIX_MP_NOT_IMPLEMENTED();
    39 }
    40 
    41 int _POSIX_Mutex_MP_Send_request_packet (
    42   POSIX_Mutex_MP_Remote_operations  operation,
    43   Objects_Id                        mutex_id,
    44   boolean                           wait,  /* XXX options */
    45   Watchdog_Interval                 timeout
    46 )
    47 {
    48   return POSIX_MP_NOT_IMPLEMENTED();
    49 }
    50 
    51 void POSIX_Threads_mutex_MP_support(
    52   Thread_Control *the_thread,
    53   Objects_Id      id
    54 )
    55 {
    56   (void) POSIX_MP_NOT_IMPLEMENTED();   /* XXX: should never get here */
    57 }
    58 #endif
    59 
    60 /*
    61  *  END OF TEMPORARY
    62  */
    63 
    64 /*PAGE
    65  * 
    66  *  The default mutex attributes structure.
    67  */
    68 
    69 const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
    70   TRUE,                                    /* is_initialized */
    71   PTHREAD_PROCESS_PRIVATE,                 /* process_shared */
    72   POSIX_SCHEDULER_MAXIMUM_PRIORITY,        /* prio_ceiling   */
    73   PTHREAD_PRIO_NONE,                       /* protocol       */
    74   FALSE                                    /* recursive      */
    75 };
    76 
    77 /*PAGE
    78  *
    79  *  _POSIX_Mutex_From_core_mutex_status
    80  */
    81 
    82 int _POSIX_Mutex_From_core_mutex_status(
    83   CORE_mutex_Status  status
    84 )
    85 {
    86   switch ( status ) {
    87     case CORE_MUTEX_STATUS_SUCCESSFUL:
    88       return 0;
    89     case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
    90       return EBUSY;
    91     case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
    92       return EDEADLK;
    93     case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
    94       return EPERM;
    95     case CORE_MUTEX_WAS_DELETED:
    96       return EINVAL;
    97     case CORE_MUTEX_TIMEOUT:
    98       return EAGAIN;
    99     case CORE_MUTEX_STATUS_CEILING_VIOLATED:
    100       return EINVAL;
    101     default:
    102       break;
    103   }
    104   assert( 0 );
    105   return 0;
    106 }
    10718
    10819/*PAGE
     
    13344  );
    13445}
    135 
    136 /*PAGE
    137  *
    138  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    139  */
    140 
    141 int pthread_mutexattr_init(
    142   pthread_mutexattr_t *attr
    143 )
    144 {
    145   if ( !attr )
    146     return EINVAL;
    147 
    148   *attr = _POSIX_Mutex_Default_attributes;
    149   return 0;
    150 }
    151 
    152 /*PAGE
    153  *
    154  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    155  */
    156 
    157 int pthread_mutexattr_destroy(
    158   pthread_mutexattr_t *attr
    159 )
    160 {
    161   if ( !attr || !attr->is_initialized )
    162     return EINVAL;
    163 
    164   attr->is_initialized = FALSE;
    165   return 0;
    166 }
    167 
    168 /*PAGE
    169  *
    170  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    171  */
    172 
    173 int pthread_mutexattr_getpshared(
    174   const pthread_mutexattr_t *attr,
    175   int                       *pshared
    176 )
    177 {
    178   if ( !attr || !attr->is_initialized || !pshared )
    179     return EINVAL;
    180 
    181   *pshared = attr->process_shared;
    182   return 0;
    183 }
    184 
    185 /*PAGE
    186  *
    187  *  11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
    188  */
    189 
    190 int pthread_mutexattr_setpshared(
    191   pthread_mutexattr_t *attr,
    192   int                  pshared
    193 )
    194 {
    195   if ( !attr || !attr->is_initialized )
    196     return EINVAL;
    197 
    198   switch ( pshared ) {
    199     case PTHREAD_PROCESS_SHARED:
    200     case PTHREAD_PROCESS_PRIVATE:
    201       attr->process_shared = pshared;
    202       return 0;
    203 
    204     default:
    205       return EINVAL;
    206   }
    207 }
    208 
    209 /*PAGE
    210  *
    211  *  11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
    212  *
    213  *  NOTE:  XXX Could be optimized so all the attribute error checking
    214  *             is not performed when attr is NULL.
    215  */
    216 
    217 int pthread_mutex_init(
    218   pthread_mutex_t           *mutex,
    219   const pthread_mutexattr_t *attr
    220 )
    221 {
    222   POSIX_Mutex_Control          *the_mutex;
    223   CORE_mutex_Attributes        *the_mutex_attr;
    224   const pthread_mutexattr_t    *the_attr;
    225   CORE_mutex_Disciplines        the_discipline;
    226 #if 0
    227   register POSIX_Mutex_Control *mutex_in_use;
    228   Objects_Locations             location;
    229 #endif
    230 
    231   if ( attr ) the_attr = attr;
    232   else        the_attr = &_POSIX_Mutex_Default_attributes;
    233 
    234   /* Check for NULL mutex */
    235 
    236   if ( !mutex )
    237     return EINVAL;
    238 
    239   /*
    240    *  This code should eventually be removed. 
    241    *
    242    *  Although the POSIX specification says:
    243    *
    244    *  "Attempting to initialize an already initialized mutex results
    245    *  in undefined behavior."
    246    *
    247    *  Trying to keep the caller from doing the create when *mutex
    248    *  is actually a valid ID causes grief.  All it takes is the wrong
    249    *  value in an uninitialized variable to make this fail.  As best
    250    *  I can tell, RTEMS was the only pthread implementation to choose
    251    *  this option for "undefined behavior" and doing so has created
    252    *  portability problems.  In particular, Rosimildo DaSilva
    253    *  <rdasilva@connecttel.com> saw seemingly random failures in the
    254    *  RTEMS port of omniORB2 when this code was enabled.
    255    *
    256    *  Joel Sherrill <joel@OARcorp.com>     14 May 1999
    257    */
    258 
    259  
    260 #if 0
    261   /* avoid infinite recursion on call to this routine in _POSIX_Mutex_Get */
    262 
    263   if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) {
    264 
    265     /* EBUSY if *mutex is a valid id */
    266 
    267     mutex_in_use = _POSIX_Mutex_Get( mutex, &location );
    268     switch ( location ) {
    269       case OBJECTS_REMOTE:
    270       case OBJECTS_ERROR:
    271         break;
    272       case OBJECTS_LOCAL:
    273         _Thread_Enable_dispatch();
    274         return EBUSY;
    275     }
    276   }
    277 #endif
    278  
    279   if ( !the_attr->is_initialized )
    280     return EINVAL;
    281 
    282   /*
    283    *  XXX: Be careful about attributes when global!!!
    284    */
    285 
    286   assert( the_attr->process_shared == PTHREAD_PROCESS_PRIVATE );
    287 
    288 #if defined(RTEMS_MULTIPROCESSING)
    289   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    290     return POSIX_MP_NOT_IMPLEMENTED();
    291 #endif
    292  
    293   /*
    294    *  Determine the discipline of the mutex
    295    */
    296  
    297   switch ( the_attr->protocol ) {
    298     case PTHREAD_PRIO_NONE:
    299       the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
    300       break;
    301     case PTHREAD_PRIO_INHERIT:
    302       the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
    303       break;
    304     case PTHREAD_PRIO_PROTECT:
    305       the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
    306       break;
    307     default:
    308       return EINVAL;
    309   }
    310 
    311   if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) )
    312     return EINVAL;
    313 
    314   _Thread_Disable_dispatch();
    315 
    316   the_mutex = _POSIX_Mutex_Allocate();
    317  
    318   if ( !the_mutex ) {
    319     _Thread_Enable_dispatch();
    320     return EAGAIN;
    321   }
    322 
    323 #if defined(RTEMS_MULTIPROCESSING)
    324   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
    325        !( _Objects_MP_Allocate_and_open( &_POSIX_Mutex_Information, 0,
    326                             the_mutex->Object.id, FALSE ) ) ) {
    327     _POSIX_Mutex_Free( the_mutex );
    328     _Thread_Enable_dispatch();
    329     return EAGAIN;
    330   }
    331 #endif
    332 
    333   the_mutex->process_shared = the_attr->process_shared;
    334 
    335   the_mutex_attr = &the_mutex->Mutex.Attributes;
    336 
    337   the_mutex_attr->allow_nesting = the_attr->recursive;
    338   the_mutex_attr->priority_ceiling =
    339     _POSIX_Priority_To_core( the_attr->prio_ceiling );
    340   the_mutex_attr->discipline = the_discipline;
    341 
    342   /*
    343    *  Must be initialized to unlocked.
    344    */
    345 
    346   _CORE_mutex_Initialize(
    347     &the_mutex->Mutex,
    348     OBJECTS_POSIX_MUTEXES,
    349     the_mutex_attr,
    350     CORE_MUTEX_UNLOCKED,
    351     NULL                      /* proxy_extract_callout */
    352   );
    353 
    354   _Objects_Open( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
    355 
    356   *mutex = the_mutex->Object.id;
    357 
    358 #if defined(RTEMS_MULTIPROCESSING)
    359   if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
    360     _POSIX_Mutex_MP_Send_process_packet(
    361       POSIX_MUTEX_MP_ANNOUNCE_CREATE,
    362       the_mutex->Object.id,
    363       0,                         /* Name not used */
    364       0                          /* Not used */
    365     );
    366 #endif
    367 
    368   _Thread_Enable_dispatch();
    369   return 0;
    370 }
    371 
    372 /*PAGE
    373  *
    374  *  11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
    375  */
    376 
    377 int pthread_mutex_destroy(
    378   pthread_mutex_t           *mutex
    379 )
    380 {
    381   register POSIX_Mutex_Control *the_mutex;
    382   Objects_Locations             location;
    383  
    384   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    385   switch ( location ) {
    386     case OBJECTS_REMOTE:
    387 #if defined(RTEMS_MULTIPROCESSING)
    388       _Thread_Dispatch();
    389       return POSIX_MP_NOT_IMPLEMENTED();
    390       return EINVAL;
    391 #endif
    392     case OBJECTS_ERROR:
    393       return EINVAL;
    394     case OBJECTS_LOCAL:
    395        /*
    396         * XXX: There is an error for the mutex being locked
    397         *  or being in use by a condition variable.
    398         */
    399 
    400       if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
    401         _Thread_Enable_dispatch();
    402         return EBUSY;
    403       }
    404  
    405       _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
    406  
    407       _CORE_mutex_Flush(
    408         &the_mutex->Mutex,
    409 #if defined(RTEMS_MULTIPROCESSING)
    410         _POSIX_Mutex_MP_Send_object_was_deleted,
    411 #else
    412         NULL,
    413 #endif
    414         EINVAL
    415       );
    416  
    417       _POSIX_Mutex_Free( the_mutex );
    418  
    419 #if defined(RTEMS_MULTIPROCESSING)
    420       if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
    421  
    422         _Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
    423  
    424         _POSIX_Mutex_MP_Send_process_packet(
    425           POSIX_MUTEX_MP_ANNOUNCE_DELETE,
    426           the_mutex->Object.id,
    427           0,                         /* Not used */
    428           0                          /* Not used */
    429         );
    430       }
    431 #endif
    432       _Thread_Enable_dispatch();
    433       return 0;
    434   }
    435   return POSIX_BOTTOM_REACHED();
    436 }
    437 
    438 /*PAGE
    439  *
    440  *  _POSIX_Mutex_Lock_support
    441  *
    442  *  A support routine which implements guts of the blocking, non-blocking, and
    443  *  timed wait version of mutex lock.
    444  */
    445 
    446 int _POSIX_Mutex_Lock_support(
    447   pthread_mutex_t           *mutex,
    448   boolean                    blocking,
    449   Watchdog_Interval          timeout
    450 )
    451 {
    452   register POSIX_Mutex_Control *the_mutex;
    453   Objects_Locations             location;
    454  
    455   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    456   switch ( location ) {
    457     case OBJECTS_REMOTE:
    458 #if defined(RTEMS_MULTIPROCESSING)
    459       return _POSIX_Mutex_MP_Send_request_packet(
    460           POSIX_MUTEX_MP_OBTAIN_REQUEST,
    461           *mutex,
    462           0,   /* must define the option set */
    463           WATCHDOG_NO_TIMEOUT
    464       );
    465 #endif
    466     case OBJECTS_ERROR:
    467       return EINVAL;
    468     case OBJECTS_LOCAL:
    469       _CORE_mutex_Seize(
    470         &the_mutex->Mutex,
    471         the_mutex->Object.id,
    472         blocking,
    473         timeout
    474       );
    475       _Thread_Enable_dispatch();
    476       return _POSIX_Mutex_From_core_mutex_status(
    477         (CORE_mutex_Status) _Thread_Executing->Wait.return_code
    478       );
    479   }
    480   return POSIX_BOTTOM_REACHED();
    481 }
    482 
    483 /*PAGE
    484  *
    485  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    486  *       
    487  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    488  */
    489 
    490 int pthread_mutex_lock(
    491   pthread_mutex_t           *mutex
    492 )
    493 {
    494   return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
    495 }
    496 
    497 /*PAGE
    498  *
    499  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    500  *       
    501  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    502  */
    503 
    504 int pthread_mutex_trylock(
    505   pthread_mutex_t           *mutex
    506 )
    507 {
    508   return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
    509 }
    510 
    511 /*PAGE
    512  *
    513  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    514  *       
    515  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    516  */
    517 
    518 int pthread_mutex_unlock(
    519   pthread_mutex_t           *mutex
    520 )
    521 {
    522   register POSIX_Mutex_Control *the_mutex;
    523   Objects_Locations             location;
    524   CORE_mutex_Status             status;
    525  
    526   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    527   switch ( location ) {
    528     case OBJECTS_REMOTE:
    529 #if defined(RTEMS_MULTIPROCESSING)
    530       return _POSIX_Mutex_MP_Send_request_packet(
    531           POSIX_MUTEX_MP_RELEASE_REQUEST,
    532           *mutex,
    533           0,                    /* Not used */
    534           MPCI_DEFAULT_TIMEOUT
    535       );
    536 #endif
    537     case OBJECTS_ERROR:
    538       return EINVAL;
    539     case OBJECTS_LOCAL:
    540       status = _CORE_mutex_Surrender(
    541         &the_mutex->Mutex,
    542         the_mutex->Object.id,
    543 #if defined(RTEMS_MULTIPROCESSING)
    544         POSIX_Threads_mutex_MP_support
    545 #else
    546         NULL
    547 #endif
    548       );
    549       _Thread_Enable_dispatch();
    550       return _POSIX_Mutex_From_core_mutex_status( status );
    551       break;
    552   }
    553   return POSIX_BOTTOM_REACHED();
    554 }
    555 
    556 /*PAGE
    557  *
    558  *  11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
    559  *       
    560  *  NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
    561  */
    562 
    563 int pthread_mutex_timedlock(
    564   pthread_mutex_t       *mutex,
    565   const struct timespec *timeout
    566 )
    567 {
    568   return _POSIX_Mutex_Lock_support(
    569     mutex,
    570     TRUE,
    571     _POSIX_Timespec_to_interval( timeout )
    572   );
    573 }
    574 
    575 /*PAGE
    576  *
    577  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    578  */
    579  
    580 int pthread_mutexattr_setprotocol(
    581   pthread_mutexattr_t   *attr,
    582   int                    protocol
    583 )
    584 {
    585   if ( !attr || !attr->is_initialized )
    586     return EINVAL;
    587 
    588   switch ( protocol ) {
    589     case PTHREAD_PRIO_NONE:
    590     case PTHREAD_PRIO_INHERIT:
    591     case PTHREAD_PRIO_PROTECT:
    592       attr->protocol = protocol;
    593       return 0;
    594  
    595     default:
    596       return EINVAL;
    597   }
    598 }
    599 
    600 /*PAGE
    601  *
    602  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    603  */
    604  
    605 int pthread_mutexattr_getprotocol(
    606   const pthread_mutexattr_t   *attr,
    607   int                         *protocol
    608 )
    609 {
    610   if ( !attr || !attr->is_initialized || !protocol )
    611     return EINVAL;
    612 
    613   *protocol = attr->protocol;
    614   return 0;
    615 }
    616 
    617 /*PAGE
    618  *
    619  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    620  */
    621  
    622 int pthread_mutexattr_setprioceiling(
    623   pthread_mutexattr_t   *attr,
    624   int                    prioceiling
    625 )
    626 {
    627   if ( !attr || !attr->is_initialized )
    628     return EINVAL;
    629 
    630   if ( !_POSIX_Priority_Is_valid( prioceiling ) )
    631     return EINVAL;
    632 
    633   attr->prio_ceiling = prioceiling;
    634   return 0;
    635 }
    636 
    637 /*PAGE
    638  *
    639  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
    640  */
    641  
    642 int pthread_mutexattr_getprioceiling(
    643   const pthread_mutexattr_t   *attr,
    644   int                         *prioceiling
    645 )
    646 {
    647   if ( !attr || !attr->is_initialized || !prioceiling )
    648     return EINVAL;
    649 
    650   *prioceiling = attr->prio_ceiling;
    651   return 0;
    652 }
    653 
    654 /*PAGE
    655  *
    656  *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    657  */
    658 
    659 int pthread_mutex_setprioceiling(
    660   pthread_mutex_t   *mutex,
    661   int                prioceiling,
    662   int               *old_ceiling
    663 )
    664 {
    665   register POSIX_Mutex_Control *the_mutex;
    666   Objects_Locations             location;
    667   Priority_Control              the_priority;
    668   int                           status;
    669 
    670   if ( !old_ceiling )
    671     return EINVAL;
    672 
    673   if ( !_POSIX_Priority_Is_valid( prioceiling ) )
    674     return EINVAL;
    675 
    676   the_priority = _POSIX_Priority_To_core( prioceiling );
    677 
    678   /*
    679    *  Must acquire the mutex before we can change it's ceiling
    680    */
    681 
    682   status = pthread_mutex_lock( mutex );
    683   if ( status )
    684     return status;
    685 
    686   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    687   switch ( location ) {
    688     case OBJECTS_REMOTE:
    689 #if defined(RTEMS_MULTIPROCESSING)
    690       /*  XXX It feels questionable to set the ceiling on a remote mutex. */
    691       return EINVAL;
    692 #endif
    693     case OBJECTS_ERROR:
    694       return EINVAL;        /* impossible to get here */
    695     case OBJECTS_LOCAL:
    696       *old_ceiling = _POSIX_Priority_From_core(
    697         the_mutex->Mutex.Attributes.priority_ceiling
    698       );
    699       the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
    700       _CORE_mutex_Surrender(
    701         &the_mutex->Mutex,
    702         the_mutex->Object.id,
    703 #if defined(RTEMS_MULTIPROCESSING)
    704         POSIX_Threads_mutex_MP_support
    705 #else
    706         NULL
    707 #endif
    708       );
    709       _Thread_Enable_dispatch();
    710       return 0;
    711   }
    712   return POSIX_BOTTOM_REACHED();
    713 }
    714  
    715 /*PAGE
    716  *
    717  *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    718  */
    719 
    720 int pthread_mutex_getprioceiling(
    721   pthread_mutex_t   *mutex,
    722   int               *prioceiling
    723 )
    724 {
    725   register POSIX_Mutex_Control *the_mutex;
    726   Objects_Locations             location;
    727 
    728   if ( !prioceiling )
    729     return EINVAL;
    730 
    731   the_mutex = _POSIX_Mutex_Get( mutex, &location );
    732   switch ( location ) {
    733     case OBJECTS_REMOTE:
    734 #if defined(RTEMS_MULTIPROCESSING)
    735       return POSIX_MP_NOT_IMPLEMENTED();   /* XXX feels questionable */
    736 #endif
    737     case OBJECTS_ERROR:
    738       return EINVAL;
    739     case OBJECTS_LOCAL:
    740       *prioceiling = _POSIX_Priority_From_core(
    741         the_mutex->Mutex.Attributes.priority_ceiling
    742       );
    743       _Thread_Enable_dispatch();
    744       return 0;
    745   }
    746   return POSIX_BOTTOM_REACHED();
    747 }
Note: See TracChangeset for help on using the changeset viewer.