From 96c041c42ba7cf9489113bb337c8dc9b344f152e Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 2 Nov 1999 17:19:23 +0000 Subject: Split mutex.c into multiple files. --- cpukit/posix/src/mutexinit.c | 180 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 cpukit/posix/src/mutexinit.c (limited to 'cpukit/posix/src/mutexinit.c') diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c new file mode 100644 index 0000000000..04c8c8132f --- /dev/null +++ b/cpukit/posix/src/mutexinit.c @@ -0,0 +1,180 @@ +/* + * $Id$ + */ + +#include +#include +#include + +#include +#include +#include +#if defined(RTEMS_MULTIPROCESSING) +#include +#endif +#include +#include +#include + +/*PAGE + * + * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 + * + * NOTE: XXX Could be optimized so all the attribute error checking + * is not performed when attr is NULL. + */ + +int pthread_mutex_init( + pthread_mutex_t *mutex, + const pthread_mutexattr_t *attr +) +{ + POSIX_Mutex_Control *the_mutex; + CORE_mutex_Attributes *the_mutex_attr; + const pthread_mutexattr_t *the_attr; + CORE_mutex_Disciplines the_discipline; +#if 0 + register POSIX_Mutex_Control *mutex_in_use; + Objects_Locations location; +#endif + + if ( attr ) the_attr = attr; + else the_attr = &_POSIX_Mutex_Default_attributes; + + /* Check for NULL mutex */ + + if ( !mutex ) + return EINVAL; + + /* + * This code should eventually be removed. + * + * Although the POSIX specification says: + * + * "Attempting to initialize an already initialized mutex results + * in undefined behavior." + * + * Trying to keep the caller from doing the create when *mutex + * is actually a valid ID causes grief. All it takes is the wrong + * value in an uninitialized variable to make this fail. As best + * I can tell, RTEMS was the only pthread implementation to choose + * this option for "undefined behavior" and doing so has created + * portability problems. In particular, Rosimildo DaSilva + * saw seemingly random failures in the + * RTEMS port of omniORB2 when this code was enabled. + * + * Joel Sherrill 14 May 1999 + */ + + +#if 0 + /* avoid infinite recursion on call to this routine in _POSIX_Mutex_Get */ + + if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) { + + /* EBUSY if *mutex is a valid id */ + + mutex_in_use = _POSIX_Mutex_Get( mutex, &location ); + switch ( location ) { + case OBJECTS_REMOTE: + case OBJECTS_ERROR: + break; + case OBJECTS_LOCAL: + _Thread_Enable_dispatch(); + return EBUSY; + } + } +#endif + + if ( !the_attr->is_initialized ) + return EINVAL; + + /* + * XXX: Be careful about attributes when global!!! + */ + + assert( the_attr->process_shared == PTHREAD_PROCESS_PRIVATE ); + +#if defined(RTEMS_MULTIPROCESSING) + if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED ) + return POSIX_MP_NOT_IMPLEMENTED(); +#endif + + /* + * Determine the discipline of the mutex + */ + + switch ( the_attr->protocol ) { + case PTHREAD_PRIO_NONE: + the_discipline = CORE_MUTEX_DISCIPLINES_FIFO; + break; + case PTHREAD_PRIO_INHERIT: + the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT; + break; + case PTHREAD_PRIO_PROTECT: + the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING; + break; + default: + return EINVAL; + } + + if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) ) + return EINVAL; + + _Thread_Disable_dispatch(); + + the_mutex = _POSIX_Mutex_Allocate(); + + if ( !the_mutex ) { + _Thread_Enable_dispatch(); + return EAGAIN; + } + +#if defined(RTEMS_MULTIPROCESSING) + if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED && + !( _Objects_MP_Allocate_and_open( &_POSIX_Mutex_Information, 0, + the_mutex->Object.id, FALSE ) ) ) { + _POSIX_Mutex_Free( the_mutex ); + _Thread_Enable_dispatch(); + return EAGAIN; + } +#endif + + the_mutex->process_shared = the_attr->process_shared; + + the_mutex_attr = &the_mutex->Mutex.Attributes; + + the_mutex_attr->allow_nesting = the_attr->recursive; + the_mutex_attr->priority_ceiling = + _POSIX_Priority_To_core( the_attr->prio_ceiling ); + the_mutex_attr->discipline = the_discipline; + + /* + * Must be initialized to unlocked. + */ + + _CORE_mutex_Initialize( + &the_mutex->Mutex, + OBJECTS_POSIX_MUTEXES, + the_mutex_attr, + CORE_MUTEX_UNLOCKED, + NULL /* proxy_extract_callout */ + ); + + _Objects_Open( &_POSIX_Mutex_Information, &the_mutex->Object, 0 ); + + *mutex = the_mutex->Object.id; + +#if defined(RTEMS_MULTIPROCESSING) + if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED ) + _POSIX_Mutex_MP_Send_process_packet( + POSIX_MUTEX_MP_ANNOUNCE_CREATE, + the_mutex->Object.id, + 0, /* Name not used */ + 0 /* Not used */ + ); +#endif + + _Thread_Enable_dispatch(); + return 0; +} -- cgit v1.2.3