forked from Imagelibrary/rtems
Split mutex.c into multiple files.
This commit is contained in:
@@ -40,6 +40,12 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
POSIX_EXTERN Objects_Information _POSIX_Mutex_Information;
|
POSIX_EXTERN Objects_Information _POSIX_Mutex_Information;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default mutex attributes structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _POSIX_Mutex_Manager_initialization
|
* _POSIX_Mutex_Manager_initialization
|
||||||
@@ -108,6 +114,35 @@ RTEMS_INLINE_ROUTINE boolean _POSIX_Mutex_Is_null (
|
|||||||
POSIX_Mutex_Control *the_mutex
|
POSIX_Mutex_Control *the_mutex
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _POSIX_Mutex_Lock_support
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* A support routine which implements guts of the blocking, non-blocking, and
|
||||||
|
* timed wait version of mutex lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_Lock_support(
|
||||||
|
pthread_mutex_t *mutex,
|
||||||
|
boolean blocking,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _POSIX_Mutex_From_core_mutex_status
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* A support routine which converts core mutex status codes into the
|
||||||
|
* appropriate POSIX status values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_From_core_mutex_status(
|
||||||
|
CORE_mutex_Status status
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#include <rtems/posix/mutex.inl>
|
#include <rtems/posix/mutex.inl>
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
#include <rtems/posix/mutexmp.h>
|
#include <rtems/posix/mutexmp.h>
|
||||||
|
|||||||
@@ -27,6 +27,13 @@ MESSAGE_QUEUE_PIECES= mqueue mqueueclose mqueuecreatesupp mqueuedeletesupp \
|
|||||||
mqueuerecvsupp mqueuesend mqueuesendsupp mqueuesetattr \
|
mqueuerecvsupp mqueuesend mqueuesendsupp mqueuesetattr \
|
||||||
mqueuetimedreceive mqueuetimedsend mqueueunlink \
|
mqueuetimedreceive mqueuetimedsend mqueueunlink \
|
||||||
|
|
||||||
|
MUTEX_C_PIECES= mutex mutexattrdestroy mutexattrgetprioceiling \
|
||||||
|
mutexattrgetprotocol mutexattrgetpshared mutexattrinit \
|
||||||
|
mutexattrsetprioceiling mutexattrsetprotocol mutexattrsetpshared \
|
||||||
|
mutexdefaultattributes mutexdestroy mutexfromcorestatus \
|
||||||
|
mutexgetprioceiling mutexinit mutexlock mutexlocksupp mutexmp \
|
||||||
|
mutexsetprioceiling mutextimedlock mutextrylock mutexunlock
|
||||||
|
|
||||||
PTHREAD_C_PIECES = pthread pthreadsetcputime pthreadgetcputime \
|
PTHREAD_C_PIECES = pthread pthreadsetcputime pthreadgetcputime \
|
||||||
pthreadgetcpuclockid pthreadonce pthreadequal pthreadself pthreadexit \
|
pthreadgetcpuclockid pthreadonce pthreadequal pthreadself pthreadexit \
|
||||||
pthreaddetach pthreadjoin pthreadcreate pthreadattrsetdetachstate \
|
pthreaddetach pthreadjoin pthreadcreate pthreadattrsetdetachstate \
|
||||||
@@ -44,7 +51,7 @@ PSIGNAL_C_PIECES = psignal alarm kill killinfo pause pthreadkill \
|
|||||||
sigwait sigwaitinfo signal_2
|
sigwait sigwaitinfo signal_2
|
||||||
|
|
||||||
C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \
|
C_PIECES = adasupp cond getpid key $(MESSAGE_QUEUE_PIECES) \
|
||||||
mutex $(PTHREAD_C_PIECES) \
|
$(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
|
||||||
$(PSIGNAL_C_PIECES) ptimer sched time types unistd $(ENOSYS_C_PIECES) \
|
$(PSIGNAL_C_PIECES) ptimer sched time types unistd $(ENOSYS_C_PIECES) \
|
||||||
$(BUILD_FOR_NOW_C_PIECES)
|
$(BUILD_FOR_NOW_C_PIECES)
|
||||||
|
|
||||||
|
|||||||
@@ -16,95 +16,6 @@
|
|||||||
#include <rtems/posix/priority.h>
|
#include <rtems/posix/priority.h>
|
||||||
#include <rtems/posix/time.h>
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* TEMPORARY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
void _POSIX_Mutex_MP_Send_process_packet (
|
|
||||||
POSIX_Mutex_MP_Remote_operations operation,
|
|
||||||
Objects_Id mutex_id,
|
|
||||||
Objects_Name name,
|
|
||||||
Objects_Id proxy_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _POSIX_Mutex_MP_Send_object_was_deleted (
|
|
||||||
Thread_Control *the_proxy
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
int _POSIX_Mutex_MP_Send_request_packet (
|
|
||||||
POSIX_Mutex_MP_Remote_operations operation,
|
|
||||||
Objects_Id mutex_id,
|
|
||||||
boolean wait, /* XXX options */
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void POSIX_Threads_mutex_MP_support(
|
|
||||||
Thread_Control *the_thread,
|
|
||||||
Objects_Id id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) POSIX_MP_NOT_IMPLEMENTED(); /* XXX: should never get here */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* END OF TEMPORARY
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* The default mutex attributes structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
|
|
||||||
TRUE, /* is_initialized */
|
|
||||||
PTHREAD_PROCESS_PRIVATE, /* process_shared */
|
|
||||||
POSIX_SCHEDULER_MAXIMUM_PRIORITY, /* prio_ceiling */
|
|
||||||
PTHREAD_PRIO_NONE, /* protocol */
|
|
||||||
FALSE /* recursive */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Mutex_From_core_mutex_status
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Mutex_From_core_mutex_status(
|
|
||||||
CORE_mutex_Status status
|
|
||||||
)
|
|
||||||
{
|
|
||||||
switch ( status ) {
|
|
||||||
case CORE_MUTEX_STATUS_SUCCESSFUL:
|
|
||||||
return 0;
|
|
||||||
case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
|
|
||||||
return EBUSY;
|
|
||||||
case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
|
|
||||||
return EDEADLK;
|
|
||||||
case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
|
|
||||||
return EPERM;
|
|
||||||
case CORE_MUTEX_WAS_DELETED:
|
|
||||||
return EINVAL;
|
|
||||||
case CORE_MUTEX_TIMEOUT:
|
|
||||||
return EAGAIN;
|
|
||||||
case CORE_MUTEX_STATUS_CEILING_VIOLATED:
|
|
||||||
return EINVAL;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert( 0 );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _POSIX_Mutex_Manager_initialization
|
* _POSIX_Mutex_Manager_initialization
|
||||||
@@ -132,616 +43,3 @@ void _POSIX_Mutex_Manager_initialization(
|
|||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_init(
|
|
||||||
pthread_mutexattr_t *attr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*attr = _POSIX_Mutex_Default_attributes;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_destroy(
|
|
||||||
pthread_mutexattr_t *attr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
attr->is_initialized = FALSE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_getpshared(
|
|
||||||
const pthread_mutexattr_t *attr,
|
|
||||||
int *pshared
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized || !pshared )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*pshared = attr->process_shared;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_setpshared(
|
|
||||||
pthread_mutexattr_t *attr,
|
|
||||||
int pshared
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
switch ( pshared ) {
|
|
||||||
case PTHREAD_PROCESS_SHARED:
|
|
||||||
case PTHREAD_PROCESS_PRIVATE:
|
|
||||||
attr->process_shared = pshared;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*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
|
|
||||||
* <rdasilva@connecttel.com> saw seemingly random failures in the
|
|
||||||
* RTEMS port of omniORB2 when this code was enabled.
|
|
||||||
*
|
|
||||||
* Joel Sherrill <joel@OARcorp.com> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_destroy(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
return EINVAL;
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/*
|
|
||||||
* XXX: There is an error for the mutex being locked
|
|
||||||
* or being in use by a condition variable.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
|
|
||||||
|
|
||||||
_CORE_mutex_Flush(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_POSIX_Mutex_MP_Send_object_was_deleted,
|
|
||||||
#else
|
|
||||||
NULL,
|
|
||||||
#endif
|
|
||||||
EINVAL
|
|
||||||
);
|
|
||||||
|
|
||||||
_POSIX_Mutex_Free( the_mutex );
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
|
|
||||||
|
|
||||||
_Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
|
|
||||||
|
|
||||||
_POSIX_Mutex_MP_Send_process_packet(
|
|
||||||
POSIX_MUTEX_MP_ANNOUNCE_DELETE,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
0, /* Not used */
|
|
||||||
0 /* Not used */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Mutex_Lock_support
|
|
||||||
*
|
|
||||||
* A support routine which implements guts of the blocking, non-blocking, and
|
|
||||||
* timed wait version of mutex lock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Mutex_Lock_support(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
boolean blocking,
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return _POSIX_Mutex_MP_Send_request_packet(
|
|
||||||
POSIX_MUTEX_MP_OBTAIN_REQUEST,
|
|
||||||
*mutex,
|
|
||||||
0, /* must define the option set */
|
|
||||||
WATCHDOG_NO_TIMEOUT
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
_CORE_mutex_Seize(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
blocking,
|
|
||||||
timeout
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return _POSIX_Mutex_From_core_mutex_status(
|
|
||||||
(CORE_mutex_Status) _Thread_Executing->Wait.return_code
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_lock(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_trylock(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_unlock(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
CORE_mutex_Status status;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return _POSIX_Mutex_MP_Send_request_packet(
|
|
||||||
POSIX_MUTEX_MP_RELEASE_REQUEST,
|
|
||||||
*mutex,
|
|
||||||
0, /* Not used */
|
|
||||||
MPCI_DEFAULT_TIMEOUT
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
status = _CORE_mutex_Surrender(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
POSIX_Threads_mutex_MP_support
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return _POSIX_Mutex_From_core_mutex_status( status );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_timedlock(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
const struct timespec *timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Mutex_Lock_support(
|
|
||||||
mutex,
|
|
||||||
TRUE,
|
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_setprotocol(
|
|
||||||
pthread_mutexattr_t *attr,
|
|
||||||
int protocol
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
switch ( protocol ) {
|
|
||||||
case PTHREAD_PRIO_NONE:
|
|
||||||
case PTHREAD_PRIO_INHERIT:
|
|
||||||
case PTHREAD_PRIO_PROTECT:
|
|
||||||
attr->protocol = protocol;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_getprotocol(
|
|
||||||
const pthread_mutexattr_t *attr,
|
|
||||||
int *protocol
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized || !protocol )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*protocol = attr->protocol;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_setprioceiling(
|
|
||||||
pthread_mutexattr_t *attr,
|
|
||||||
int prioceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
attr->prio_ceiling = prioceiling;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_getprioceiling(
|
|
||||||
const pthread_mutexattr_t *attr,
|
|
||||||
int *prioceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized || !prioceiling )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*prioceiling = attr->prio_ceiling;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_setprioceiling(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
int prioceiling,
|
|
||||||
int *old_ceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
Priority_Control the_priority;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if ( !old_ceiling )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
the_priority = _POSIX_Priority_To_core( prioceiling );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Must acquire the mutex before we can change it's ceiling
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = pthread_mutex_lock( mutex );
|
|
||||||
if ( status )
|
|
||||||
return status;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
/* XXX It feels questionable to set the ceiling on a remote mutex. */
|
|
||||||
return EINVAL;
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL; /* impossible to get here */
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
*old_ceiling = _POSIX_Priority_From_core(
|
|
||||||
the_mutex->Mutex.Attributes.priority_ceiling
|
|
||||||
);
|
|
||||||
the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
|
|
||||||
_CORE_mutex_Surrender(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
POSIX_Threads_mutex_MP_support
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_getprioceiling(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
int *prioceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
if ( !prioceiling )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED(); /* XXX feels questionable */
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
*prioceiling = _POSIX_Priority_From_core(
|
|
||||||
the_mutex->Mutex.Attributes.priority_ceiling
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|||||||
34
c/src/exec/posix/src/mutexattrdestroy.c
Normal file
34
c/src/exec/posix/src/mutexattrdestroy.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_destroy(
|
||||||
|
pthread_mutexattr_t *attr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
attr->is_initialized = FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
34
c/src/exec/posix/src/mutexattrgetprioceiling.c
Normal file
34
c/src/exec/posix/src/mutexattrgetprioceiling.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_getprioceiling(
|
||||||
|
const pthread_mutexattr_t *attr,
|
||||||
|
int *prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized || !prioceiling )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*prioceiling = attr->prio_ceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
c/src/exec/posix/src/mutexattrgetprotocol.c
Normal file
42
c/src/exec/posix/src/mutexattrgetprotocol.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprotocol(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int protocol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch ( protocol ) {
|
||||||
|
case PTHREAD_PRIO_NONE:
|
||||||
|
case PTHREAD_PRIO_INHERIT:
|
||||||
|
case PTHREAD_PRIO_PROTECT:
|
||||||
|
attr->protocol = protocol;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
c/src/exec/posix/src/mutexattrgetpshared.c
Normal file
34
c/src/exec/posix/src/mutexattrgetpshared.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_getpshared(
|
||||||
|
const pthread_mutexattr_t *attr,
|
||||||
|
int *pshared
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized || !pshared )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*pshared = attr->process_shared;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
33
c/src/exec/posix/src/mutexattrinit.c
Normal file
33
c/src/exec/posix/src/mutexattrinit.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_init(
|
||||||
|
pthread_mutexattr_t *attr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*attr = _POSIX_Mutex_Default_attributes;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
37
c/src/exec/posix/src/mutexattrsetprioceiling.c
Normal file
37
c/src/exec/posix/src/mutexattrsetprioceiling.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprioceiling(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
attr->prio_ceiling = prioceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
c/src/exec/posix/src/mutexattrsetprotocol.c
Normal file
42
c/src/exec/posix/src/mutexattrsetprotocol.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprotocol(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int protocol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch ( protocol ) {
|
||||||
|
case PTHREAD_PRIO_NONE:
|
||||||
|
case PTHREAD_PRIO_INHERIT:
|
||||||
|
case PTHREAD_PRIO_PROTECT:
|
||||||
|
attr->protocol = protocol;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
42
c/src/exec/posix/src/mutexattrsetpshared.c
Normal file
42
c/src/exec/posix/src/mutexattrsetpshared.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setpshared(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int pshared
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch ( pshared ) {
|
||||||
|
case PTHREAD_PROCESS_SHARED:
|
||||||
|
case PTHREAD_PROCESS_PRIVATE:
|
||||||
|
attr->process_shared = pshared;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
30
c/src/exec/posix/src/mutexdefaultattributes.c
Normal file
30
c/src/exec/posix/src/mutexdefaultattributes.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* The default mutex attributes structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
|
||||||
|
TRUE, /* is_initialized */
|
||||||
|
PTHREAD_PROCESS_PRIVATE, /* process_shared */
|
||||||
|
POSIX_SCHEDULER_MAXIMUM_PRIORITY, /* prio_ceiling */
|
||||||
|
PTHREAD_PRIO_NONE, /* protocol */
|
||||||
|
FALSE /* recursive */
|
||||||
|
};
|
||||||
83
c/src/exec/posix/src/mutexdestroy.c
Normal file
83
c/src/exec/posix/src/mutexdestroy.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_destroy(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Mutex_Control *the_mutex;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
return EINVAL;
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return EINVAL;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/*
|
||||||
|
* XXX: There is an error for the mutex being locked
|
||||||
|
* or being in use by a condition variable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
|
||||||
|
|
||||||
|
_CORE_mutex_Flush(
|
||||||
|
&the_mutex->Mutex,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_POSIX_Mutex_MP_Send_object_was_deleted,
|
||||||
|
#else
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
|
EINVAL
|
||||||
|
);
|
||||||
|
|
||||||
|
_POSIX_Mutex_Free( the_mutex );
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
|
||||||
|
|
||||||
|
_Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
|
||||||
|
|
||||||
|
_POSIX_Mutex_MP_Send_process_packet(
|
||||||
|
POSIX_MUTEX_MP_ANNOUNCE_DELETE,
|
||||||
|
the_mutex->Object.id,
|
||||||
|
0, /* Not used */
|
||||||
|
0 /* Not used */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
48
c/src/exec/posix/src/mutexfromcorestatus.c
Normal file
48
c/src/exec/posix/src/mutexfromcorestatus.c
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Mutex_From_core_mutex_status
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_From_core_mutex_status(
|
||||||
|
CORE_mutex_Status status
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch ( status ) {
|
||||||
|
case CORE_MUTEX_STATUS_SUCCESSFUL:
|
||||||
|
return 0;
|
||||||
|
case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
|
||||||
|
return EBUSY;
|
||||||
|
case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
|
||||||
|
return EDEADLK;
|
||||||
|
case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
|
||||||
|
return EPERM;
|
||||||
|
case CORE_MUTEX_WAS_DELETED:
|
||||||
|
return EINVAL;
|
||||||
|
case CORE_MUTEX_TIMEOUT:
|
||||||
|
return EAGAIN;
|
||||||
|
case CORE_MUTEX_STATUS_CEILING_VIOLATED:
|
||||||
|
return EINVAL;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert( 0 );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
34
c/src/exec/posix/src/mutexgetprioceiling.c
Normal file
34
c/src/exec/posix/src/mutexgetprioceiling.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_getprioceiling(
|
||||||
|
const pthread_mutexattr_t *attr,
|
||||||
|
int *prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized || !prioceiling )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*prioceiling = attr->prio_ceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
180
c/src/exec/posix/src/mutexinit.c
Normal file
180
c/src/exec/posix/src/mutexinit.c
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*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
|
||||||
|
* <rdasilva@connecttel.com> saw seemingly random failures in the
|
||||||
|
* RTEMS port of omniORB2 when this code was enabled.
|
||||||
|
*
|
||||||
|
* Joel Sherrill <joel@OARcorp.com> 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;
|
||||||
|
}
|
||||||
31
c/src/exec/posix/src/mutexlock.c
Normal file
31
c/src/exec/posix/src/mutexlock.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_lock(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
|
||||||
|
}
|
||||||
62
c/src/exec/posix/src/mutexlocksupp.c
Normal file
62
c/src/exec/posix/src/mutexlocksupp.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Mutex_Lock_support
|
||||||
|
*
|
||||||
|
* A support routine which implements guts of the blocking, non-blocking, and
|
||||||
|
* timed wait version of mutex lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_Lock_support(
|
||||||
|
pthread_mutex_t *mutex,
|
||||||
|
boolean blocking,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Mutex_Control *the_mutex;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
return _POSIX_Mutex_MP_Send_request_packet(
|
||||||
|
POSIX_MUTEX_MP_OBTAIN_REQUEST,
|
||||||
|
*mutex,
|
||||||
|
0, /* must define the option set */
|
||||||
|
WATCHDOG_NO_TIMEOUT
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return EINVAL;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
_CORE_mutex_Seize(
|
||||||
|
&the_mutex->Mutex,
|
||||||
|
the_mutex->Object.id,
|
||||||
|
blocking,
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return _POSIX_Mutex_From_core_mutex_status(
|
||||||
|
(CORE_mutex_Status) _Thread_Executing->Wait.return_code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
62
c/src/exec/posix/src/mutexmp.c
Normal file
62
c/src/exec/posix/src/mutexmp.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEMPORARY
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
void _POSIX_Mutex_MP_Send_process_packet (
|
||||||
|
POSIX_Mutex_MP_Remote_operations operation,
|
||||||
|
Objects_Id mutex_id,
|
||||||
|
Objects_Name name,
|
||||||
|
Objects_Id proxy_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(void) POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _POSIX_Mutex_MP_Send_object_was_deleted (
|
||||||
|
Thread_Control *the_proxy
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(void) POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
int _POSIX_Mutex_MP_Send_request_packet (
|
||||||
|
POSIX_Mutex_MP_Remote_operations operation,
|
||||||
|
Objects_Id mutex_id,
|
||||||
|
boolean wait, /* XXX options */
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void POSIX_Threads_mutex_MP_support(
|
||||||
|
Thread_Control *the_thread,
|
||||||
|
Objects_Id id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(void) POSIX_MP_NOT_IMPLEMENTED(); /* XXX: should never get here */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* END OF TEMPORARY
|
||||||
|
*/
|
||||||
37
c/src/exec/posix/src/mutexsetprioceiling.c
Normal file
37
c/src/exec/posix/src/mutexsetprioceiling.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprioceiling(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
attr->prio_ceiling = prioceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
36
c/src/exec/posix/src/mutextimedlock.c
Normal file
36
c/src/exec/posix/src/mutextimedlock.c
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_timedlock(
|
||||||
|
pthread_mutex_t *mutex,
|
||||||
|
const struct timespec *timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Mutex_Lock_support(
|
||||||
|
mutex,
|
||||||
|
TRUE,
|
||||||
|
_POSIX_Timespec_to_interval( timeout )
|
||||||
|
);
|
||||||
|
}
|
||||||
31
c/src/exec/posix/src/mutextrylock.c
Normal file
31
c/src/exec/posix/src/mutextrylock.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_trylock(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
|
||||||
|
}
|
||||||
62
c/src/exec/posix/src/mutexunlock.c
Normal file
62
c/src/exec/posix/src/mutexunlock.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_unlock(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Mutex_Control *the_mutex;
|
||||||
|
Objects_Locations location;
|
||||||
|
CORE_mutex_Status status;
|
||||||
|
|
||||||
|
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
return _POSIX_Mutex_MP_Send_request_packet(
|
||||||
|
POSIX_MUTEX_MP_RELEASE_REQUEST,
|
||||||
|
*mutex,
|
||||||
|
0, /* Not used */
|
||||||
|
MPCI_DEFAULT_TIMEOUT
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return EINVAL;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
status = _CORE_mutex_Surrender(
|
||||||
|
&the_mutex->Mutex,
|
||||||
|
the_mutex->Object.id,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
POSIX_Threads_mutex_MP_support
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return _POSIX_Mutex_From_core_mutex_status( status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
@@ -40,6 +40,12 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
POSIX_EXTERN Objects_Information _POSIX_Mutex_Information;
|
POSIX_EXTERN Objects_Information _POSIX_Mutex_Information;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default mutex attributes structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _POSIX_Mutex_Manager_initialization
|
* _POSIX_Mutex_Manager_initialization
|
||||||
@@ -108,6 +114,35 @@ RTEMS_INLINE_ROUTINE boolean _POSIX_Mutex_Is_null (
|
|||||||
POSIX_Mutex_Control *the_mutex
|
POSIX_Mutex_Control *the_mutex
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _POSIX_Mutex_Lock_support
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* A support routine which implements guts of the blocking, non-blocking, and
|
||||||
|
* timed wait version of mutex lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_Lock_support(
|
||||||
|
pthread_mutex_t *mutex,
|
||||||
|
boolean blocking,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _POSIX_Mutex_From_core_mutex_status
|
||||||
|
*
|
||||||
|
* DESCRIPTION:
|
||||||
|
*
|
||||||
|
* A support routine which converts core mutex status codes into the
|
||||||
|
* appropriate POSIX status values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_From_core_mutex_status(
|
||||||
|
CORE_mutex_Status status
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#include <rtems/posix/mutex.inl>
|
#include <rtems/posix/mutex.inl>
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
#include <rtems/posix/mutexmp.h>
|
#include <rtems/posix/mutexmp.h>
|
||||||
|
|||||||
@@ -16,95 +16,6 @@
|
|||||||
#include <rtems/posix/priority.h>
|
#include <rtems/posix/priority.h>
|
||||||
#include <rtems/posix/time.h>
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* TEMPORARY
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
void _POSIX_Mutex_MP_Send_process_packet (
|
|
||||||
POSIX_Mutex_MP_Remote_operations operation,
|
|
||||||
Objects_Id mutex_id,
|
|
||||||
Objects_Name name,
|
|
||||||
Objects_Id proxy_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _POSIX_Mutex_MP_Send_object_was_deleted (
|
|
||||||
Thread_Control *the_proxy
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
int _POSIX_Mutex_MP_Send_request_packet (
|
|
||||||
POSIX_Mutex_MP_Remote_operations operation,
|
|
||||||
Objects_Id mutex_id,
|
|
||||||
boolean wait, /* XXX options */
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void POSIX_Threads_mutex_MP_support(
|
|
||||||
Thread_Control *the_thread,
|
|
||||||
Objects_Id id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) POSIX_MP_NOT_IMPLEMENTED(); /* XXX: should never get here */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* END OF TEMPORARY
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* The default mutex attributes structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
|
|
||||||
TRUE, /* is_initialized */
|
|
||||||
PTHREAD_PROCESS_PRIVATE, /* process_shared */
|
|
||||||
POSIX_SCHEDULER_MAXIMUM_PRIORITY, /* prio_ceiling */
|
|
||||||
PTHREAD_PRIO_NONE, /* protocol */
|
|
||||||
FALSE /* recursive */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Mutex_From_core_mutex_status
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Mutex_From_core_mutex_status(
|
|
||||||
CORE_mutex_Status status
|
|
||||||
)
|
|
||||||
{
|
|
||||||
switch ( status ) {
|
|
||||||
case CORE_MUTEX_STATUS_SUCCESSFUL:
|
|
||||||
return 0;
|
|
||||||
case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
|
|
||||||
return EBUSY;
|
|
||||||
case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
|
|
||||||
return EDEADLK;
|
|
||||||
case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
|
|
||||||
return EPERM;
|
|
||||||
case CORE_MUTEX_WAS_DELETED:
|
|
||||||
return EINVAL;
|
|
||||||
case CORE_MUTEX_TIMEOUT:
|
|
||||||
return EAGAIN;
|
|
||||||
case CORE_MUTEX_STATUS_CEILING_VIOLATED:
|
|
||||||
return EINVAL;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert( 0 );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _POSIX_Mutex_Manager_initialization
|
* _POSIX_Mutex_Manager_initialization
|
||||||
@@ -132,616 +43,3 @@ void _POSIX_Mutex_Manager_initialization(
|
|||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_init(
|
|
||||||
pthread_mutexattr_t *attr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*attr = _POSIX_Mutex_Default_attributes;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_destroy(
|
|
||||||
pthread_mutexattr_t *attr
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
attr->is_initialized = FALSE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_getpshared(
|
|
||||||
const pthread_mutexattr_t *attr,
|
|
||||||
int *pshared
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized || !pshared )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*pshared = attr->process_shared;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_setpshared(
|
|
||||||
pthread_mutexattr_t *attr,
|
|
||||||
int pshared
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
switch ( pshared ) {
|
|
||||||
case PTHREAD_PROCESS_SHARED:
|
|
||||||
case PTHREAD_PROCESS_PRIVATE:
|
|
||||||
attr->process_shared = pshared;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*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
|
|
||||||
* <rdasilva@connecttel.com> saw seemingly random failures in the
|
|
||||||
* RTEMS port of omniORB2 when this code was enabled.
|
|
||||||
*
|
|
||||||
* Joel Sherrill <joel@OARcorp.com> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_destroy(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_Thread_Dispatch();
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED();
|
|
||||||
return EINVAL;
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
/*
|
|
||||||
* XXX: There is an error for the mutex being locked
|
|
||||||
* or being in use by a condition variable.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
|
|
||||||
|
|
||||||
_CORE_mutex_Flush(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
_POSIX_Mutex_MP_Send_object_was_deleted,
|
|
||||||
#else
|
|
||||||
NULL,
|
|
||||||
#endif
|
|
||||||
EINVAL
|
|
||||||
);
|
|
||||||
|
|
||||||
_POSIX_Mutex_Free( the_mutex );
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
|
|
||||||
|
|
||||||
_Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
|
|
||||||
|
|
||||||
_POSIX_Mutex_MP_Send_process_packet(
|
|
||||||
POSIX_MUTEX_MP_ANNOUNCE_DELETE,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
0, /* Not used */
|
|
||||||
0 /* Not used */
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _POSIX_Mutex_Lock_support
|
|
||||||
*
|
|
||||||
* A support routine which implements guts of the blocking, non-blocking, and
|
|
||||||
* timed wait version of mutex lock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _POSIX_Mutex_Lock_support(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
boolean blocking,
|
|
||||||
Watchdog_Interval timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return _POSIX_Mutex_MP_Send_request_packet(
|
|
||||||
POSIX_MUTEX_MP_OBTAIN_REQUEST,
|
|
||||||
*mutex,
|
|
||||||
0, /* must define the option set */
|
|
||||||
WATCHDOG_NO_TIMEOUT
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
_CORE_mutex_Seize(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
blocking,
|
|
||||||
timeout
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return _POSIX_Mutex_From_core_mutex_status(
|
|
||||||
(CORE_mutex_Status) _Thread_Executing->Wait.return_code
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_lock(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_trylock(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_unlock(
|
|
||||||
pthread_mutex_t *mutex
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
CORE_mutex_Status status;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return _POSIX_Mutex_MP_Send_request_packet(
|
|
||||||
POSIX_MUTEX_MP_RELEASE_REQUEST,
|
|
||||||
*mutex,
|
|
||||||
0, /* Not used */
|
|
||||||
MPCI_DEFAULT_TIMEOUT
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
status = _CORE_mutex_Surrender(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
POSIX_Threads_mutex_MP_support
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return _POSIX_Mutex_From_core_mutex_status( status );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
|
||||||
*
|
|
||||||
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_timedlock(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
const struct timespec *timeout
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return _POSIX_Mutex_Lock_support(
|
|
||||||
mutex,
|
|
||||||
TRUE,
|
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_setprotocol(
|
|
||||||
pthread_mutexattr_t *attr,
|
|
||||||
int protocol
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
switch ( protocol ) {
|
|
||||||
case PTHREAD_PRIO_NONE:
|
|
||||||
case PTHREAD_PRIO_INHERIT:
|
|
||||||
case PTHREAD_PRIO_PROTECT:
|
|
||||||
attr->protocol = protocol;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_getprotocol(
|
|
||||||
const pthread_mutexattr_t *attr,
|
|
||||||
int *protocol
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized || !protocol )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*protocol = attr->protocol;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_setprioceiling(
|
|
||||||
pthread_mutexattr_t *attr,
|
|
||||||
int prioceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
attr->prio_ceiling = prioceiling;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutexattr_getprioceiling(
|
|
||||||
const pthread_mutexattr_t *attr,
|
|
||||||
int *prioceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( !attr || !attr->is_initialized || !prioceiling )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
*prioceiling = attr->prio_ceiling;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_setprioceiling(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
int prioceiling,
|
|
||||||
int *old_ceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
Priority_Control the_priority;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
if ( !old_ceiling )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
the_priority = _POSIX_Priority_To_core( prioceiling );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Must acquire the mutex before we can change it's ceiling
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = pthread_mutex_lock( mutex );
|
|
||||||
if ( status )
|
|
||||||
return status;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
/* XXX It feels questionable to set the ceiling on a remote mutex. */
|
|
||||||
return EINVAL;
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL; /* impossible to get here */
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
*old_ceiling = _POSIX_Priority_From_core(
|
|
||||||
the_mutex->Mutex.Attributes.priority_ceiling
|
|
||||||
);
|
|
||||||
the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
|
|
||||||
_CORE_mutex_Surrender(
|
|
||||||
&the_mutex->Mutex,
|
|
||||||
the_mutex->Object.id,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
POSIX_Threads_mutex_MP_support
|
|
||||||
#else
|
|
||||||
NULL
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pthread_mutex_getprioceiling(
|
|
||||||
pthread_mutex_t *mutex,
|
|
||||||
int *prioceiling
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register POSIX_Mutex_Control *the_mutex;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
if ( !prioceiling )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return POSIX_MP_NOT_IMPLEMENTED(); /* XXX feels questionable */
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return EINVAL;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
*prioceiling = _POSIX_Priority_From_core(
|
|
||||||
the_mutex->Mutex.Attributes.priority_ceiling
|
|
||||||
);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return POSIX_BOTTOM_REACHED();
|
|
||||||
}
|
|
||||||
|
|||||||
34
cpukit/posix/src/mutexattrdestroy.c
Normal file
34
cpukit/posix/src/mutexattrdestroy.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_destroy(
|
||||||
|
pthread_mutexattr_t *attr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
attr->is_initialized = FALSE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
34
cpukit/posix/src/mutexattrgetprioceiling.c
Normal file
34
cpukit/posix/src/mutexattrgetprioceiling.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_getprioceiling(
|
||||||
|
const pthread_mutexattr_t *attr,
|
||||||
|
int *prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized || !prioceiling )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*prioceiling = attr->prio_ceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
cpukit/posix/src/mutexattrgetprotocol.c
Normal file
42
cpukit/posix/src/mutexattrgetprotocol.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprotocol(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int protocol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch ( protocol ) {
|
||||||
|
case PTHREAD_PRIO_NONE:
|
||||||
|
case PTHREAD_PRIO_INHERIT:
|
||||||
|
case PTHREAD_PRIO_PROTECT:
|
||||||
|
attr->protocol = protocol;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
cpukit/posix/src/mutexattrgetpshared.c
Normal file
34
cpukit/posix/src/mutexattrgetpshared.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_getpshared(
|
||||||
|
const pthread_mutexattr_t *attr,
|
||||||
|
int *pshared
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized || !pshared )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*pshared = attr->process_shared;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
33
cpukit/posix/src/mutexattrinit.c
Normal file
33
cpukit/posix/src/mutexattrinit.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_init(
|
||||||
|
pthread_mutexattr_t *attr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*attr = _POSIX_Mutex_Default_attributes;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
37
cpukit/posix/src/mutexattrsetprioceiling.c
Normal file
37
cpukit/posix/src/mutexattrsetprioceiling.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprioceiling(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
attr->prio_ceiling = prioceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
cpukit/posix/src/mutexattrsetprotocol.c
Normal file
42
cpukit/posix/src/mutexattrsetprotocol.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprotocol(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int protocol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch ( protocol ) {
|
||||||
|
case PTHREAD_PRIO_NONE:
|
||||||
|
case PTHREAD_PRIO_INHERIT:
|
||||||
|
case PTHREAD_PRIO_PROTECT:
|
||||||
|
attr->protocol = protocol;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
42
cpukit/posix/src/mutexattrsetpshared.c
Normal file
42
cpukit/posix/src/mutexattrsetpshared.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setpshared(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int pshared
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch ( pshared ) {
|
||||||
|
case PTHREAD_PROCESS_SHARED:
|
||||||
|
case PTHREAD_PROCESS_PRIVATE:
|
||||||
|
attr->process_shared = pshared;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
30
cpukit/posix/src/mutexdefaultattributes.c
Normal file
30
cpukit/posix/src/mutexdefaultattributes.c
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* The default mutex attributes structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const pthread_mutexattr_t _POSIX_Mutex_Default_attributes = {
|
||||||
|
TRUE, /* is_initialized */
|
||||||
|
PTHREAD_PROCESS_PRIVATE, /* process_shared */
|
||||||
|
POSIX_SCHEDULER_MAXIMUM_PRIORITY, /* prio_ceiling */
|
||||||
|
PTHREAD_PRIO_NONE, /* protocol */
|
||||||
|
FALSE /* recursive */
|
||||||
|
};
|
||||||
83
cpukit/posix/src/mutexdestroy.c
Normal file
83
cpukit/posix/src/mutexdestroy.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_destroy(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Mutex_Control *the_mutex;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_Thread_Dispatch();
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
return EINVAL;
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return EINVAL;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
/*
|
||||||
|
* XXX: There is an error for the mutex being locked
|
||||||
|
* or being in use by a condition variable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
|
||||||
|
|
||||||
|
_CORE_mutex_Flush(
|
||||||
|
&the_mutex->Mutex,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_POSIX_Mutex_MP_Send_object_was_deleted,
|
||||||
|
#else
|
||||||
|
NULL,
|
||||||
|
#endif
|
||||||
|
EINVAL
|
||||||
|
);
|
||||||
|
|
||||||
|
_POSIX_Mutex_Free( the_mutex );
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
if ( the_mutex->process_shared == PTHREAD_PROCESS_SHARED ) {
|
||||||
|
|
||||||
|
_Objects_MP_Close( &_POSIX_Mutex_Information, the_mutex->Object.id );
|
||||||
|
|
||||||
|
_POSIX_Mutex_MP_Send_process_packet(
|
||||||
|
POSIX_MUTEX_MP_ANNOUNCE_DELETE,
|
||||||
|
the_mutex->Object.id,
|
||||||
|
0, /* Not used */
|
||||||
|
0 /* Not used */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
48
cpukit/posix/src/mutexfromcorestatus.c
Normal file
48
cpukit/posix/src/mutexfromcorestatus.c
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Mutex_From_core_mutex_status
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_From_core_mutex_status(
|
||||||
|
CORE_mutex_Status status
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch ( status ) {
|
||||||
|
case CORE_MUTEX_STATUS_SUCCESSFUL:
|
||||||
|
return 0;
|
||||||
|
case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
|
||||||
|
return EBUSY;
|
||||||
|
case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
|
||||||
|
return EDEADLK;
|
||||||
|
case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
|
||||||
|
return EPERM;
|
||||||
|
case CORE_MUTEX_WAS_DELETED:
|
||||||
|
return EINVAL;
|
||||||
|
case CORE_MUTEX_TIMEOUT:
|
||||||
|
return EAGAIN;
|
||||||
|
case CORE_MUTEX_STATUS_CEILING_VIOLATED:
|
||||||
|
return EINVAL;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert( 0 );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
34
cpukit/posix/src/mutexgetprioceiling.c
Normal file
34
cpukit/posix/src/mutexgetprioceiling.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_getprioceiling(
|
||||||
|
const pthread_mutexattr_t *attr,
|
||||||
|
int *prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized || !prioceiling )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
*prioceiling = attr->prio_ceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
180
cpukit/posix/src/mutexinit.c
Normal file
180
cpukit/posix/src/mutexinit.c
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*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
|
||||||
|
* <rdasilva@connecttel.com> saw seemingly random failures in the
|
||||||
|
* RTEMS port of omniORB2 when this code was enabled.
|
||||||
|
*
|
||||||
|
* Joel Sherrill <joel@OARcorp.com> 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;
|
||||||
|
}
|
||||||
31
cpukit/posix/src/mutexlock.c
Normal file
31
cpukit/posix/src/mutexlock.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_lock(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Mutex_Lock_support( mutex, TRUE, THREAD_QUEUE_WAIT_FOREVER );
|
||||||
|
}
|
||||||
62
cpukit/posix/src/mutexlocksupp.c
Normal file
62
cpukit/posix/src/mutexlocksupp.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _POSIX_Mutex_Lock_support
|
||||||
|
*
|
||||||
|
* A support routine which implements guts of the blocking, non-blocking, and
|
||||||
|
* timed wait version of mutex lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int _POSIX_Mutex_Lock_support(
|
||||||
|
pthread_mutex_t *mutex,
|
||||||
|
boolean blocking,
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Mutex_Control *the_mutex;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
return _POSIX_Mutex_MP_Send_request_packet(
|
||||||
|
POSIX_MUTEX_MP_OBTAIN_REQUEST,
|
||||||
|
*mutex,
|
||||||
|
0, /* must define the option set */
|
||||||
|
WATCHDOG_NO_TIMEOUT
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return EINVAL;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
_CORE_mutex_Seize(
|
||||||
|
&the_mutex->Mutex,
|
||||||
|
the_mutex->Object.id,
|
||||||
|
blocking,
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return _POSIX_Mutex_From_core_mutex_status(
|
||||||
|
(CORE_mutex_Status) _Thread_Executing->Wait.return_code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
62
cpukit/posix/src/mutexmp.c
Normal file
62
cpukit/posix/src/mutexmp.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEMPORARY
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
void _POSIX_Mutex_MP_Send_process_packet (
|
||||||
|
POSIX_Mutex_MP_Remote_operations operation,
|
||||||
|
Objects_Id mutex_id,
|
||||||
|
Objects_Name name,
|
||||||
|
Objects_Id proxy_id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(void) POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _POSIX_Mutex_MP_Send_object_was_deleted (
|
||||||
|
Thread_Control *the_proxy
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(void) POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
int _POSIX_Mutex_MP_Send_request_packet (
|
||||||
|
POSIX_Mutex_MP_Remote_operations operation,
|
||||||
|
Objects_Id mutex_id,
|
||||||
|
boolean wait, /* XXX options */
|
||||||
|
Watchdog_Interval timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return POSIX_MP_NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void POSIX_Threads_mutex_MP_support(
|
||||||
|
Thread_Control *the_thread,
|
||||||
|
Objects_Id id
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(void) POSIX_MP_NOT_IMPLEMENTED(); /* XXX: should never get here */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* END OF TEMPORARY
|
||||||
|
*/
|
||||||
37
cpukit/posix/src/mutexsetprioceiling.c
Normal file
37
cpukit/posix/src/mutexsetprioceiling.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutexattr_setprioceiling(
|
||||||
|
pthread_mutexattr_t *attr,
|
||||||
|
int prioceiling
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !attr || !attr->is_initialized )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if ( !_POSIX_Priority_Is_valid( prioceiling ) )
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
attr->prio_ceiling = prioceiling;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
36
cpukit/posix/src/mutextimedlock.c
Normal file
36
cpukit/posix/src/mutextimedlock.c
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_timedlock(
|
||||||
|
pthread_mutex_t *mutex,
|
||||||
|
const struct timespec *timeout
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Mutex_Lock_support(
|
||||||
|
mutex,
|
||||||
|
TRUE,
|
||||||
|
_POSIX_Timespec_to_interval( timeout )
|
||||||
|
);
|
||||||
|
}
|
||||||
31
cpukit/posix/src/mutextrylock.c
Normal file
31
cpukit/posix/src/mutextrylock.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_trylock(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return _POSIX_Mutex_Lock_support( mutex, FALSE, THREAD_QUEUE_WAIT_FOREVER );
|
||||||
|
}
|
||||||
62
cpukit/posix/src/mutexunlock.c
Normal file
62
cpukit/posix/src/mutexunlock.c
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <rtems/system.h>
|
||||||
|
#include <rtems/score/coremutex.h>
|
||||||
|
#include <rtems/score/watchdog.h>
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
#include <rtems/score/mpci.h>
|
||||||
|
#endif
|
||||||
|
#include <rtems/posix/mutex.h>
|
||||||
|
#include <rtems/posix/priority.h>
|
||||||
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
|
||||||
|
*
|
||||||
|
* NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pthread_mutex_unlock(
|
||||||
|
pthread_mutex_t *mutex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register POSIX_Mutex_Control *the_mutex;
|
||||||
|
Objects_Locations location;
|
||||||
|
CORE_mutex_Status status;
|
||||||
|
|
||||||
|
the_mutex = _POSIX_Mutex_Get( mutex, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
return _POSIX_Mutex_MP_Send_request_packet(
|
||||||
|
POSIX_MUTEX_MP_RELEASE_REQUEST,
|
||||||
|
*mutex,
|
||||||
|
0, /* Not used */
|
||||||
|
MPCI_DEFAULT_TIMEOUT
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return EINVAL;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
status = _CORE_mutex_Surrender(
|
||||||
|
&the_mutex->Mutex,
|
||||||
|
the_mutex->Object.id,
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
POSIX_Threads_mutex_MP_support
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return _POSIX_Mutex_From_core_mutex_status( status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return POSIX_BOTTOM_REACHED();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user