summaryrefslogtreecommitdiffstats
path: root/c/src/exec/posix/src
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-09-26 19:27:15 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-09-26 19:27:15 +0000
commit5e9b32b439627068a0292370fe595220dbfc95a0 (patch)
tree3740b62de3aaa10140867de33adad9a1fcc15b26 /c/src/exec/posix/src
parentfixed Id strings (diff)
downloadrtems-5e9b32b439627068a0292370fe595220dbfc95a0.tar.bz2
posix support initially added
Diffstat (limited to 'c/src/exec/posix/src')
-rw-r--r--c/src/exec/posix/src/aio.c112
-rw-r--r--c/src/exec/posix/src/cancel.c226
-rw-r--r--c/src/exec/posix/src/cond.c398
-rw-r--r--c/src/exec/posix/src/devctl.c24
-rw-r--r--c/src/exec/posix/src/intr.c336
-rw-r--r--c/src/exec/posix/src/key.c259
-rw-r--r--c/src/exec/posix/src/mqueue.c713
-rw-r--r--c/src/exec/posix/src/mutex.c569
-rw-r--r--c/src/exec/posix/src/psignal.c261
-rw-r--r--c/src/exec/posix/src/pthread.c552
-rw-r--r--c/src/exec/posix/src/sched.c126
-rw-r--r--c/src/exec/posix/src/semaphore.c575
-rw-r--r--c/src/exec/posix/src/time.c192
-rw-r--r--c/src/exec/posix/src/types.c167
-rw-r--r--c/src/exec/posix/src/unistd.c20
-rw-r--r--c/src/exec/posix/src/utsname.c60
16 files changed, 4590 insertions, 0 deletions
diff --git a/c/src/exec/posix/src/aio.c b/c/src/exec/posix/src/aio.c
new file mode 100644
index 0000000000..dab31c108f
--- /dev/null
+++ b/c/src/exec/posix/src/aio.c
@@ -0,0 +1,112 @@
+/* aio.c
+ *
+ */
+
+#include <aio.h>
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 6.7.2 Asynchronous Read, P1003.1b-1993, p. 154
+ */
+
+int aio_read(
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.3 Asynchronous Write, P1003.1b-1993, p. 155
+ */
+
+int aio_write(
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.4 List Directed I/O, P1003.1b-1993, p. 158
+ */
+
+int lio_listio(
+ int mode,
+ struct aiocb * const list[],
+ int nent,
+ struct sigevent *sig
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.5 Retrieve Error of Asynchronous I/O Operation, P1003.1b-1993, p. 161
+ */
+
+int aio_error(
+ const struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.6 Retrieve Return Status of Asynchronous I/O Operation,
+ * P1003.1b-1993, p. 162
+ */
+
+int aio_return(
+ const struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.7 Cancel Asynchronous I/O Operation, P1003.1b-1993, p. 163
+ */
+
+int aio_cancel(
+ int filedes,
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.7 Wait for Asynchronous I/O Request, P1003.1b-1993, p. 164
+ */
+
+int aio_suspend(
+ struct aiocb * const list[],
+ int nent,
+ const struct timespec *timeout
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 6.7.9 Asynchronous File Synchronization, P1003.1b-1993, p. 166
+ */
+
+int aio_fsync(
+ int op,
+ struct aiocb *aiocbp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+#endif
diff --git a/c/src/exec/posix/src/cancel.c b/c/src/exec/posix/src/cancel.c
new file mode 100644
index 0000000000..32a9a90890
--- /dev/null
+++ b/c/src/exec/posix/src/cancel.c
@@ -0,0 +1,226 @@
+/* cancel.c
+ *
+ */
+
+#include <pthread.h>
+#include <errno.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/cancel.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/threadsup.h>
+
+/*PAGE
+ *
+ * POSIX_Thread_cancel_run
+ *
+ */
+
+void POSIX_Thread_cancel_run(
+ Thread_Control *the_thread
+)
+{
+ int old_cancel_state;
+ POSIX_Cancel_Handler_control *handler;
+ Chain_Control *handler_stack;
+ POSIX_API_Thread_Support_Control *thread_support;
+ ISR_Level level;
+
+ thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ handler_stack = &thread_support->Cancellation_Handlers;
+
+ old_cancel_state = thread_support->cancelability_state;
+
+ thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE;
+
+ while ( !_Chain_Is_empty( handler_stack ) ) {
+ _ISR_Disable( level );
+ handler = (POSIX_Cancel_Handler_control *) _Chain_Tail( handler_stack );
+ _Chain_Extract_unprotected( &handler->Node );
+ _ISR_Enable( level );
+
+ (*handler->routine)( handler->arg );
+
+ _Workspace_Free( handler );
+ }
+
+ thread_support->cancelation_requested = 0;
+
+ thread_support->cancelability_state = old_cancel_state;
+}
+
+/*PAGE
+ *
+ * 18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181
+ */
+
+int pthread_cancel(
+ pthread_t thread
+)
+{
+ Thread_Control *the_thread;
+ POSIX_API_Thread_Support_Control *thread_support;
+ Objects_Locations location;
+
+ the_thread = _POSIX_Threads_Get( &thread, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return POSIX_MP_NOT_IMPLEMENTED();
+ case OBJECTS_LOCAL:
+ thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+ thread_support->cancelation_requested = 1;
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
+ */
+
+int pthread_setcancelstate(
+ int state,
+ int *oldstate
+)
+{
+ POSIX_API_Thread_Support_Control *thread_support;
+
+ if ( !oldstate )
+ return EINVAL;
+
+ if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE )
+ return EINVAL;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ *oldstate = thread_support->cancelability_state;
+ thread_support->cancelability_state = state;
+
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
+ thread_support->cancelation_requested )
+ POSIX_Thread_cancel_run( _Thread_Executing );
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
+ */
+
+int pthread_setcanceltype(
+ int type,
+ int *oldtype
+)
+{
+ POSIX_API_Thread_Support_Control *thread_support;
+
+ if ( !oldtype )
+ return EINVAL;
+
+ if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS )
+ return EINVAL;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ *oldtype = thread_support->cancelability_type;
+ thread_support->cancelability_type = type;
+
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
+ thread_support->cancelation_requested )
+ POSIX_Thread_cancel_run( _Thread_Executing );
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
+ */
+
+void pthread_testcancel( void )
+{
+ POSIX_API_Thread_Support_Control *thread_support;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
+ thread_support->cancelation_requested )
+ POSIX_Thread_cancel_run( _Thread_Executing );
+}
+
+/*PAGE
+ *
+ * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184
+ */
+
+void pthread_cleanup_push(
+ void (*routine)( void * ),
+ void *arg
+)
+{
+ POSIX_Cancel_Handler_control *handler;
+ Chain_Control *handler_stack;
+ POSIX_API_Thread_Support_Control *thread_support;
+
+ if ( !routine )
+ return; /* XXX what to do really? */
+
+ handler = _Workspace_Allocate( sizeof( POSIX_Cancel_Handler_control ) );
+
+ if ( !handler )
+ return; /* XXX what to do really? */
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ handler_stack = &thread_support->Cancellation_Handlers;
+
+ handler->routine = routine;
+ handler->arg = arg;
+
+ _Chain_Append( handler_stack, &handler->Node );
+}
+
+/*PAGE
+ *
+ * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184
+ */
+
+void pthread_cleanup_pop(
+ int execute
+)
+{
+ POSIX_Cancel_Handler_control *handler;
+ Chain_Control *handler_stack;
+ POSIX_API_Thread_Support_Control *thread_support;
+ ISR_Level level;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ handler_stack = &thread_support->Cancellation_Handlers;
+
+ if ( _Chain_Is_empty( handler_stack ) )
+ return;
+
+ _ISR_Disable( level );
+ handler = (POSIX_Cancel_Handler_control *) _Chain_Tail( handler_stack );
+ _Chain_Extract_unprotected( &handler->Node );
+ _ISR_Enable( level );
+
+ if ( execute )
+ (*handler->routine)( handler->arg );
+
+ _Workspace_Free( handler );
+}
diff --git a/c/src/exec/posix/src/cond.c b/c/src/exec/posix/src/cond.c
new file mode 100644
index 0000000000..061353e858
--- /dev/null
+++ b/c/src/exec/posix/src/cond.c
@@ -0,0 +1,398 @@
+/* cond.c
+ *
+ */
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <rtems/score/object.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/cond.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * The default condition variable attributes structure.
+ */
+
+const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = {
+ TRUE, /* is_initialized */
+ PTHREAD_PROCESS_PRIVATE /* process_shared */
+};
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Manager_initialization
+ *
+ * This routine initializes all condition variable manager related data
+ * structures.
+ *
+ * Input parameters:
+ * maximum_condition_variables - maximum configured condition_variables
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Condition_variables_Manager_initialization(
+ unsigned32 maximum_condition_variables
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Condition_variables_Information,
+ OBJECTS_POSIX_CONDITION_VARIABLES,
+ TRUE,
+ maximum_condition_variables,
+ sizeof( POSIX_Condition_variables_Control ),
+ FALSE,
+ 0,
+ FALSE
+ );
+}
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_init(
+ pthread_condattr_t *attr
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *attr = _POSIX_Condition_variables_Default_attributes;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_destroy(
+ pthread_condattr_t *attr
+)
+{
+ if ( !attr || attr->is_initialized == FALSE )
+ return EINVAL;
+
+ attr->is_initialized = FALSE;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_getpshared(
+ const pthread_condattr_t *attr,
+ int *pshared
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *pshared = attr->process_shared;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 11.4.1 Condition Variable Initialization Attributes,
+ * P1003.1c/Draft 10, p. 96
+ */
+
+int pthread_condattr_setpshared(
+ pthread_condattr_t *attr,
+ int pshared
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ attr->process_shared = pshared;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 11.4.2 Initializing and Destroying a Condition Variable,
+ * P1003.1c/Draft 10, p. 87
+ */
+
+int pthread_cond_init(
+ pthread_cond_t *cond,
+ const pthread_condattr_t *attr
+)
+{
+ POSIX_Condition_variables_Control *the_cond;
+ const pthread_condattr_t *the_attr;
+
+ if ( attr ) the_attr = attr;
+ else the_attr = &_POSIX_Condition_variables_Default_attributes;
+
+ /*
+ * XXX: Be careful about attributes when global!!!
+ */
+
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ return POSIX_MP_NOT_IMPLEMENTED();
+
+ if ( !the_attr->is_initialized )
+ return EINVAL;
+
+ _Thread_Disable_dispatch();
+
+ the_cond = _POSIX_Condition_variables_Allocate();
+
+ if ( !the_cond ) {
+ _Thread_Enable_dispatch();
+ return ENOMEM;
+ }
+
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Condition_variables_Information,
+ 0, the_cond->Object.id, FALSE ) ) ) {
+ _POSIX_Condition_variables_Free( the_cond );
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+
+ the_cond->process_shared = the_attr->process_shared;
+
+ the_cond->Mutex = 0;
+
+/* XXX some more initialization might need to go here */
+ _Thread_queue_Initialize(
+ &the_cond->Wait_queue,
+ OBJECTS_POSIX_CONDITION_VARIABLES,
+ THREAD_QUEUE_DISCIPLINE_FIFO,
+ STATES_WAITING_FOR_CONDITION_VARIABLE,
+ _POSIX_Condition_variables_MP_Send_extract_proxy,
+ ETIMEDOUT
+ );
+
+ _Objects_Open(
+ &_POSIX_Condition_variables_Information,
+ &the_cond->Object,
+ 0
+ );
+
+ *cond = the_cond->Object.id;
+
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Condition_variables_MP_Send_process_packet(
+ POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE,
+ the_cond->Object.id,
+ 0, /* Name not used */
+ 0 /* Not used */
+ );
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 11.4.2 Initializing and Destroying a Condition Variable,
+ * P1003.1c/Draft 10, p. 87
+ */
+
+int pthread_cond_destroy(
+ pthread_cond_t *cond
+)
+{
+ register POSIX_Condition_variables_Control *the_cond;
+ Objects_Locations location;
+
+ the_cond = _POSIX_Condition_variables_Get( cond, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+ case OBJECTS_LOCAL:
+
+ _Objects_Close(
+ &_POSIX_Condition_variables_Information,
+ &the_cond->Object
+ );
+
+ if ( _Thread_queue_Get_number_waiting( &the_cond->Wait_queue ) )
+ return EBUSY;
+
+ _POSIX_Condition_variables_Free( the_cond );
+
+ if ( the_cond->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Condition_variables_Information,
+ the_cond->Object.id
+ );
+
+ _POSIX_Condition_variables_MP_Send_process_packet(
+ POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE,
+ the_cond->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Signal_support
+ *
+ * A support routine which implements guts of the broadcast and single task
+ * wake up version of the "signal" operation.
+ */
+
+int _POSIX_Condition_variables_Signal_support(
+ pthread_cond_t *cond,
+ boolean is_broadcast
+)
+{
+ register POSIX_Condition_variables_Control *the_cond;
+ Objects_Locations location;
+ Thread_Control *the_thread;
+
+ the_cond = _POSIX_Condition_variables_Get( cond, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+ case OBJECTS_LOCAL:
+
+ do {
+ the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue );
+ } while ( is_broadcast && the_thread );
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
+ */
+
+int pthread_cond_signal(
+ pthread_cond_t *cond
+)
+{
+ return _POSIX_Condition_variables_Signal_support( cond, FALSE );
+}
+
+/*PAGE
+ *
+ * 11.4.3 Broadcasting and Signaling a Condition, P1003.1c/Draft 10, p. 101
+ */
+
+int pthread_cond_broadcast(
+ pthread_cond_t *cond
+)
+{
+ return _POSIX_Condition_variables_Signal_support( cond, TRUE );
+}
+
+/*PAGE
+ *
+ * _POSIX_Condition_variables_Wait_support
+ *
+ * A support routine which implements guts of the blocking, non-blocking, and
+ * timed wait version of condition variable wait routines.
+ */
+
+int _POSIX_Condition_variables_Wait_support(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ Watchdog_Interval timeout
+)
+{
+ register POSIX_Condition_variables_Control *the_cond;
+ Objects_Locations location;
+ int status;
+
+ the_cond = _POSIX_Condition_variables_Get( cond, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ return EINVAL;
+ case OBJECTS_LOCAL:
+
+ /*
+ * XXX: should be an error if cond->Mutex != mutex
+ */
+
+ status = pthread_mutex_unlock( mutex );
+ if ( !status )
+ return status;
+
+ the_cond->Mutex = *mutex;
+
+ _Thread_queue_Enqueue( &the_cond->Wait_queue, 0 );
+
+ _Thread_Enable_dispatch();
+
+ status = pthread_mutex_lock( mutex );
+ if ( !status )
+ return status;
+
+ return _Thread_Executing->Wait.return_code;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
+ */
+
+int pthread_cond_wait(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex
+)
+{
+ return _POSIX_Condition_variables_Wait_support(
+ cond,
+ mutex,
+ THREAD_QUEUE_WAIT_FOREVER
+ );
+}
+
+/*PAGE
+ *
+ * 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
+ */
+
+int pthread_cond_timedwait(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime
+)
+{
+ return _POSIX_Condition_variables_Wait_support(
+ cond,
+ mutex,
+ _POSIX_Time_Spec_to_interval( abstime )
+ );
+}
diff --git a/c/src/exec/posix/src/devctl.c b/c/src/exec/posix/src/devctl.c
new file mode 100644
index 0000000000..e4ff6d3cd8
--- /dev/null
+++ b/c/src/exec/posix/src/devctl.c
@@ -0,0 +1,24 @@
+/* devctl.c
+ *
+ */
+
+#include <devctl.h>
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 21.2.1 Control a Device, P1003.4b/D8, p. 65
+ */
+
+int devctl(
+ int filedes,
+ void *dev_data_ptr,
+ size_t nbyte,
+ int *dev_info_ptr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
diff --git a/c/src/exec/posix/src/intr.c b/c/src/exec/posix/src/intr.c
new file mode 100644
index 0000000000..4011cf9a91
--- /dev/null
+++ b/c/src/exec/posix/src/intr.c
@@ -0,0 +1,336 @@
+/* intr.c
+ *
+ * NOTE: Each task has an interrupt semaphore associated with it.
+ * No matter which interrupt occurs that it has registered,
+ * the same semaphore is used.
+ */
+
+#include <errno.h>
+#include <intr.h>
+
+#include <pthread.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/intr.h>
+#include <rtems/posix/time.h>
+#include <rtems/posix/threadsup.h>
+
+/*
+ * _POSIX_Interrupt_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Interrupt_Manager_initialization(
+ unsigned32 maximum_interrupt_handlers
+)
+{
+ unsigned32 index;
+ POSIX_Interrupt_Control *the_vector;
+
+ _Objects_Initialize_information(
+ &_POSIX_Interrupt_Handlers_Information,
+ OBJECTS_POSIX_INTERRUPTS,
+ FALSE,
+ maximum_interrupt_handlers,
+ sizeof( POSIX_Interrupt_Handler_control ),
+ FALSE,
+ 0,
+ FALSE
+ );
+
+ for ( index=0 ; index < CPU_INTERRUPT_NUMBER_OF_VECTORS ; index++ ) {
+ the_vector = &_POSIX_Interrupt_Information[ index ];
+
+ the_vector->number_installed = 0;
+ the_vector->lock_count = 0;
+ the_vector->deferred_count = 0;
+ _Chain_Initialize_empty( &the_vector->Handlers );
+ }
+}
+
+/*PAGE
+ *
+ * 22.3.1 Associate a User-Written ISR with an Interrupt, P1003.4b/D8, p. 74
+ */
+
+int intr_capture(
+ intr_t intr,
+ int (*intr_handler)( void *area ),
+ volatile void *area,
+ size_t areasize
+)
+{
+ POSIX_Interrupt_Handler_control *the_intr;
+ POSIX_Interrupt_Control *the_vector;
+ POSIX_API_Thread_Support_Control *thread_support;
+ proc_ptr old_handler;
+
+ if ( !_ISR_Is_vector_number_valid( intr ) ||
+ !_ISR_Is_valid_user_handler( intr_handler ) )
+ return EINVAL;
+
+ _Thread_Disable_dispatch();
+
+ the_intr = _POSIX_Interrupt_Allocate();
+
+ if ( !the_intr ) {
+ _Thread_Enable_dispatch();
+ return ENOMEM;
+ }
+
+ the_vector = &_POSIX_Interrupt_Information[ intr ];
+
+ the_intr->vector = intr;
+ the_intr->handler = intr_handler;
+ the_intr->user_data_area = area;
+ the_intr->server = _Thread_Executing;
+ the_intr->is_active = TRUE;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+ thread_support->interrupts_installed++;
+
+/* XXX should we malloc the semaphore on the fly??? if so we probably need to
+ release it when the thread has released all interrupts and keep
+ a count of how many it has installed. CURRENTLY NO.. ALLOCATED w/TCB
+*/
+
+ /*
+ * This is sufficient to have the handlers invoked in the opposite
+ * order of installation. The loop invoking them can then go from
+ * the front of the list to the end.
+ */
+
+ _Chain_Prepend( &the_vector->Handlers, &the_intr->Object.Node );
+
+ if ( !the_vector->number_installed++ )
+ _ISR_Install_vector(
+ intr,
+ (proc_ptr) _POSIX_Interrupt_Handler,
+ &old_handler
+ );
+
+ _Objects_Open( &_POSIX_Interrupt_Handlers_Information, &the_intr->Object, 0 );
+
+ /*
+ * Normally, an Id would be returned here.
+ */
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 22.3.1 Associate a User-Written ISR with an Interrupt, P1003.4b/D8, p. 74
+ */
+
+int intr_release(
+ intr_t intr,
+ int (*intr_handler)( void *area )
+)
+{
+ boolean found;
+ POSIX_Interrupt_Handler_control *the_intr;
+ POSIX_Interrupt_Control *the_vector;
+ POSIX_API_Thread_Support_Control *thread_support;
+ Chain_Node *the_node;
+
+ if ( !_ISR_Is_valid_user_handler( intr_handler ) )
+ return EINVAL;
+
+ _Thread_Disable_dispatch();
+
+ /*
+ * Since interrupt handlers do not have a user visible id, there is
+ * no choice but to search the entire set of active interrupt handlers
+ * to find this one.
+ */
+
+ found = FALSE;
+
+ the_vector = &_POSIX_Interrupt_Information[ intr ];
+
+ the_node = _Chain_Head( &the_vector->Handlers );
+
+ for ( ; !_Chain_Is_tail( &the_vector->Handlers, the_node ) ; ) {
+ the_intr = (POSIX_Interrupt_Handler_control *) the_node;
+
+ if ( the_intr->handler == intr_handler ) {
+ found = TRUE;
+ break;
+ }
+ the_node = the_node->next;
+ }
+
+ if ( !found ) {
+ _Thread_Enable_dispatch();
+ return EINVAL;
+ }
+
+ if ( !_Thread_Is_executing( the_intr->server ) ) {
+ _Thread_Enable_dispatch();
+ return EINVAL; /* XXX should be ENOISR; */
+ }
+
+ /*
+ * OK now we have found the interrupt handler and can do some work.
+ */
+
+ _Chain_Extract( &the_intr->Object.Node );
+
+ the_intr->is_active = FALSE;
+
+ the_vector->number_installed -= 1;
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+ thread_support->interrupts_installed--;
+
+ /*
+ * It is unnecessary to flush the semaphore since the handler can only
+ * be "removed" by the thread which installed it. Thus it cannot be
+ * blocked on the semaphore or it would not be executing this routine.
+ */
+
+ _Objects_Close( &_POSIX_Interrupt_Handlers_Information, &the_intr->Object );
+
+ _POSIX_Interrupt_Free( the_intr );
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 22.3.1 Associate a User-Written ISR with an Interrupt, P1003.4b/D8, p. 74
+ */
+
+int intr_lock(
+ intr_t intr
+)
+{
+ POSIX_Interrupt_Control *the_vector;
+
+ _Thread_Disable_dispatch();
+
+ the_vector = &_POSIX_Interrupt_Information[ intr ];
+
+ the_vector->lock_count++;
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 22.3.1 Associate a User-Written ISR with an Interrupt, P1003.4b/D8, p. 74
+ */
+
+int intr_unlock(
+ intr_t intr
+)
+{
+ POSIX_Interrupt_Control *the_vector;
+
+ _Thread_Disable_dispatch();
+
+ the_vector = &_POSIX_Interrupt_Information[ intr ];
+
+ if ( !--the_vector->lock_count ) {
+ while ( --the_vector->deferred_count ) {
+ _POSIX_Interrupt_Handler( intr );
+ }
+ }
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+/*
+ * 22.3.2 Await Interrupt Notification, P1003.4b/D8, p. 76
+ */
+
+int intr_timed_wait(
+ int flags,
+ const struct timespec *timeout
+)
+{
+ Watchdog_Interval ticks;
+ POSIX_API_Thread_Support_Control *thread_support;
+
+ ticks = _POSIX_Time_Spec_to_interval( timeout );
+
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ _Thread_Disable_dispatch();
+
+ _CORE_semaphore_Seize(
+ &thread_support->Interrupt_Semaphore,
+ 0, /* XXX does id=0 hurt in this case? */
+ TRUE,
+ ticks
+ );
+ _Thread_Enable_dispatch();
+
+ return _Thread_Executing->Wait.return_code; /* XXX should be POSIX */
+}
+
+/*PAGE
+ *
+ * _POSIX_Interrupt_Handler
+ *
+ */
+
+void _POSIX_Interrupt_Handler(
+ ISR_Vector_number vector
+)
+{
+ POSIX_Interrupt_Handler_control *the_intr;
+ POSIX_Interrupt_Control *the_vector;
+ POSIX_API_Thread_Support_Control *thread_support;
+ Chain_Node *the_node;
+ int status;
+
+ the_vector = &_POSIX_Interrupt_Information[ vector ];
+
+ the_node = _Chain_Head( &the_vector->Handlers );
+
+ for ( ; !_Chain_Is_tail( &the_vector->Handlers, the_node ) ; ) {
+ the_intr = (POSIX_Interrupt_Handler_control *) the_node;
+
+ status = (*the_intr->handler)( (void *) the_intr->user_data_area );
+
+ switch ( status ) {
+ case INTR_HANDLED_NOTIFY:
+ thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
+
+ _CORE_semaphore_Surrender(
+ &thread_support->Interrupt_Semaphore,
+ 0, /* XXX is id=0 a problem */
+ 0 /* XXX is this a problem (mp support)*/
+ );
+ return;
+
+ case INTR_HANDLED_DO_NOT_NOTIFY:
+ return;
+
+ case INTR_NOT_HANDLED:
+ default: /* this should not happen */
+ break;
+ }
+ the_node = the_node->next;
+ }
+
+ /* XXX
+ *
+ * This is an unhandled interrupt!!!
+ */
+}
diff --git a/c/src/exec/posix/src/key.c b/c/src/exec/posix/src/key.c
new file mode 100644
index 0000000000..b92a976c55
--- /dev/null
+++ b/c/src/exec/posix/src/key.c
@@ -0,0 +1,259 @@
+/* key.c
+ *
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <string.h>
+
+#include <rtems/score/thread.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/posix/key.h>
+
+/*
+ * _POSIX_Key_Manager_initialization
+ *
+ * DESCRIPTION:
+ *
+ * This routine performs the initialization necessary for this manager.
+ */
+
+void _POSIX_Key_Manager_initialization(
+ unsigned32 maximum_keys
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Keys_Information,
+ OBJECTS_POSIX_KEYS,
+ FALSE,
+ maximum_keys,
+ sizeof( POSIX_Keys_Control ),
+ FALSE,
+ 0,
+ FALSE
+ );
+}
+
+/*PAGE
+ *
+ * 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
+ */
+
+int pthread_key_create(
+ pthread_key_t *key,
+ void (*destructor)( void * )
+)
+{
+ POSIX_Keys_Control *the_key;
+ void *table;
+ unsigned32 the_class;
+ unsigned32 bytes_to_allocate;
+
+
+ _Thread_Disable_dispatch();
+
+ the_key = _POSIX_Keys_Allocate();
+
+ if ( !the_key ) {
+ _Thread_Enable_dispatch();
+ return EAGAIN;
+ }
+
+ the_key->destructor = destructor;
+
+ for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
+ the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
+ the_class++ ) {
+
+ bytes_to_allocate =
+ (_Objects_Information_table[ the_class ]->maximum + 1) * sizeof( void * );
+
+ table = _Workspace_Allocate( bytes_to_allocate );
+
+ if ( !table ) {
+ for ( --the_class;
+ the_class >= OBJECTS_CLASSES_FIRST_THREAD_CLASS;
+ the_class-- )
+ _Workspace_Free( the_key->Values[ the_class ] );
+
+ _POSIX_Keys_Free( the_key );
+ _Thread_Enable_dispatch();
+ return ENOMEM;
+ }
+
+ the_key->Values[ the_class ] = table;
+ memset( table, '\0', bytes_to_allocate );
+ }
+
+ the_key->is_active = TRUE;
+
+ _Objects_Open( &_POSIX_Keys_Information, &the_key->Object, 0 );
+
+ *key = the_key->Object.id;
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+/*PAGE
+ *
+ * 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
+ */
+
+int pthread_setspecific(
+ pthread_key_t key,
+ const void *value
+)
+{
+ register POSIX_Keys_Control *the_key;
+ unsigned32 index;
+ unsigned32 class;
+ Objects_Locations location;
+
+ the_key = _POSIX_Keys_Get( key, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return EINVAL; /* should never happen */
+ case OBJECTS_LOCAL:
+ index = _Objects_Get_index( _Thread_Executing->Object.id );
+ class = _Objects_Get_class( _Thread_Executing->Object.id );
+ the_key->Values[ class ][ index ] = (void *) value;
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 17.1.2 Thread-Specific Data Management, P1003.1c/Draft 10, p. 165
+ */
+
+void *pthread_getspecific(
+ pthread_key_t key
+)
+{
+ register POSIX_Keys_Control *the_key;
+ unsigned32 index;
+ unsigned32 class;
+ Objects_Locations location;
+
+ the_key = _POSIX_Keys_Get( key, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return NULL;
+ case OBJECTS_REMOTE:
+ return 0; /* should never happen */
+ case OBJECTS_LOCAL:
+ index = _Objects_Get_index( _Thread_Executing->Object.id );
+ class = _Objects_Get_class( _Thread_Executing->Object.id );
+ return (void *) the_key->Values[ class ][ index ];
+ }
+ return (void *) POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167
+ */
+
+int pthread_key_delete(
+ pthread_key_t key
+)
+{
+ register POSIX_Keys_Control *the_key;
+ Objects_Locations location;
+ unsigned32 the_class;
+
+ the_key = _POSIX_Keys_Get( key, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return 0; /* should never happen */
+ case OBJECTS_LOCAL:
+ _Objects_Close( &_POSIX_Keys_Information, &the_key->Object );
+
+ the_key->is_active = FALSE;
+
+ for ( the_class = OBJECTS_CLASSES_FIRST_THREAD_CLASS;
+ the_class <= OBJECTS_CLASSES_LAST_THREAD_CLASS;
+ the_class++ )
+ _Workspace_Free( the_key->Values[ the_class ] );
+
+ /*
+ * NOTE: The destructor is not called and it is the responsibility
+ * of the application to free the memory.
+ */
+
+ _POSIX_Keys_Free( the_key );
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * _POSIX_Keys_Run_destructors
+ *
+ * 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
+ *
+ * NOTE: This is the routine executed when a thread exits to
+ * run through all the keys and do the destructor action.
+ *
+ * XXX: This needs to be hooked to the thread exitting -- SOMEHOW.
+ */
+
+void _POSIX_Keys_Run_destructors(
+ Thread_Control *thread
+)
+{
+ unsigned32 index;
+ unsigned32 pthread_index;
+ unsigned32 pthread_class;
+ unsigned32 iterations;
+ boolean are_all_null;
+ POSIX_Keys_Control *the_key;
+ void *value;
+
+ pthread_index = _Objects_Get_index( thread->Object.id );
+ pthread_class = _Objects_Get_class( thread->Object.id );
+
+ iterations = 0;
+
+ for ( ; ; ) {
+
+ are_all_null = TRUE;
+
+ for ( index=1 ; index <= _POSIX_Keys_Information.maximum ; index++ ) {
+
+ the_key = (POSIX_Keys_Control *)
+ _POSIX_Keys_Information.local_table[ index ];
+
+ if ( the_key && the_key->is_active && the_key->destructor ) {
+ value = the_key->Values[ pthread_class ][ pthread_index ];
+ if ( value ) {
+ (*the_key->destructor)( value );
+ if ( the_key->Values[ pthread_class ][ pthread_index ] )
+ are_all_null = FALSE;
+ }
+ }
+ }
+
+ if ( are_all_null == TRUE )
+ return;
+
+ iterations++;
+
+ /*
+ * The standard allows one to not do this and thus go into an infinite
+ * loop. It seems rude to unnecessarily lock up a system.
+ */
+
+ if ( iterations >= PTHREAD_DESTRUCTOR_ITERATIONS )
+ return;
+ }
+}
diff --git a/c/src/exec/posix/src/mqueue.c b/c/src/exec/posix/src/mqueue.c
new file mode 100644
index 0000000000..f531b94754
--- /dev/null
+++ b/c/src/exec/posix/src/mqueue.c
@@ -0,0 +1,713 @@
+/* mqueue.c
+ *
+ * NOTE: The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ */
+
+#include <stdarg.h>
+
+#include <pthread.h>
+#include <limits.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <mqueue.h>
+#include <rtems/system.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Manager_initialization
+ *
+ * This routine initializes all message_queue manager related data structures.
+ *
+ * Input parameters:
+ * maximum_message_queues - maximum configured message_queues
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Message_queue_Manager_initialization(
+ unsigned32 maximum_message_queues
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Message_queue_Information,
+ OBJECTS_POSIX_MESSAGE_QUEUES,
+ TRUE,
+ maximum_message_queues,
+ sizeof( POSIX_Message_queue_Control ),
+ TRUE,
+ _POSIX_PATH_MAX,
+ FALSE
+ );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Create_support
+ */
+
+int _POSIX_Message_queue_Create_support(
+ const char *name,
+ int pshared,
+ unsigned int oflag,
+ struct mq_attr *attr,
+ POSIX_Message_queue_Control **message_queue
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+
+ _Thread_Disable_dispatch();
+
+ the_mq = _POSIX_Message_queue_Allocate();
+
+ if ( !the_mq ) {
+ _Thread_Enable_dispatch();
+ seterrno( ENFILE );
+ return -1;
+ }
+
+ if ( pshared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Message_queue_Information, 0,
+ the_mq->Object.id, FALSE ) ) ) {
+ _POSIX_Message_queue_Free( the_mq );
+ _Thread_Enable_dispatch();
+ seterrno( ENFILE );
+ return -1;
+ }
+
+ the_mq->process_shared = pshared;
+
+ if ( name ) {
+ the_mq->named = TRUE;
+ the_mq->open_count = 1;
+ the_mq->linked = TRUE;
+ }
+ else
+ the_mq->named = FALSE;
+
+ if ( oflag & O_NONBLOCK )
+ the_mq->blocking = FALSE;
+ else
+ the_mq->blocking = TRUE;
+
+ /* XXX
+ *
+ * Note that this should be based on the current scheduling policy.
+ */
+
+ /* XXX
+ *
+ * Message and waiting disciplines are not distinguished.
+ */
+/*
+ the_mq_attr->message_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+ the_mq_attr->waiting_discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+ */
+
+ the_mq->Message_queue.Attributes.discipline =
+ CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
+
+ if ( ! _CORE_message_queue_Initialize(
+ &the_mq->Message_queue,
+ OBJECTS_POSIX_MESSAGE_QUEUES,
+ &the_mq->Message_queue.Attributes,
+ attr->mq_maxmsg,
+ attr->mq_msgsize,
+ _POSIX_Message_queue_MP_Send_extract_proxy ) ) {
+
+ if ( pshared == PTHREAD_PROCESS_SHARED )
+ _Objects_MP_Close( &_POSIX_Message_queue_Information, the_mq->Object.id );
+
+ _POSIX_Message_queue_Free( the_mq );
+ _Thread_Enable_dispatch();
+ seterrno( ENOSPC );
+ return -1;
+ }
+
+
+ /* XXX - need Names to be a string!!! */
+ _Objects_Open(
+ &_POSIX_Message_queue_Information,
+ &the_mq->Object,
+ (char *) name
+ );
+
+ *message_queue = the_mq;
+
+ if ( pshared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Message_queue_MP_Send_process_packet(
+ POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE,
+ the_mq->Object.id,
+ (char *) name,
+ 0 /* Not used */
+ );
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
+
+/*PAGE
+ *
+ * 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
+ */
+
+mqd_t mq_open(
+ const char *name,
+ int oflag,
+ ...
+ /* mode_t mode, */
+ /* struct mq_attr attr */
+)
+{
+ va_list arg;
+ mode_t mode;
+ struct mq_attr *attr;
+ int status;
+ Objects_Id the_mq_id;
+ POSIX_Message_queue_Control *the_mq;
+
+ if ( oflag & O_CREAT ) {
+ va_start(arg, oflag);
+ mode = (mode_t) va_arg( arg, mode_t * );
+ attr = (struct mq_attr *) va_arg( arg, struct mq_attr ** );
+ va_end(arg);
+ }
+
+ status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
+
+ /*
+ * If the name to id translation worked, then the message queue exists
+ * and we can just return a pointer to the id. Otherwise we may
+ * need to check to see if this is a "message queue does not exist"
+ * or some other miscellaneous error on the name.
+ */
+
+ if ( status ) {
+
+ if ( status == EINVAL ) { /* name -> ID translation failed */
+ if ( !(oflag & O_CREAT) ) { /* willing to create it? */
+ seterrno( ENOENT );
+ return (mqd_t) -1;
+ }
+ /* we are willing to create it */
+ }
+ seterrno( status ); /* some type of error */
+ return (mqd_t) -1;
+
+ } else { /* name -> ID translation succeeded */
+
+ if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
+ seterrno( EEXIST );
+ return (mqd_t) -1;
+ }
+
+ /*
+ * XXX In this case we need to do an ID->pointer conversion to
+ * check the mode. This is probably a good place for a subroutine.
+ */
+
+ the_mq->open_count += 1;
+
+ return (mqd_t)&the_mq->Object.id;
+
+ }
+
+ /* XXX verify this comment...
+ *
+ * At this point, the message queue does not exist and everything has been
+ * checked. We should go ahead and create a message queue.
+ */
+
+ status = _POSIX_Message_queue_Create_support(
+ name,
+ TRUE, /* shared across processes */
+ oflag,
+ attr,
+ &the_mq
+ );
+
+ if ( status == -1 )
+ return (mqd_t) -1;
+
+ return (mqd_t) &the_mq->Object.id;
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Delete
+ */
+
+void _POSIX_Message_queue_Delete(
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ if ( !the_mq->linked && !the_mq->open_count ) {
+ _POSIX_Message_queue_Free( the_mq );
+
+ if ( the_mq->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Message_queue_Information,
+ the_mq->Object.id
+ );
+
+ _POSIX_Message_queue_MP_Send_process_packet(
+ POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE,
+ the_mq->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+
+ }
+}
+
+/*PAGE
+ *
+ * 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
+ */
+
+int mq_close(
+ mqd_t mqdes
+)
+{
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Locations location;
+
+ the_mq = _POSIX_Message_queue_Get( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ the_mq->open_count -= 1;
+ _POSIX_Message_queue_Delete( the_mq );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
+ */
+
+int mq_unlink(
+ const char *name
+)
+{
+ int status;
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Id the_mq_id;
+ Objects_Locations location;
+
+ status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id );
+
+ if ( !status ) {
+ seterrno( status );
+ return -1;
+ }
+
+ the_mq = _POSIX_Message_queue_Get( the_mq_id, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+
+ _Objects_MP_Close(
+ &_POSIX_Message_queue_Information,
+ the_mq->Object.id
+ );
+
+ the_mq->linked = FALSE;
+
+ _POSIX_Message_queue_Delete( the_mq );
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Send_support
+ */
+
+int _POSIX_Message_queue_Send_support(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ unsigned32 msg_len,
+ Priority_Control msg_prio,
+ Watchdog_Interval timeout
+)
+{
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Locations location;
+
+ the_mq = _POSIX_Message_queue_Get( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ /* XXX must add support for timeout and priority */
+ _CORE_message_queue_Send(
+ &the_mq->Message_queue,
+ (void *) msg_ptr,
+ msg_len,
+ mqdes,
+ NULL /* XXX _POSIX_Message_queue_Core_message_queue_mp_support*/
+ );
+ _Thread_Enable_dispatch();
+ return _Thread_Executing->Wait.return_code;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
+ */
+
+int mq_send(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio
+)
+{
+ return _POSIX_Message_queue_Send_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ THREAD_QUEUE_WAIT_FOREVER
+ );
+}
+
+/*PAGE
+ *
+ * 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
+ */
+
+int mq_timedsend(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *timeout
+)
+{
+ return _POSIX_Message_queue_Send_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ _POSIX_Time_Spec_to_interval( timeout )
+ );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Receive_support
+ */
+
+/* XXX be careful ... watch the size going through all the layers ... */
+
+ssize_t _POSIX_Message_queue_Receive_support(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ Watchdog_Interval timeout
+)
+{
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Locations location;
+ unsigned32 status = 0;
+ unsigned32 length_out;
+
+ the_mq = _POSIX_Message_queue_Get( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ /* XXX need to define the options argument to this */
+ length_out = msg_len;
+ _CORE_message_queue_Seize(
+ &the_mq->Message_queue,
+ mqdes,
+ msg_ptr,
+ &length_out,
+ /* msg_prio, XXXX */
+ the_mq->blocking,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ if ( !status )
+ return length_out;
+ /* XXX --- the return codes gotta be looked at .. fix this */
+ return _Thread_Executing->Wait.return_code;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
+ */
+
+ssize_t mq_receive(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio
+)
+{
+ return _POSIX_Message_queue_Receive_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ THREAD_QUEUE_WAIT_FOREVER
+ );
+}
+
+/*PAGE
+ *
+ * 15.2.5 Receive a Message From a Message Queue, P1003.1b-1993, p. 279
+ *
+ * NOTE: P1003.4b/D8, p. 45 adds mq_timedreceive().
+ */
+
+int mq_timedreceive( /* XXX: should this be ssize_t */
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ const struct timespec *timeout
+)
+{
+ return _POSIX_Message_queue_Receive_support(
+ mqdes,
+ msg_ptr,
+ msg_len,
+ msg_prio,
+ _POSIX_Time_Spec_to_interval( timeout )
+ );
+}
+
+/*PAGE
+ *
+ * _POSIX_Message_queue_Notify_handler
+ *
+ */
+
+void _POSIX_Message_queue_Notify_handler(
+ void *user_data
+)
+{
+ POSIX_Message_queue_Control *the_mq;
+
+ the_mq = user_data;
+
+ /* XXX do something with signals here!!!! */
+}
+
+/*PAGE
+ *
+ * 15.2.6 Notify Process that a Message is Available on a Queue,
+ * P1003.1b-1993, p. 280
+ */
+
+int mq_notify(
+ mqd_t mqdes,
+ const struct sigevent *notification
+)
+{
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Locations location;
+
+ the_mq = _POSIX_Message_queue_Get( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EBADF );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ if ( notification ) {
+ if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) {
+ _Thread_Enable_dispatch();
+ seterrno( EBUSY );
+ return( -1 );
+ }
+
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+
+ the_mq->notification = *notification;
+
+ _CORE_message_queue_Set_notify(
+ &the_mq->Message_queue,
+ _POSIX_Message_queue_Notify_handler,
+ the_mq
+ );
+ } else {
+
+ _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL );
+
+ }
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 15.2.7 Set Message Queue Attributes, P1003.1b-1993, p. 281
+ */
+
+int mq_setattr(
+ mqd_t mqdes,
+ const struct mq_attr *mqstat,
+ struct mq_attr *omqstat
+)
+{
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Locations location;
+ CORE_message_queue_Attributes *the_mq_attr;
+
+ the_mq = _POSIX_Message_queue_Get( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ /*
+ * Return the old values.
+ */
+
+ /* XXX this is the same stuff as is in mq_getattr... and probably */
+ /* XXX should be in an inlined private routine */
+
+ the_mq_attr = &the_mq->Message_queue.Attributes;
+
+ omqstat->mq_flags = the_mq->flags;
+ omqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
+ omqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
+ omqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
+
+ /*
+ * Ignore everything except the O_NONBLOCK bit.
+ */
+
+ if ( mqstat->mq_flags & O_NONBLOCK )
+ the_mq->blocking = FALSE;
+ else
+ the_mq->blocking = TRUE;
+
+ the_mq->flags = mqstat->mq_flags;
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283
+ */
+
+int mq_getattr(
+ mqd_t mqdes,
+ struct mq_attr *mqstat
+)
+{
+ register POSIX_Message_queue_Control *the_mq;
+ Objects_Locations location;
+ CORE_message_queue_Attributes *the_mq_attr;
+
+ the_mq = _POSIX_Message_queue_Get( mqdes, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ /*
+ * Return the old values.
+ */
+
+ /* XXX this is the same stuff as is in mq_setattr... and probably */
+ /* XXX should be in an inlined private routine */
+
+ the_mq_attr = &the_mq->Message_queue.Attributes;
+
+ mqstat->mq_flags = the_mq->flags;
+ mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size;
+ mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages;
+ mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages;
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/c/src/exec/posix/src/mutex.c b/c/src/exec/posix/src/mutex.c
new file mode 100644
index 0000000000..5473d4183c
--- /dev/null
+++ b/c/src/exec/posix/src/mutex.c
@@ -0,0 +1,569 @@
+/* mutex.c
+ *
+ */
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/score/system.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/mpci.h>
+
+#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_MINIMUM_PRIORITY, /* prio_ceiling */
+ PTHREAD_PRIO_NONE, /* protocol */
+ FALSE /* recursive */
+};
+
+/*PAGE
+ *
+ * _POSIX_Mutex_Manager_initialization
+ *
+ * This routine initializes all mutex manager related data structures.
+ *
+ * Input parameters:
+ * maximum_mutexes - maximum configured mutexes
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Mutex_Manager_initialization(
+ unsigned32 maximum_mutexes
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Mutex_Information,
+ OBJECTS_POSIX_MUTEXES,
+ TRUE,
+ maximum_mutexes,
+ sizeof( POSIX_Mutex_Control ),
+ FALSE,
+ 0,
+ 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 == FALSE )
+ 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 )
+ 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 )
+ return EINVAL;
+
+ attr->process_shared = pshared;
+ return 0;
+}
+
+/*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 ( attr ) the_attr = attr;
+ else the_attr = &_POSIX_Mutex_Default_attributes;
+
+ /*
+ * XXX: Be careful about attributes when global!!!
+ */
+
+ if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
+ return POSIX_MP_NOT_IMPLEMENTED();
+
+ if ( !the_attr->is_initialized )
+ return EINVAL;
+
+ /*
+ * 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 ENOMEM;
+ }
+
+ 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;
+ }
+
+ 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,
+ 0 /* XXX proxy_extract_callout */
+ );
+
+ _Objects_Open( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
+
+ *mutex = the_mutex->Object.id;
+
+ 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 */
+ );
+
+ _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_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ 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,
+ _POSIX_Mutex_MP_Send_object_was_deleted,
+ EINVAL
+ );
+
+ _POSIX_Mutex_Free( the_mutex );
+
+ 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 */
+ );
+ }
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*
+ * _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_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return _POSIX_Mutex_MP_Send_request_packet(
+ POSIX_MUTEX_MP_OBTAIN_REQUEST,
+ *mutex,
+ 0, /* must define the option set */
+ WATCHDOG_NO_TIMEOUT
+ );
+ case OBJECTS_LOCAL:
+ _CORE_mutex_Seize(
+ &the_mutex->Mutex,
+ the_mutex->Object.id,
+ blocking,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ return _Thread_Executing->Wait.return_code;
+ 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_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
+ */
+
+void POSIX_Threads_mutex_MP_support(
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED(); /* XXX: should never get here */
+}
+
+int pthread_mutex_unlock(
+ pthread_mutex_t *mutex
+)
+{
+ register POSIX_Mutex_Control *the_mutex;
+ Objects_Locations location;
+
+ the_mutex = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return _POSIX_Mutex_MP_Send_request_packet(
+ POSIX_MUTEX_MP_RELEASE_REQUEST,
+ *mutex,
+ 0, /* Not used */
+ MPCI_DEFAULT_TIMEOUT
+ );
+ case OBJECTS_LOCAL:
+ _CORE_mutex_Surrender(
+ &the_mutex->Mutex,
+ the_mutex->Object.id,
+ POSIX_Threads_mutex_MP_support
+ );
+ _Thread_Enable_dispatch();
+ return _Thread_Executing->Wait.return_code; /* XXX return 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_Time_Spec_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 )
+ return EINVAL;
+
+ attr->protocol = protocol;
+ return 0;
+}
+
+/*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 )
+ 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 )
+ return EINVAL;
+
+ if ( !_POSIX_Priority_Is_valid( attr->prio_ceiling ) )
+ 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 )
+ 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 ( !_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_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return POSIX_MP_NOT_IMPLEMENTED(); /* XXX feels questionable */
+ return EINVAL;
+ case OBJECTS_LOCAL:
+ the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
+ _CORE_mutex_Surrender(
+ &the_mutex->Mutex,
+ the_mutex->Object.id,
+ POSIX_Threads_mutex_MP_support
+ );
+ _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;
+
+ the_mutex = _POSIX_Mutex_Get( mutex, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ return EINVAL;
+ case OBJECTS_REMOTE:
+ return POSIX_MP_NOT_IMPLEMENTED(); /* XXX feels questionable */
+ case OBJECTS_LOCAL:
+ *prioceiling = _POSIX_Priority_From_core(
+ the_mutex->Mutex.Attributes.priority_ceiling
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/c/src/exec/posix/src/psignal.c b/c/src/exec/posix/src/psignal.c
new file mode 100644
index 0000000000..48701c3880
--- /dev/null
+++ b/c/src/exec/posix/src/psignal.c
@@ -0,0 +1,261 @@
+/* signal.c
+ *
+ */
+
+#include <signal.h>
+
+#include <rtems/score/thread.h>
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*
+ * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
+ *
+ * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS.
+ */
+
+int kill(
+ int pid_t,
+ int sig
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ */
+
+int sigemptyset(
+ sigset_t *set
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ */
+
+int sigfillset(
+ sigset_t *set
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ */
+
+int sigaddset(
+ sigset_t *set,
+ int signo
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ */
+
+int sigdelset(
+ sigset_t *set,
+ int signo
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69
+ */
+
+int sigismembet(
+ const sigset_t *set,
+ int signo
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70
+ */
+
+int sigaction(
+ int sig,
+ const struct sigaction *act,
+ struct sigaction *oact
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
+ *
+ * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
+ */
+
+int sigprocmask(
+ int how,
+ const sigset_t *set,
+ sigset_t *oset
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73
+ *
+ * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask().
+ */
+
+int pthread_sigmask(
+ int how,
+ const sigset_t *set,
+ sigset_t *oset
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75
+ */
+
+int sigpending(
+ sigset_t *set
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.7 Wait for a Signal, P1003.1b-1993, p. 75
+ */
+
+int sigsuspend(
+ const sigset_t *sigmask
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ *
+ * NOTE: P1003.1c/D10, p. 39 adds sigwait().
+ */
+
+int sigwaitinfo(
+ const sigset_t *set,
+ siginfo_t *info
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ *
+ * NOTE: P1003.1c/D10, p. 39 adds sigwait().
+ */
+
+int sigtimedwait(
+ const sigset_t *set,
+ siginfo_t *info,
+ const struct timespec *timeout
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76
+ *
+ * NOTE: P1003.1c/D10, p. 39 adds sigwait().
+ */
+
+int sigwait(
+ const sigset_t *set,
+ int *sig
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78
+ */
+
+int sigqueue(
+ pid_t pid,
+ int signo,
+ const union sigval value
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43
+ */
+
+int pthread_kill(
+ pthread_t thread,
+ int sig
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79
+ */
+
+unsigned int alarm(
+ unsigned int seconds
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 80
+ */
+
+int pause( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
+
+/*
+ * 3.4.3 Delay Process Execution, P1003.1b-1993, p. 73
+ */
+
+unsigned int sleep(
+ unsigned int seconds
+)
+{
+ _Thread_Disable_dispatch();
+ _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
+ _Watchdog_Initialize(
+ &_Thread_Executing->Timer,
+ _Thread_Delay_ended, /* XXX may need to be POSIX specific */
+ _Thread_Executing->Object.id,
+ NULL
+ );
+ _Watchdog_Insert_seconds(
+ &_Thread_Executing->Timer,
+ seconds,
+ WATCHDOG_ACTIVATE_NOW
+ );
+ _Thread_Enable_dispatch();
+ return 0; /* XXX should account for signal */
+}
diff --git a/c/src/exec/posix/src/pthread.c b/c/src/exec/posix/src/pthread.c
new file mode 100644
index 0000000000..ee1903c3ff
--- /dev/null
+++ b/c/src/exec/posix/src/pthread.c
@@ -0,0 +1,552 @@
+/* pthread.c
+ *
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <limits.h>
+
+#include <rtems/score/stack.h>
+#include <rtems/score/thread.h>
+#include <rtems/posix/pthread.h>
+
+/*PAGE
+ *
+ * The default pthreads attributes structure.
+ */
+
+const pthread_attr_t _POSIX_Threads_Default_attributes = {
+ TRUE, /* is_initialized */
+ 0, /* stackaddr */
+ STACK_MINIMUM_SIZE, /* stacksize */
+ PTHREAD_SCOPE_PROCESS, /* contentionscope */
+ PTHREAD_INHERIT_SCHED, /* inheritsched */
+ SCHED_FIFO, /* schedpolicy */
+ { /* schedparam */
+ 128, /* sched_priority */
+ 0, /* ss_low_priority */
+ { 0L, 0 }, /* ss_replenish_period */
+ { 0L, 0 } /* ss_initial_budget */
+ },
+ PTHREAD_CREATE_DETACHED, /* detachstate */
+ 1 /* cputime_clock_allowed */
+};
+
+/*PAGE
+ *
+ * _POSIX_Threads_Manager_initialization
+ *
+ * This routine initializes all threads manager related data structures.
+ *
+ * Input parameters:
+ * maximum_pthreads - maximum configured pthreads
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Threads_Manager_initialization(
+ unsigned32 maximum_pthreads
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Threads_Information,
+ OBJECTS_POSIX_THREADS,
+ TRUE,
+ maximum_pthreads,
+ sizeof( POSIX_Threads_Control ),
+ TRUE,
+ _POSIX_PATH_MAX,
+ TRUE
+ );
+}
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27
+ */
+
+int pthread_atfork(
+ void (*prepare)(void),
+ void (*parent)(void),
+ void (*child)(void)
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_setscope(
+ pthread_attr_t *attr,
+ int contentionscope
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->contentionscope = contentionscope;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_getscope(
+ const pthread_attr_t *attr,
+ int *contentionscope
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *contentionscope = attr->contentionscope;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_setinheritsched(
+ pthread_attr_t *attr,
+ int inheritsched
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->inheritsched = inheritsched;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_getinheritsched(
+ const pthread_attr_t *attr,
+ int *inheritsched
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *inheritsched = attr->inheritsched;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_setschedpolicy(
+ pthread_attr_t *attr,
+ int policy
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->schedpolicy = policy;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_getschedpolicy(
+ const pthread_attr_t *attr,
+ int *policy
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *policy = attr->schedpolicy;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_setschedparam(
+ pthread_attr_t *attr,
+ const struct sched_param param
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->schedparam = param;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120
+ */
+
+int pthread_attr_getschedparam(
+ const pthread_attr_t *attr,
+ struct sched_param *param
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *param = attr->schedparam;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.2 Dynamic Thread Scheduling Parameters Access,
+ * P1003.1c/Draft 10, p. 124
+ */
+
+int pthread_getschedparam(
+ pthread_t thread,
+ int *policy,
+ struct sched_param *param
+)
+{
+ pthread_attr_t *attr; /* XXX: really need to get this from the thread */
+
+ if ( !policy || !param )
+ return EINVAL;
+
+ *policy = attr->schedpolicy;
+ *param = attr->schedparam;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.5.2 Dynamic Thread Scheduling Parameters Access,
+ * P1003.1c/Draft 10, p. 124
+ */
+
+int pthread_setschedparam(
+ pthread_t thread,
+ int policy,
+ struct sched_param *param
+)
+{
+ /* XXX need to reschedule after doing this to the thread */
+ pthread_attr_t *attr; /* XXX: really need to get this from the thread */
+
+ if ( !param )
+ return EINVAL;
+
+ attr->schedpolicy = policy;
+ attr->schedparam = *param;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_init(
+ pthread_attr_t *attr
+)
+{
+ if ( !attr )
+ return EINVAL;
+
+ *attr = _POSIX_Threads_Default_attributes;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_destroy(
+ pthread_attr_t *attr
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->is_initialized = FALSE;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_getstacksize(
+ const pthread_attr_t *attr,
+ size_t *stacksize
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *stacksize = attr->stacksize;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_setstacksize(
+ pthread_attr_t *attr,
+ size_t stacksize
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->stacksize = stacksize;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_getstackaddr(
+ const pthread_attr_t *attr,
+ void **stackaddr
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *stackaddr = attr->stackaddr;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_setstackaddr(
+ pthread_attr_t *attr,
+ void *stackaddr
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->stackaddr = stackaddr;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_getdetachstate(
+ const pthread_attr_t *attr,
+ int *detachstate
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *detachstate = attr->detachstate;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140
+ */
+
+int pthread_attr_setdetachstate(
+ pthread_attr_t *attr,
+ int detachstate
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->detachstate = detachstate;
+ return 0;
+}
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144
+ */
+
+int pthread_create(
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void (*start_routine)( void * ),
+ void *arg
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147
+ */
+
+int pthread_join(
+ pthread_t thread,
+ void **value_ptr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149
+ */
+
+int pthread_detach(
+ pthread_t thread
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
+
+/*PAGE
+ *
+ * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. XXX
+ */
+
+pthread_t pthread_self( void )
+{
+ return _Thread_Executing->Object.id;
+}
+
+/*PAGE
+ *
+ * 16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153
+ */
+
+int pthread_equal(
+ pthread_t t1,
+ pthread_t t2
+)
+{
+#ifdef RTEMS_DEBUG
+ /* XXX may want to do a "get" to make sure both are valid. */
+ /* XXX behavior is undefined if not valid pthread_t's */
+#endif
+ return _Objects_Are_ids_equal( t1, t1 );
+}
+
+/*PAGE
+ *
+ * 16.1.8 Dynamic Package Initialization
+ */
+
+int pthread_once(
+ pthread_once_t *once_control,
+ void (*init_routine)(void)
+)
+{
+ /* XXX: Should we implement this routine this way or make it a full */
+ /* XXX: fledged object? */
+
+ if ( !once_control || !init_routine )
+ return EINVAL;
+
+ _Thread_Disable_dispatch();
+
+ if ( !once_control->is_initialized ) {
+
+ once_control->is_initialized = TRUE;
+ once_control->init_executed = TRUE;
+ (*init_routine)();
+
+ } if ( !once_control->init_executed ) {
+
+ once_control->init_executed = TRUE;
+ (*init_routine)();
+
+ }
+
+ _Thread_Enable_dispatch();
+
+ return 0;
+}
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/D8, p. 58
+ */
+
+int pthread_getcpuclockid(
+ pthread_t pid,
+ clockid_t *clock_id
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
+
+/*PAGE
+ *
+ * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59
+ */
+
+int pthread_attr_setcputime(
+ pthread_attr_t *attr,
+ int clock_allowed
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ attr->cputime_clock_allowed = clock_allowed;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/D8, p. 59
+ */
+
+int pthread_attr_getcputime(
+ pthread_attr_t *attr,
+ int *clock_allowed
+)
+{
+ if ( !attr || !attr->is_initialized )
+ return EINVAL;
+
+ *clock_allowed = attr->cputime_clock_allowed;
+ return 0;
+}
diff --git a/c/src/exec/posix/src/sched.c b/c/src/exec/posix/src/sched.c
new file mode 100644
index 0000000000..230fe5dbbb
--- /dev/null
+++ b/c/src/exec/posix/src/sched.c
@@ -0,0 +1,126 @@
+/* sched.c
+ *
+ */
+
+#include <sched.h>
+#include <rtems/score/tod.h>
+#include <rtems/score/thread.h>
+#include <rtems/posix/priority.h>
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 13.3.1 Set Scheduling Parameters, P1003.1b-1993, p. 252
+ *
+ */
+
+int sched_setparam(
+ pid_t pid,
+ const struct sched_param *param
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 13.3.2 Set Scheduling Parameters, P1003.1b-1993, p. 253
+ */
+
+int sched_getparam(
+ pid_t pid,
+ const struct sched_param *param
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 13.3.3 Set Scheduling Policy and Scheduling Parameters,
+ * P1003.1b-1993, p. 254
+ */
+
+int sched_setscheduler(
+ pid_t pid,
+ int policy,
+ const struct sched_param *param
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 13.3.4 Get Scheduling Policy, P1003.1b-1993, p. 256
+ */
+
+int sched_getscheduler(
+ pid_t pid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
+
+/*PAGE
+ *
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_get_priority_max(
+ int policy
+)
+{
+ /* XXX error check the policy */
+ return POSIX_SCHEDULER_MAXIMUM_PRIORITY;
+}
+
+/*PAGE
+ *
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_get_priority_min(
+ int policy
+)
+{
+ /* XXX error check the policy */
+ return POSIX_SCHEDULER_MINIMUM_PRIORITY;
+}
+
+/*PAGE
+ *
+ * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258
+ */
+
+int sched_rr_get_interval(
+ pid_t pid,
+ struct timespec *interval
+)
+{
+ time_t us_per_quantum;
+
+ /* XXX eventually should support different time quantums per thread */
+
+ /* XXX should get for errors? (bad pid) */
+
+ us_per_quantum = _TOD_Microseconds_per_tick * _Thread_Ticks_per_timeslice;
+
+ interval->tv_sec = us_per_quantum / TOD_MICROSECONDS_PER_SECOND;
+ interval->tv_nsec = (us_per_quantum % TOD_MICROSECONDS_PER_SECOND) * 1000;
+ return 0;
+}
+
+/*PAGE
+ *
+ * 13.3.5 Yield Processor, P1003.1b-1993, p. 257
+ */
+
+int sched_yield( void )
+{
+ _Thread_Yield_processor();
+ return 0;
+}
diff --git a/c/src/exec/posix/src/semaphore.c b/c/src/exec/posix/src/semaphore.c
new file mode 100644
index 0000000000..16d44d1894
--- /dev/null
+++ b/c/src/exec/posix/src/semaphore.c
@@ -0,0 +1,575 @@
+/* semaphore.c
+ *
+ */
+
+#include <stdarg.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <limits.h>
+
+#include <rtems/system.h>
+#include <rtems/score/object.h>
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/time.h>
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Manager_initialization
+ *
+ * This routine initializes all semaphore manager related data structures.
+ *
+ * Input parameters:
+ * maximum_semaphores - maximum configured semaphores
+ *
+ * Output parameters: NONE
+ */
+
+void _POSIX_Semaphore_Manager_initialization(
+ unsigned32 maximum_semaphores
+)
+{
+ _Objects_Initialize_information(
+ &_POSIX_Semaphore_Information,
+ OBJECTS_POSIX_SEMAPHORES,
+ TRUE,
+ maximum_semaphores,
+ sizeof( POSIX_Semaphore_Control ),
+ TRUE,
+ _POSIX_PATH_MAX,
+ FALSE
+ );
+}
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Create_support
+ */
+
+int _POSIX_Semaphore_Create_support(
+ const char *name,
+ int pshared,
+ unsigned int value,
+ POSIX_Semaphore_Control **the_sem
+)
+{
+ POSIX_Semaphore_Control *the_semaphore;
+ CORE_semaphore_Attributes *the_sem_attr;
+
+ _Thread_Disable_dispatch();
+
+ the_semaphore = _POSIX_Semaphore_Allocate();
+
+ if ( !the_semaphore ) {
+ _Thread_Enable_dispatch();
+ seterrno( ENOMEM );
+ return -1;
+ }
+
+ if ( pshared == PTHREAD_PROCESS_SHARED &&
+ !( _Objects_MP_Allocate_and_open( &_POSIX_Semaphore_Information, 0,
+ the_semaphore->Object.id, FALSE ) ) ) {
+ _POSIX_Semaphore_Free( the_semaphore );
+ _Thread_Enable_dispatch();
+ seterrno( EAGAIN );
+ return -1;
+ }
+
+ the_semaphore->process_shared = pshared;
+
+ if ( name ) {
+ the_semaphore->named = TRUE;
+ the_semaphore->open_count = 1;
+ the_semaphore->linked = TRUE;
+ }
+ else
+ the_semaphore->named = FALSE;
+
+ the_sem_attr = &the_semaphore->Semaphore.Attributes;
+
+ /* XXX
+ *
+ * Note should this be based on the current scheduling policy?
+ */
+
+ the_sem_attr->discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
+
+ _CORE_semaphore_Initialize(
+ &the_semaphore->Semaphore,
+ OBJECTS_POSIX_SEMAPHORES,
+ the_sem_attr,
+ value,
+ 0 /* XXX - proxy_extract_callout is unused */
+ );
+
+ /* XXX - need Names to be a string!!! */
+ _Objects_Open(
+ &_POSIX_Semaphore_Information,
+ &the_semaphore->Object,
+ (char *) name
+ );
+
+ *the_sem = the_semaphore;
+
+ if ( pshared == PTHREAD_PROCESS_SHARED )
+ _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_SEMAPHORE_MP_ANNOUNCE_CREATE,
+ the_semaphore->Object.id,
+ (char *) name,
+ 0 /* proxy id - Not used */
+ );
+
+ _Thread_Enable_dispatch();
+ return 0;
+}
+
+
+/*PAGE
+ *
+ * 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219
+ */
+
+int sem_init(
+ sem_t *sem,
+ int pshared,
+ unsigned int value
+)
+{
+ int status;
+ POSIX_Semaphore_Control *the_semaphore;
+
+ status = _POSIX_Semaphore_Create_support(
+ NULL,
+ pshared,
+ value,
+ &the_semaphore
+ );
+
+ if ( status != -1 )
+ *sem = the_semaphore->Object.id;
+
+ return status;
+}
+
+/*PAGE
+ *
+ * 11.2.2 Destroy an Unnamed Semaphore, P1003.1b-1993, p.220
+ */
+
+int sem_destroy(
+ sem_t *sem
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ /*
+ * Undefined operation on a named semaphore.
+ */
+
+ if ( the_semaphore->named == TRUE ) {
+ seterrno( EINVAL );
+ return( -1 );
+ }
+
+ _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
+
+ _CORE_semaphore_Flush(
+ &the_semaphore->Semaphore,
+ _POSIX_Semaphore_MP_Send_object_was_deleted,
+ -1 /* XXX should also seterrno -> EINVAL */
+ );
+
+ _POSIX_Semaphore_Free( the_semaphore );
+
+ if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Semaphore_Information,
+ the_semaphore->Object.id
+ );
+
+ _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
+ the_semaphore->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221
+ *
+ * NOTE: When oflag is O_CREAT, then optional third and fourth
+ * parameters must be present.
+ */
+
+sem_t *sem_open(
+ const char *name,
+ int oflag,
+ ...
+ /* mode_t mode, */
+ /* unsigned int value */
+)
+{
+ va_list arg;
+ mode_t mode;
+ unsigned int value;
+ int status;
+ Objects_Id the_semaphore_id;
+ POSIX_Semaphore_Control *the_semaphore;
+
+
+ if ( oflag & O_CREAT ) {
+ va_start(arg, oflag);
+ mode = (mode_t) va_arg( arg, mode_t * );
+ value = (unsigned int) va_arg( arg, unsigned int * );
+ va_end(arg);
+ }
+
+ status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
+
+ /*
+ * If the name to id translation worked, then the semaphore exists
+ * and we can just return a pointer to the id. Otherwise we may
+ * need to check to see if this is a "semaphore does not exist"
+ * or some other miscellaneous error on the name.
+ */
+
+ if ( status ) {
+
+ if ( status == EINVAL ) { /* name -> ID translation failed */
+ if ( !(oflag & O_CREAT) ) { /* willing to create it? */
+ seterrno( ENOENT );
+ return (sem_t *) -1;
+ }
+ /* we are willing to create it */
+ }
+ seterrno( status ); /* some type of error */
+ return (sem_t *) -1;
+
+ } else { /* name -> ID translation succeeded */
+
+ if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) {
+ seterrno( EEXIST );
+ return (sem_t *) -1;
+ }
+
+ /*
+ * XXX In this case we need to do an ID->pointer conversion to
+ * check the mode. This is probably a good place for a subroutine.
+ */
+
+ the_semaphore->open_count += 1;
+
+ return (sem_t *)&the_semaphore->Object.id;
+
+ }
+
+ /* XXX verify this comment...
+ *
+ * At this point, the semaphore does not exist and everything has been
+ * checked. We should go ahead and create a semaphore.
+ */
+
+ status = _POSIX_Semaphore_Create_support(
+ name,
+ TRUE, /* shared across processes */
+ value,
+ &the_semaphore
+ );
+
+ if ( status == -1 )
+ return (sem_t *) -1;
+
+ return (sem_t *) &the_semaphore->Object.id;
+
+}
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Delete
+ */
+
+void _POSIX_Semaphore_Delete(
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ if ( !the_semaphore->linked && !the_semaphore->open_count ) {
+ _POSIX_Semaphore_Free( the_semaphore );
+
+ if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
+
+ _Objects_MP_Close(
+ &_POSIX_Semaphore_Information,
+ the_semaphore->Object.id
+ );
+
+ _POSIX_Semaphore_MP_Send_process_packet(
+ POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE,
+ the_semaphore->Object.id,
+ 0, /* Not used */
+ 0 /* Not used */
+ );
+ }
+
+ }
+}
+
+/*PAGE
+ *
+ * 11.2.4 Close a Named Semaphore, P1003.1b-1993, p.224
+ */
+
+int sem_close(
+ sem_t *sem
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ the_semaphore->open_count -= 1;
+ _POSIX_Semaphore_Delete( the_semaphore );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 11.2.5 Remove a Named Semaphore, P1003.1b-1993, p.225
+ */
+
+int sem_unlink(
+ const char *name
+)
+{
+ int status;
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Id the_semaphore_id;
+ Objects_Locations location;
+
+ status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id );
+
+ if ( !status ) {
+ seterrno( status );
+ return -1;
+ }
+
+ the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+
+ if ( the_semaphore->process_shared == PTHREAD_PROCESS_SHARED ) {
+ _Objects_MP_Close(
+ &_POSIX_Semaphore_Information,
+ the_semaphore->Object.id
+ );
+ }
+
+ the_semaphore->linked = FALSE;
+
+ _POSIX_Semaphore_Delete( the_semaphore );
+
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * _POSIX_Semaphore_Wait_support
+ */
+
+int _POSIX_Semaphore_Wait_support(
+ sem_t *sem,
+ boolean blocking,
+ Watchdog_Interval timeout
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ _CORE_semaphore_Seize(
+ &the_semaphore->Semaphore,
+ the_semaphore->Object.id,
+ blocking,
+ timeout
+ );
+ _Thread_Enable_dispatch();
+ return _Thread_Executing->Wait.return_code;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_wait(
+ sem_t *sem
+)
+{
+ return _POSIX_Semaphore_Wait_support( sem, TRUE, THREAD_QUEUE_WAIT_FOREVER );
+}
+
+/*PAGE
+ *
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_trywait(
+ sem_t *sem
+)
+{
+ return _POSIX_Semaphore_Wait_support( sem, FALSE, THREAD_QUEUE_WAIT_FOREVER );
+}
+
+/*PAGE
+ *
+ * 11.2.6 Lock a Semaphore, P1003.1b-1993, p.226
+ *
+ * NOTE: P1003.4b/D8 adds sem_timedwait(), p. 27
+ */
+
+int sem_timedwait(
+ sem_t *sem,
+ const struct timespec *timeout
+)
+{
+ return _POSIX_Semaphore_Wait_support(
+ sem,
+ TRUE,
+ _POSIX_Time_Spec_to_interval( timeout )
+ );
+}
+
+/*PAGE
+ *
+ * 11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227
+ */
+
+void POSIX_Semaphore_MP_support(
+ Thread_Control *the_thread,
+ Objects_Id id
+)
+{
+ (void) POSIX_MP_NOT_IMPLEMENTED();
+}
+
+
+int sem_post(
+ sem_t *sem
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ _CORE_semaphore_Surrender(
+ &the_semaphore->Semaphore,
+ the_semaphore->Object.id,
+ POSIX_Semaphore_MP_support
+ );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
+
+/*PAGE
+ *
+ * 11.2.8 Get the Value of a Semaphore, P1003.1b-1993, p.229
+ */
+
+int sem_getvalue(
+ sem_t *sem,
+ int *sval
+)
+{
+ register POSIX_Semaphore_Control *the_semaphore;
+ Objects_Locations location;
+
+ the_semaphore = _POSIX_Semaphore_Get( sem, &location );
+ switch ( location ) {
+ case OBJECTS_ERROR:
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_REMOTE:
+ _Thread_Dispatch();
+ return POSIX_MP_NOT_IMPLEMENTED();
+ seterrno( EINVAL );
+ return( -1 );
+ case OBJECTS_LOCAL:
+ *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore );
+ _Thread_Enable_dispatch();
+ return 0;
+ }
+ return POSIX_BOTTOM_REACHED();
+}
diff --git a/c/src/exec/posix/src/time.c b/c/src/exec/posix/src/time.c
new file mode 100644
index 0000000000..fb99848c67
--- /dev/null
+++ b/c/src/exec/posix/src/time.c
@@ -0,0 +1,192 @@
+/* time.c
+ *
+ */
+
+#include <time.h>
+#include <rtems/score/tod.h>
+
+/*
+ * Seconds from January 1, 1970 to January 1, 1988. Used to account for
+ * differences between POSIX API and RTEMS core.
+ */
+
+#define POSIX_TIME_SECONDS_1970_THROUGH_1988 \
+ (((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
+ (4 * TOD_SECONDS_PER_DAY))
+
+/*
+ * 4.5.1 Get System Time, P1003.1b-1993, p. 91
+ */
+
+time_t time(
+ time_t *tloc
+)
+{
+ time_t seconds_since_epoch;
+
+ if ( !_TOD_Is_set() ) {
+ /* XXX set errno */
+ return -1;
+ }
+
+ /*
+ * Internally the RTEMS epoch is 1988. This must be taken into account.
+ */
+
+ seconds_since_epoch = _TOD_Seconds_since_epoch;
+
+ seconds_since_epoch += POSIX_TIME_SECONDS_1970_THROUGH_1988;
+
+ if ( tloc )
+ *tloc = seconds_since_epoch;
+
+ return seconds_since_epoch;
+}
+
+#ifdef NOT_IMPLEMENTED_YET
+/*
+ * 14.2.1 Clocks, P1003.1b-1993, p. 263
+ */
+
+int clock_settime(
+ clockid_t clock_id,
+ const struct timespec *tp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.1 Clocks, P1003.1b-1993, p. 263
+ */
+
+int clock_gettime(
+ clockid_t clock_id,
+ struct timespec *tp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.1 Clocks, P1003.1b-1993, p. 263
+ */
+
+int clock_getres(
+ clockid_t clock_id,
+ struct timespec *res
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
+ */
+
+int timer_create(
+ clockid_t clock_id,
+ struct sigevent *evp,
+ timer_t *timerid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
+ */
+
+int timer_delete(
+ timer_t timerid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+int timer_settime(
+ timer_t timerid,
+ int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+int timer_gettime(
+ timer_t timerid,
+ struct itimerspec *value
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+int timer_getoverrun(
+ timer_t timerid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
+ */
+
+int nanosleep(
+ const struct timespec *rqtp,
+ struct timespec *rmtp
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 20.1.3 Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55
+ */
+
+int clock_getcpuclockid(
+ pid_t pid,
+ clockid_t *clock_id
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
+ */
+
+int clock_setenable_attr(
+ clockid_t clock_id,
+ int attr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*
+ * 20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
+ */
+
+int clock_getenable_attr(
+ clockid_t clock_id,
+ int *attr
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
diff --git a/c/src/exec/posix/src/types.c b/c/src/exec/posix/src/types.c
new file mode 100644
index 0000000000..34b0905e04
--- /dev/null
+++ b/c/src/exec/posix/src/types.c
@@ -0,0 +1,167 @@
+/* types.c
+ *
+ */
+
+#include <sys/types.h>
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83
+ */
+
+pid_t getpid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83
+ */
+
+pid_t getppid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+uid_t getuid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+uid_t geteuid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+gid_t getgid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.1 Get Real User, Effective User, Ral Group, and Effective Group IDs,
+ * P1003.1b-1993, p. 84
+ */
+
+gid_t getegid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.2 Set User and Group IDs, P1003.1b-1993, p. 84
+ */
+
+int setuid(
+ uid_t uid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.2 Set User and Group IDs, P1003.1b-1993, p. 84
+ */
+
+int setgid(
+ gid_t gid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.3 Get Supplementary IDs, P1003.1b-1993, p. 86
+ */
+
+int getgroups(
+ int gidsetsize,
+ gid_t grouplist[]
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.4 Get User Name, P1003.1b-1993, p. 87
+ *
+ * NOTE: P1003.1c/D10, p. 49 adds getlogin_r().
+ */
+
+char *getlogin( void )
+{
+ return (char *)POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.2.4 Get User Name, P1003.1b-1993, p. 87
+ *
+ * NOTE: P1003.1c/D10, p. 49 adds getlogin_r().
+ */
+
+char *getlogin_r( void )
+{
+ return (char *)POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.3.1 Get Process Group IDs, P1003.1b-1993, p. 89
+ */
+
+pid_t getpgrp( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.3.2 Create Session and Set Process Group ID, P1003.1b-1993, p. 88
+ */
+
+pid_t setsid( void )
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+/*PAGE
+ *
+ * 4.3.3 Set Process Group ID for Job Control, P1003.1b-1993, p. 89
+ */
+
+int setpgid(
+ pid_t pid,
+ pid_t pgid
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
diff --git a/c/src/exec/posix/src/unistd.c b/c/src/exec/posix/src/unistd.c
new file mode 100644
index 0000000000..ecda95ebe3
--- /dev/null
+++ b/c/src/exec/posix/src/unistd.c
@@ -0,0 +1,20 @@
+/* unistd.c
+ *
+ */
+
+#include <unistd.h>
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*
+ * 4.8.1 Get Configurable System Variables, P1003.1b-1993, p. 95
+ */
+
+long sysconf(
+ int name
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif
diff --git a/c/src/exec/posix/src/utsname.c b/c/src/exec/posix/src/utsname.c
new file mode 100644
index 0000000000..15bd2665f6
--- /dev/null
+++ b/c/src/exec/posix/src/utsname.c
@@ -0,0 +1,60 @@
+/* utsname.c
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/utsname.h>
+
+#include <rtems/score/system.h>
+#include <rtems/score/object.h>
+
+/*PAGE
+ *
+ * 4.4.1 Get System Name, P1003.1b-1993, p. 90
+ */
+
+int uname(
+ struct utsname *name
+)
+{
+ /* XXX: Here is what Solaris returns...
+ sysname = SunOS
+ nodename = merlin
+ release = 5.3
+ version = Generic_101318-12
+ machine = sun4m
+ */
+
+ strcpy( name->sysname, "RTEMS" );
+
+ sprintf( name->nodename, "Node %d\n", _Objects_Local_node );
+
+ /* XXX release string is in BAD format for this routine!!! */
+ strcpy( name->release, "3.2.0" );
+
+ /* XXX does this have any meaning for RTEMS */
+
+ strcpy( name->release, "" );
+
+ sprintf( name->machine, "%s/%s", CPU_NAME, CPU_MODEL_NAME );
+
+ return 0;
+}
+
+#ifdef NOT_IMPLEMENTED_YET
+
+/*PAGE
+ *
+ * 4.5.2 Get Process Times, P1003.1b-1993, p. 92
+ */
+
+clock_t times(
+ struct tms *buffer
+)
+{
+ return POSIX_NOT_IMPLEMENTED();
+}
+
+#endif