From 5e9b32b439627068a0292370fe595220dbfc95a0 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 26 Sep 1995 19:27:15 +0000 Subject: posix support initially added --- cpukit/posix/include/aio.h | 136 +++++ cpukit/posix/include/devctl.h | 29 + cpukit/posix/include/intr.h | 70 +++ cpukit/posix/include/mqueue.h | 144 +++++ cpukit/posix/include/rtems/posix/cancel.h | 15 + cpukit/posix/include/rtems/posix/cond.h | 123 +++++ cpukit/posix/include/rtems/posix/condmp.h | 162 ++++++ cpukit/posix/include/rtems/posix/intr.h | 154 ++++++ cpukit/posix/include/rtems/posix/key.h | 136 +++++ cpukit/posix/include/rtems/posix/mqueue.h | 186 +++++++ cpukit/posix/include/rtems/posix/mqueuemp.h | 161 ++++++ cpukit/posix/include/rtems/posix/mutex.h | 117 ++++ cpukit/posix/include/rtems/posix/mutexmp.h | 161 ++++++ cpukit/posix/include/rtems/posix/priority.h | 34 ++ cpukit/posix/include/rtems/posix/pthread.h | 113 ++++ cpukit/posix/include/rtems/posix/pthreadmp.h | 161 ++++++ cpukit/posix/include/rtems/posix/semaphore.h | 135 +++++ cpukit/posix/include/rtems/posix/semaphoremp.h | 161 ++++++ cpukit/posix/include/rtems/posix/threadsup.h | 29 + cpukit/posix/include/rtems/posix/time.h | 14 + cpukit/posix/include/sched.h | 87 +++ cpukit/posix/include/semaphore.h | 107 ++++ cpukit/posix/inline/rtems/posix/cond.inl | 76 +++ cpukit/posix/inline/rtems/posix/intr.inl | 72 +++ cpukit/posix/inline/rtems/posix/key.inl | 70 +++ cpukit/posix/inline/rtems/posix/mqueue.inl | 83 +++ cpukit/posix/inline/rtems/posix/mutex.inl | 88 +++ cpukit/posix/inline/rtems/posix/priority.inl | 26 + cpukit/posix/inline/rtems/posix/pthread.inl | 71 +++ cpukit/posix/inline/rtems/posix/semaphore.inl | 71 +++ cpukit/posix/src/aio.c | 112 ++++ cpukit/posix/src/cancel.c | 226 ++++++++ cpukit/posix/src/cond.c | 398 ++++++++++++++ cpukit/posix/src/devctl.c | 24 + cpukit/posix/src/intr.c | 336 ++++++++++++ cpukit/posix/src/key.c | 259 +++++++++ cpukit/posix/src/mqueue.c | 713 +++++++++++++++++++++++++ cpukit/posix/src/mutex.c | 569 ++++++++++++++++++++ cpukit/posix/src/psignal.c | 261 +++++++++ cpukit/posix/src/pthread.c | 552 +++++++++++++++++++ cpukit/posix/src/sched.c | 126 +++++ cpukit/posix/src/semaphore.c | 575 ++++++++++++++++++++ cpukit/posix/src/time.c | 192 +++++++ cpukit/posix/src/types.c | 167 ++++++ 44 files changed, 7502 insertions(+) create mode 100644 cpukit/posix/include/aio.h create mode 100644 cpukit/posix/include/devctl.h create mode 100644 cpukit/posix/include/intr.h create mode 100644 cpukit/posix/include/mqueue.h create mode 100644 cpukit/posix/include/rtems/posix/cancel.h create mode 100644 cpukit/posix/include/rtems/posix/cond.h create mode 100644 cpukit/posix/include/rtems/posix/condmp.h create mode 100644 cpukit/posix/include/rtems/posix/intr.h create mode 100644 cpukit/posix/include/rtems/posix/key.h create mode 100644 cpukit/posix/include/rtems/posix/mqueue.h create mode 100644 cpukit/posix/include/rtems/posix/mqueuemp.h create mode 100644 cpukit/posix/include/rtems/posix/mutex.h create mode 100644 cpukit/posix/include/rtems/posix/mutexmp.h create mode 100644 cpukit/posix/include/rtems/posix/priority.h create mode 100644 cpukit/posix/include/rtems/posix/pthread.h create mode 100644 cpukit/posix/include/rtems/posix/pthreadmp.h create mode 100644 cpukit/posix/include/rtems/posix/semaphore.h create mode 100644 cpukit/posix/include/rtems/posix/semaphoremp.h create mode 100644 cpukit/posix/include/rtems/posix/threadsup.h create mode 100644 cpukit/posix/include/rtems/posix/time.h create mode 100644 cpukit/posix/include/sched.h create mode 100644 cpukit/posix/include/semaphore.h create mode 100644 cpukit/posix/inline/rtems/posix/cond.inl create mode 100644 cpukit/posix/inline/rtems/posix/intr.inl create mode 100644 cpukit/posix/inline/rtems/posix/key.inl create mode 100644 cpukit/posix/inline/rtems/posix/mqueue.inl create mode 100644 cpukit/posix/inline/rtems/posix/mutex.inl create mode 100644 cpukit/posix/inline/rtems/posix/priority.inl create mode 100644 cpukit/posix/inline/rtems/posix/pthread.inl create mode 100644 cpukit/posix/inline/rtems/posix/semaphore.inl create mode 100644 cpukit/posix/src/aio.c create mode 100644 cpukit/posix/src/cancel.c create mode 100644 cpukit/posix/src/cond.c create mode 100644 cpukit/posix/src/devctl.c create mode 100644 cpukit/posix/src/intr.c create mode 100644 cpukit/posix/src/key.c create mode 100644 cpukit/posix/src/mqueue.c create mode 100644 cpukit/posix/src/mutex.c create mode 100644 cpukit/posix/src/psignal.c create mode 100644 cpukit/posix/src/pthread.c create mode 100644 cpukit/posix/src/sched.c create mode 100644 cpukit/posix/src/semaphore.c create mode 100644 cpukit/posix/src/time.c create mode 100644 cpukit/posix/src/types.c (limited to 'cpukit/posix') diff --git a/cpukit/posix/include/aio.h b/cpukit/posix/include/aio.h new file mode 100644 index 0000000000..2fbb8ad925 --- /dev/null +++ b/cpukit/posix/include/aio.h @@ -0,0 +1,136 @@ +/* aio.h + * + */ + +#ifndef __POSIX_ASYNCHRONOUS_IO_h +#define __POSIX_ASYNCHRONOUS_IO_h + +#include + +#if defined(_POSIX_ASYNCHRONOUS_IO) + +/* + * 6.7.1 Data Definitions for Asynchronous Input and Output, + * P1003.1b-1993, p. 151 + */ + +#include +#include +#include +#include + +/* + * 6.7.1.2 Manifest Constants, P1003.1b-1993, p. 153 + */ + +#define AIO_CANCELED 0 /* all requested operations have been canceled */ +#define AIO_NOTCANCELED 0 /* some of the operations could not be canceled */ + /* since they are in progress */ +#define AIO_ALLDONE 0 /* none of the requested operations could be */ + /* canceled since they are already complete */ + +/* lio_listio() options */ + +#define LIO_WAIT 0 /* calling process is to suspend until the */ + /* operation is complete */ +#define LIO_NOWAIT 0 /* calling process is to continue execution while */ + /* the operation is performed and no notification */ + /* shall be given when the operation is completed */ +#define LIO_READ 0 /* request a read() */ +#define LIO_WRITE 0 /* request a write() */ +#define LIO_NOP 0 /* no transfer is requested */ + +/* + * 6.7.1.1 Asynchronous I/O Control Block, P1003.1b-1993, p. 151 + */ + +struct aiocb { + int aio_fildes; /* File descriptor */ + off_t aio_offset; /* File offset */ + volatile void *aio_buf; /* Location of buffer */ + size_t aio_nbytes; /* Length of transfer */ + int aio_reqprio; /* Request priority offset */ + struct sigevent aio_sigevent; /* Signal number and value */ + int aoi_lio_opcode; /* Operation to be performed */ +}; + +/* + * 6.7.2 Asynchronous Read, P1003.1b-1993, p. 154 + */ + +int aio_read( + struct aiocb *aiocbp +); + +/* + * 6.7.3 Asynchronous Write, P1003.1b-1993, p. 155 + */ + +int aio_write( + struct aiocb *aiocbp +); + +/* + * 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 +); + +/* + * 6.7.5 Retrieve Error of Asynchronous I/O Operation, P1003.1b-1993, p. 161 + */ + +int aio_error( + const struct aiocb *aiocbp +); + +/* + * 6.7.6 Retrieve Return Status of Asynchronous I/O Operation, + * P1003.1b-1993, p. 162 + */ + +int aio_return( + const struct aiocb *aiocbp +); + +/* + * 6.7.7 Cancel Asynchronous I/O Operation, P1003.1b-1993, p. 163 + */ + +int aio_cancel( + int filedes, + struct aiocb *aiocbp +); + +/* + * 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 +); + +#if defined(_POSIX_SYNCHRONIZED_IO) + +/* + * 6.7.9 Asynchronous File Synchronization, P1003.1b-1993, p. 166 + */ + +int aio_fsync( + int op, + struct aiocb *aiocbp +); + +#endif /* _POSIX_SYNCHRONIZED_IO */ + +#endif /* _POSIX_ASYNCHRONOUS_IO */ + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/devctl.h b/cpukit/posix/include/devctl.h new file mode 100644 index 0000000000..e3fd39128f --- /dev/null +++ b/cpukit/posix/include/devctl.h @@ -0,0 +1,29 @@ +/* devctl.h + * + */ + +#ifndef __POSIX_DEVICE_CONTROL_h +#define __POSIX_DEVICE_CONTROL_h + +#include + +#if defined(_POSIX_DEVICE_CONTROL) + +#include +#include + +/* + * 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 +); + +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/intr.h b/cpukit/posix/include/intr.h new file mode 100644 index 0000000000..9394ab22a3 --- /dev/null +++ b/cpukit/posix/include/intr.h @@ -0,0 +1,70 @@ +/* intr.h + * + * XXX: It is unclear if the type "intr_t" should be defined when + * _POSIX_INTERRUPT_CONTROL is not. + */ + +#ifndef __POSIX_INTERRUPTS_h +#define __POSIX_INTERRUPTS_h + +#include +#include +#include + +#if defined(_POSIX_INTERRUPT_CONTROL) + +/* + * 22.2 Concepts, P1003.4b/D8, p. 73 + */ + +typedef int intr_t; + +/* + * 22.3.1 Associate a User-Written ISR with an Interrupt, P1003.4b/D8, p. 74 + */ + +/* + * Return codes from an interrupt handler + */ + +#define INTR_HANDLED_NOTIFY 0 /* ISR handled this interrupt, notify */ + /* the thread that registered the */ + /* ISR that the interrupt occurred. */ +#define INTR_HANDLED_DO_NOT_NOTIFY 1 /* ISR handled this interrupt, but */ + /* do NOT perform notification. */ +#define INTR_NOT_HANDLED 2 /* ISR did not handle this interrupt, */ + /* let the next handler try. */ + +int intr_capture( + intr_t intr, + int (*intr_handler)( void *area ), + volatile void *area, + size_t areasize +); + +int intr_release( + intr_t intr, + int (*intr_handler)( void *area ) +); + +int intr_lock( + intr_t intr +); + +int intr_unlock( + intr_t intr +); + +/* + * 22.3.2 Await Interrupt Notification, P1003.4b/D8, p. 76 + */ + +int intr_timed_wait( + int flags, + const struct timespec *timeout +); + +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/mqueue.h b/cpukit/posix/include/mqueue.h new file mode 100644 index 0000000000..f40381c5f5 --- /dev/null +++ b/cpukit/posix/include/mqueue.h @@ -0,0 +1,144 @@ +/* mqueue.h + * + */ + +#ifndef __POSIX_MESSAGE_QUEUE_h +#define __POSIX_MESSAGE_QUEUE_h + +#include + +#if defined(_POSIX_MESSAGE_PASSING) + +#include + +#include +#include + +/* + * 15.1.1 Data Structures, P1003.1b-1993, p. 271 + */ + +typedef Objects_Id mqd_t; + +struct mq_attr { + long mq_flags; /* Message queue flags */ + long mq_maxmsg; /* Maximum number of messages */ + long mq_msgsize; /* Maximum message size */ + long mq_curmsgs; /* Number of messages currently queued */ +}; + +/* + * 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272 + */ + +mqd_t mq_open( + const char *name, + int oflag, + ... +); + +/* + * 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275 + */ + +int mq_close( + mqd_t mqdes +); + +/* + * 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276 + */ + +int mq_unlink( + const char *name +); + +/* + * 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 +); + +#if defined(_POSIX_TIMEOUTS) + +#include + +int mq_timedsend( + mqd_t mqdes, + const char *msg_ptr, + size_t msg_len, + unsigned int msg_prio, + const struct timespec *timeout +); + +#endif /* _POSIX_TIMEOUTS */ + +/* + * 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 +); + +#if defined(_POSIX_TIMEOUTS) + +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 +); + +#endif /* _POSIX_TIMEOUTS */ + +#if defined(_POSIX_REALTIME_SIGNALS) + +/* + * 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 +); + +#endif /* _POSIX_REALTIME_SIGNALS */ + +/* + * 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 +); + +/* + * 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283 + */ + +int mq_getattr( + mqd_t mqdes, + struct mq_attr *mqstat +); + +#endif /* _POSIX_MESSAGE_PASSING */ + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/cancel.h b/cpukit/posix/include/rtems/posix/cancel.h new file mode 100644 index 0000000000..de059d317d --- /dev/null +++ b/cpukit/posix/include/rtems/posix/cancel.h @@ -0,0 +1,15 @@ +/* rtems/posix/cancel.h + * + */ + +#ifndef __RTEMS_POSIX_CANCEL_h +#define __RTEMS_POSIX_CANCEL_h + +typedef struct { + Chain_Node Node; + void (*routine)( void * ); + void *arg; +} POSIX_Cancel_Handler_control; + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/cond.h b/cpukit/posix/include/rtems/posix/cond.h new file mode 100644 index 0000000000..4448e38b6c --- /dev/null +++ b/cpukit/posix/include/rtems/posix/cond.h @@ -0,0 +1,123 @@ +/* rtems/posix/cond.h + * + * This include file contains all the private support information for + * POSIX condition variables. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_CONDITION_VARIABLES_h +#define __RTEMS_POSIX_CONDITION_VARIABLES_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Data Structure used to manage a POSIX condition variable + */ + +typedef struct { + Objects_Control Object; + int process_shared; + pthread_mutex_t Mutex; + Thread_queue_Control Wait_queue; +} POSIX_Condition_variables_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Condition_variables_Information; + +/* + * _POSIX_Condition_variables_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Condition_variables_Manager_initialization( + unsigned32 maximum_condition_variables +); + +/* + * _POSIX_Condition_variables_Allocate + * + * DESCRIPTION: + * + * This function allocates a condition variable control block from + * the inactive chain of free condition variable control blocks. + */ + +STATIC INLINE POSIX_Condition_variables_Control * + _POSIX_Condition_variables_Allocate( void ); + +/* + * _POSIX_Condition_variables_Free + * + * DESCRIPTION: + * + * This routine frees a condition variable control block to the + * inactive chain of free condition variable control blocks. + */ + +STATIC INLINE void _POSIX_Condition_variables_Free ( + POSIX_Condition_variables_Control *the_condition_variable +); + +/* + * _POSIX_Condition_variables_Get + * + * DESCRIPTION: + * + * This function maps condition variable IDs to condition variable control + * blocks. If ID corresponds to a local condition variable, then it returns + * the_condition variable control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the condition variable ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_condition variable is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_condition variable is undefined. + */ + +STATIC INLINE POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get ( + Objects_Id *id, + Objects_Locations *location +); + +/* + * _POSIX_Condition_variables_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_condition variable is NULL + * and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Condition_variables_Is_null ( + POSIX_Condition_variables_Control *the_condition_variable +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/condmp.h b/cpukit/posix/include/rtems/posix/condmp.h new file mode 100644 index 0000000000..12997b68f4 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/condmp.h @@ -0,0 +1,162 @@ +/* condmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the POSIX Condition Variable Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_CONDITION_VARIABLES_MP_h +#define __RTEMS_POSIX_CONDITION_VARIABLES_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote condition variable operations. + */ + +typedef enum { + POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_CREATE = 0, + POSIX_CONDITION_VARIABLES_MP_ANNOUNCE_DELETE = 1, + POSIX_CONDITION_VARIABLES_MP_EXTRACT_PROXY = 2, + POSIX_CONDITION_VARIABLES_MP_OBTAIN_REQUEST = 3, + POSIX_CONDITION_VARIABLES_MP_OBTAIN_RESPONSE = 4, + POSIX_CONDITION_VARIABLES_MP_RELEASE_REQUEST = 5, + POSIX_CONDITION_VARIABLES_MP_RELEASE_RESPONSE = 6, +} POSIX_Condition_variables_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote condition variable operations. + */ + +typedef struct { + MP_packet_Prefix Prefix; + POSIX_Condition_variables_MP_Remote_operations operation; + Objects_Name name; + boolean wait; /* XXX options */ + Objects_Id proxy_id; +} POSIX_Condition_variables_MP_Packet; + +/* + * _POSIX_Condition_variables_MP_Send_process_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ + +void _POSIX_Condition_variables_MP_Send_process_packet ( + POSIX_Condition_variables_MP_Remote_operations operation, + Objects_Id condition_variables_id, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _POSIX_Condition_variables_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +int _POSIX_Condition_variables_MP_Send_request_packet ( + POSIX_Condition_variables_MP_Remote_operations operation, + Objects_Id condition_variables_id, + boolean wait, /* XXX options */ + Watchdog_Interval timeout +); + +/* + * _POSIX_Condition_variables_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _POSIX_Condition_variables_MP_Send_response_packet ( + POSIX_Condition_variables_MP_Remote_operations operation, + Objects_Id condition_variables_id, + Thread_Control *the_thread +); + +/* + * + * _POSIX_Condition_variables_MP_Process_packet + * + * DESCRIPTION: + * + * This routine performs the actions specific to this package for + * the request from another node. + */ + +void _POSIX_Condition_variables_MP_Process_packet ( + MP_packet_Prefix *the_packet_prefix +); + +/* + * _POSIX_Condition_variables_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Condition_variables_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/* + * _POSIX_Condition_variables_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Condition_variables_MP_Send_extract_proxy ( + Thread_Control *the_thread +); + +/* + * _POSIX_Condition_variables_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a condition variable mp packet. + */ + +POSIX_Condition_variables_MP_Packet + *_POSIX_Condition_variables_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/posix/include/rtems/posix/intr.h b/cpukit/posix/include/rtems/posix/intr.h new file mode 100644 index 0000000000..b940148999 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/intr.h @@ -0,0 +1,154 @@ +/* rtems/posix/intr.h + * + * This include file contains all the private support information for + * POSIX Interrupt Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_KEY_h +#define __RTEMS_POSIX_KEY_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Data Structure used to manage each POSIX Interrupt Vector + */ + +typedef struct { + int number_installed; + int lock_count; + int deferred_count; + Chain_Control Handlers; +} POSIX_Interrupt_Control; + +/* + * Data Structure used to manage a POSIX Interrupt Handler + */ + +typedef struct { + Objects_Control Object; + int is_active; + intr_t vector; + Thread_Control *server; + int (*handler)( void *area ); + volatile void *user_data_area; +} POSIX_Interrupt_Handler_control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Interrupt_Handlers_Information; + +/* + * The following is an array which is used to manage the set of + * interrupt handlers installed on each vector. + */ + +EXTERN POSIX_Interrupt_Control + _POSIX_Interrupt_Information[ ISR_NUMBER_OF_VECTORS ]; + +/* + * _POSIX_Interrupt_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Interrupt_Manager_initialization( + unsigned32 maximum_interrupt_handlers +); + +/* + * _POSIX_Interrupt_Allocate + * + * DESCRIPTION: + * + * This function allocates a interrupt handler control block from + * the inactive chain of free interrupt handler control blocks. + */ + +STATIC INLINE POSIX_Interrupt_Handler_control * + _POSIX_Interrupt_Allocate( void ); + +/* + * _POSIX_Interrupt_Free + * + * DESCRIPTION: + * + * This routine frees a interrupt handler control block to the + * inactive chain of free interrupt handler control blocks. + */ + +STATIC INLINE void _POSIX_Interrupt_Free ( + POSIX_Interrupt_Handler_control *the_intr +); + +/* + * _POSIX_Interrupt_Get + * + * DESCRIPTION: + * + * This function maps interrupt handler IDs to interrupt handler control + * blocks. If ID corresponds to a local interrupt handler, then it returns + * the_intr control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the interrupt handler ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_intr is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_intr is undefined. + */ + +STATIC INLINE POSIX_Interrupt_Control *_POSIX_Interrupt_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _POSIX_Interrupt_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_intr is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Interrupt_Is_null ( + POSIX_Interrupt_Handler_control *the_intr +); + +/* + * _POSIX_Interrupt_Handler + * + * DESCRIPTION: + * + * This function XXX. + */ + +void _POSIX_Interrupt_Handler( + ISR_Vector_number vector +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/key.h b/cpukit/posix/include/rtems/posix/key.h new file mode 100644 index 0000000000..0e690161b8 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/key.h @@ -0,0 +1,136 @@ +/* rtems/posix/key.h + * + * This include file contains all the private support information for + * POSIX key. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_KEY_h +#define __RTEMS_POSIX_KEY_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Data Structure used to manage a POSIX key + * + * NOTE: The Values is a table indexed by the index portion of the + * ID of the currently executing thread. + */ + +typedef struct { + Objects_Control Object; + boolean is_active; + void (*destructor)( void * ); + void **Values[ OBJECTS_CLASSES_LAST_THREAD_CLASS + 1 ]; +} POSIX_Keys_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Keys_Information; + +/* + * _POSIX_Keys_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Key_Manager_initialization( + unsigned32 maximum_keys +); + +/* + * _POSIX_Keys_Run_destructors + * + * DESCRIPTION: + * + * This function executes all the destructors associated with the thread's + * keys. This function will execute until all values have been set to NULL. + * + * NOTE: This is the routine executed when a thread exits to + * run through all the keys and do the destructor action. + */ + +void _POSIX_Keys_Run_destructors( + Thread_Control *thread +); + +/* + * _POSIX_Keys_Allocate + * + * DESCRIPTION: + * + * This function allocates a keys control block from + * the inactive chain of free keys control blocks. + */ + +STATIC INLINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void ); + +/* + * _POSIX_Keys_Free + * + * DESCRIPTION: + * + * This routine frees a keys control block to the + * inactive chain of free keys control blocks. + */ + +STATIC INLINE void _POSIX_Keys_Free ( + POSIX_Keys_Control *the_key +); + +/* + * _POSIX_Keys_Get + * + * DESCRIPTION: + * + * This function maps key IDs to key control blocks. + * If ID corresponds to a local keys, then it returns + * the_key control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the keys ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_key is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_key is undefined. + */ + +STATIC INLINE POSIX_Keys_Control *_POSIX_Keys_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _POSIX_Keys_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_key is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Keys_Is_null ( + POSIX_Keys_Control *the_key +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/mqueue.h b/cpukit/posix/include/rtems/posix/mqueue.h new file mode 100644 index 0000000000..5d5cfee61b --- /dev/null +++ b/cpukit/posix/include/rtems/posix/mqueue.h @@ -0,0 +1,186 @@ +/* rtems/posix/mqueue.h + * + * This include file contains all the private support information for + * POSIX Message Queues. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_MESSAGE_QUEUE_h +#define __RTEMS_POSIX_MESSAGE_QUEUE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Data Structure used to manage a POSIX message queue + */ + +typedef struct { + Objects_Control Object; + int process_shared; + int flags; + boolean named; + boolean linked; + boolean blocking; + unsigned32 open_count; + CORE_message_queue_Control Message_queue; + struct sigevent notification; +} POSIX_Message_queue_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Message_queue_Information; + +/* + * _POSIX_Message_queue_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Message_queue_Manager_initialization( + unsigned32 maximum_message_queues +); + +/* + * + * _POSIX_Message_queue_Create_support + * + * DESCRIPTION: + * + * This routine performs the creation of a message queue utilizing the + * core message queue. + */ + +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_Send_support + * + * DESCRIPTION: + * + * This routine posts a message to a specified message queue. + */ + +int _POSIX_Message_queue_Send_support( + mqd_t mqdes, + const char *msg_ptr, + unsigned32 msg_len, + Priority_Control msg_prio, + Watchdog_Interval timeout +); + +/* + * _POSIX_Message_queue_Allocate + * + * DESCRIPTION: + * + * This function allocates a message queue control block from + * the inactive chain of free message queue control blocks. + */ + +STATIC INLINE POSIX_Message_queue_Control *_POSIX_Message_queue_Allocate( void ); + +/* + * _POSIX_Message_queue_Free + * + * DESCRIPTION: + * + * This routine frees a message queue control block to the + * inactive chain of free message queue control blocks. + */ + +STATIC INLINE void _POSIX_Message_queue_Free ( + POSIX_Message_queue_Control *the_mq +); + +/* + * _POSIX_Message_queue_Get + * + * DESCRIPTION: + * + * This function maps message queue IDs to message queue control blocks. + * If ID corresponds to a local message queue, then it returns + * the_mq control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the message queue ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_message queue is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_mq is undefined. + */ + +STATIC INLINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _POSIX_Message_queue_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_message_queue is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Message_queue_Is_null ( + POSIX_Message_queue_Control *the_mq +); + +/* + * _POSIX_Message_queue_Name_to_id + * + * DESCRIPTION: + * + * XXX + */ + +int _POSIX_Message_queue_Name_to_id( + const char *name, + Objects_Id *id +); + +/* + * _POSIX_Message_queue_Priority_to_core + * + * DESCRIPTION: + * + * XXX + */ + +STATIC INLINE Priority_Control _POSIX_Message_queue_Priority_to_core( + unsigned int priority +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/mqueuemp.h b/cpukit/posix/include/rtems/posix/mqueuemp.h new file mode 100644 index 0000000000..ae23f6af56 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/mqueuemp.h @@ -0,0 +1,161 @@ +/* mqueuemp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the POSIX Message Queue Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_MESSAGE_QUEUE_MP_h +#define __RTEMS_POSIX_MESSAGE_QUEUE_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote message queue operations. + */ + +typedef enum { + POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_CREATE = 0, + POSIX_MESSAGE_QUEUE_MP_ANNOUNCE_DELETE = 1, + POSIX_MESSAGE_QUEUE_MP_EXTRACT_PROXY = 2, + POSIX_MESSAGE_QUEUE_MP_OBTAIN_REQUEST = 3, + POSIX_MESSAGE_QUEUE_MP_OBTAIN_RESPONSE = 4, + POSIX_MESSAGE_QUEUE_MP_RELEASE_REQUEST = 5, + POSIX_MESSAGE_QUEUE_MP_RELEASE_RESPONSE = 6, +} POSIX_Message_queue_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote message queue operations. + */ + +typedef struct { + MP_packet_Prefix Prefix; + POSIX_Message_queue_MP_Remote_operations operation; + Objects_Name name; + boolean wait; /* XXX options */ + Objects_Id proxy_id; +} POSIX_Message_queue_MP_Packet; + +/* + * _POSIX_Message_queue_MP_Send_process_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ + +void _POSIX_Message_queue_MP_Send_process_packet ( + POSIX_Message_queue_MP_Remote_operations operation, + Objects_Id mq_id, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _POSIX_Message_queue_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +int _POSIX_Message_queue_MP_Send_request_packet ( + POSIX_Message_queue_MP_Remote_operations operation, + Objects_Id mq_id, + boolean wait, /* XXX options */ + Watchdog_Interval timeout +); + +/* + * _POSIX_Message_queue_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _POSIX_Message_queue_MP_Send_response_packet ( + POSIX_Message_queue_MP_Remote_operations operation, + Objects_Id mq_id, + Thread_Control *the_thread +); + +/* + * + * _POSIX_Message_queue_MP_Process_packet + * + * DESCRIPTION: + * + * This routine performs the actions specific to this package for + * the request from another node. + */ + +void _POSIX_Message_queue_MP_Process_packet ( + MP_packet_Prefix *the_packet_prefix +); + +/* + * _POSIX_Message_queue_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Message_queue_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/* + * _POSIX_Message_queue_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Message_queue_MP_Send_extract_proxy ( + Thread_Control *the_thread +); + +/* + * _POSIX_Message_queue_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a message queue mp packet. + */ + +POSIX_Message_queue_MP_Packet *_POSIX_Message_queue_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/posix/include/rtems/posix/mutex.h b/cpukit/posix/include/rtems/posix/mutex.h new file mode 100644 index 0000000000..5639d908d2 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/mutex.h @@ -0,0 +1,117 @@ +/* rtems/posix/mutex.h + * + * This include file contains all the private support information for + * POSIX mutex's. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_MUTEX_h +#define __RTEMS_POSIX_MUTEX_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Data Structure used to manage a POSIX mutex + */ + +typedef struct { + Objects_Control Object; + int process_shared; + CORE_mutex_Control Mutex; +} POSIX_Mutex_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Mutex_Information; + +/* + * _POSIX_Mutex_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Mutex_Manager_initialization( + unsigned32 maximum_mutexes +); + +/* + * _POSIX_Mutex_Allocate + * + * DESCRIPTION: + * + * This function allocates a mutexes control block from + * the inactive chain of free mutexes control blocks. + */ + +STATIC INLINE POSIX_Mutex_Control *_POSIX_Mutex_Allocate( void ); + +/* + * _POSIX_Mutex_Free + * + * DESCRIPTION: + * + * This routine frees a mutexes control block to the + * inactive chain of free mutexes control blocks. + */ + +STATIC INLINE void _POSIX_Mutex_Free ( + POSIX_Mutex_Control *the_mutex +); + +/* + * _POSIX_Mutex_Get + * + * DESCRIPTION: + * + * This function maps mutexes IDs to mutexes control blocks. + * If ID corresponds to a local mutexes, then it returns + * the_mutex control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the mutexes ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_mutex is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_mutex is undefined. + */ + +STATIC INLINE POSIX_Mutex_Control *_POSIX_Mutex_Get ( + Objects_Id *id, + Objects_Locations *location +); + +/* + * _POSIX_Mutex_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_mutex is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Mutex_Is_null ( + POSIX_Mutex_Control *the_mutex +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/mutexmp.h b/cpukit/posix/include/rtems/posix/mutexmp.h new file mode 100644 index 0000000000..15ac5371e8 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/mutexmp.h @@ -0,0 +1,161 @@ +/* mutexmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the POSIX Mutex Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_MUTEX_MP_h +#define __RTEMS_POSIX_MUTEX_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote mutex operations. + */ + +typedef enum { + POSIX_MUTEX_MP_ANNOUNCE_CREATE = 0, + POSIX_MUTEX_MP_ANNOUNCE_DELETE = 1, + POSIX_MUTEX_MP_EXTRACT_PROXY = 2, + POSIX_MUTEX_MP_OBTAIN_REQUEST = 3, + POSIX_MUTEX_MP_OBTAIN_RESPONSE = 4, + POSIX_MUTEX_MP_RELEASE_REQUEST = 5, + POSIX_MUTEX_MP_RELEASE_RESPONSE = 6, +} POSIX_Mutex_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote mutex operations. + */ + +typedef struct { + MP_packet_Prefix Prefix; + POSIX_Mutex_MP_Remote_operations operation; + Objects_Name name; + boolean wait; /* XXX options */ + Objects_Id proxy_id; +} POSIX_Mutex_MP_Packet; + +/* + * _POSIX_Mutex_MP_Send_process_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ + +void _POSIX_Mutex_MP_Send_process_packet ( + POSIX_Mutex_MP_Remote_operations operation, + Objects_Id mutex_id, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _POSIX_Mutex_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +int _POSIX_Mutex_MP_Send_request_packet ( + POSIX_Mutex_MP_Remote_operations operation, + Objects_Id mutex_id, + boolean wait, /* XXX options */ + Watchdog_Interval timeout +); + +/* + * _POSIX_Mutex_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _POSIX_Mutex_MP_Send_response_packet ( + POSIX_Mutex_MP_Remote_operations operation, + Objects_Id mutex_id, + Thread_Control *the_thread +); + +/* + * + * _POSIX_Mutex_MP_Process_packet + * + * DESCRIPTION: + * + * This routine performs the actions specific to this package for + * the request from another node. + */ + +void _POSIX_Mutex_MP_Process_packet ( + MP_packet_Prefix *the_packet_prefix +); + +/* + * _POSIX_Mutex_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Mutex_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/* + * _POSIX_Mutex_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Mutex_MP_Send_extract_proxy ( + Thread_Control *the_thread +); + +/* + * _POSIX_Mutex_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a mutex mp packet. + */ + +POSIX_Mutex_MP_Packet *_POSIX_Mutex_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/posix/include/rtems/posix/priority.h b/cpukit/posix/include/rtems/posix/priority.h new file mode 100644 index 0000000000..f4cb717b7c --- /dev/null +++ b/cpukit/posix/include/rtems/posix/priority.h @@ -0,0 +1,34 @@ +/* + * + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_PRIORITY_h +#define __RTEMS_POSIX_PRIORITY_h + +#include + +/* + * RTEMS Core has priorities run in the opposite sense of the POSIX API. + */ + +#define POSIX_SCHEDULER_MAXIMUM_PRIORITY (255) + +#define POSIX_SCHEDULER_MINIMUM_PRIORITY (1) + +STATIC INLINE boolean _POSIX_Priority_Is_valid( + int priority +); + +STATIC INLINE Priority_Control _POSIX_Priority_To_core( + int priority +); + +STATIC INLINE int _POSIX_Priority_From_core( + Priority_Control priority +); + +#include + +#endif diff --git a/cpukit/posix/include/rtems/posix/pthread.h b/cpukit/posix/include/rtems/posix/pthread.h new file mode 100644 index 0000000000..538e737268 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/pthread.h @@ -0,0 +1,113 @@ +/* rtems/posix/pthread.h + * + * This include file contains all the private support information for + * POSIX threads. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_THREADS_h +#define __RTEMS_POSIX_THREADS_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Data Structure used to manage a POSIX thread + */ + +typedef Thread_Control POSIX_Threads_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Threads_Information; + +/* + * _POSIX_Threads_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Threads_Manager_initialization( + unsigned32 maximum_pthreads +); + +/* + * _POSIX_Threads_Allocate + * + * DESCRIPTION: + * + * This function allocates a pthread control block from + * the inactive chain of free pthread control blocks. + */ + +STATIC INLINE POSIX_Threads_Control *_POSIX_Threads_Allocate( void ); + +/* + * _POSIX_Threads_Free + * + * DESCRIPTION: + * + * This routine frees a pthread control block to the + * inactive chain of free pthread control blocks. + */ + +STATIC INLINE void _POSIX_Threads_Free ( + POSIX_Threads_Control *the_pthread +); + +/* + * _POSIX_Threads_Get + * + * DESCRIPTION: + * + * This function maps pthread IDs to pthread control blocks. + * If ID corresponds to a local pthread, then it returns + * the_pthread control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the pthread ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_pthread is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_pthread is undefined. + */ + +STATIC INLINE POSIX_Threads_Control *_POSIX_Threads_Get ( + Objects_Id *id, + Objects_Locations *location +); + +/* + * _POSIX_Threads_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_pthread is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Threads_Is_null ( + POSIX_Threads_Control *the_pthread +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/pthreadmp.h b/cpukit/posix/include/rtems/posix/pthreadmp.h new file mode 100644 index 0000000000..e15534136b --- /dev/null +++ b/cpukit/posix/include/rtems/posix/pthreadmp.h @@ -0,0 +1,161 @@ +/* pthreadmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the POSIX Threads Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_THREADS_MP_h +#define __RTEMS_POSIX_THREADS_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote pthread operations. + */ + +typedef enum { + POSIX_THREADS_MP_ANNOUNCE_CREATE = 0, + POSIX_THREADS_MP_ANNOUNCE_DELETE = 1, + POSIX_THREADS_MP_EXTRACT_PROXY = 2, + POSIX_THREADS_MP_OBTAIN_REQUEST = 3, + POSIX_THREADS_MP_OBTAIN_RESPONSE = 4, + POSIX_THREADS_MP_RELEASE_REQUEST = 5, + POSIX_THREADS_MP_RELEASE_RESPONSE = 6 +} POSIX_Threads_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote pthread operations. + */ + +typedef struct { + MP_packet_Prefix Prefix; + POSIX_Threads_MP_Remote_operations operation; + Objects_Name name; + boolean wait; + Objects_Id proxy_id; +} POSIX_Threads_MP_Packet; + +/* + * _POSIX_Threads_MP_Send_process_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ + +void _POSIX_Threads_MP_Send_process_packet ( + POSIX_Threads_MP_Remote_operations operation, + Objects_Id pthread_id, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _POSIX_Threads_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +int _POSIX_Threads_MP_Send_request_packet ( + POSIX_Threads_MP_Remote_operations operation, + Objects_Id pthread_id, + boolean wait, + Watchdog_Interval timeout +); + +/* + * _POSIX_Threads_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _POSIX_Threads_MP_Send_response_packet ( + POSIX_Threads_MP_Remote_operations operation, + Objects_Id pthread_id, + Thread_Control *the_thread +); + +/* + * + * _POSIX_Threads_MP_Process_packet + * + * DESCRIPTION: + * + * This routine performs the actions specific to this package for + * the request from another node. + */ + +void _POSIX_Threads_MP_Process_packet ( + MP_packet_Prefix *the_packet_prefix +); + +/* + * _POSIX_Threads_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Threads_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/* + * _POSIX_Threads_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Threads_MP_Send_extract_proxy ( + Thread_Control *the_thread +); + +/* + * _POSIX_Threads_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a pthread mp packet. + */ + +POSIX_Threads_MP_Packet *_POSIX_Threads_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/posix/include/rtems/posix/semaphore.h b/cpukit/posix/include/rtems/posix/semaphore.h new file mode 100644 index 0000000000..a538663989 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/semaphore.h @@ -0,0 +1,135 @@ +/* rtems/posix/semaphore.h + * + * This include file contains all the private support information for + * POSIX Semaphores. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_SEMAPHORE_h +#define __RTEMS_POSIX_SEMAPHORE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * Data Structure used to manage a POSIX semaphore + */ + +typedef struct { + Objects_Control Object; + int process_shared; + boolean named; + boolean linked; + unsigned32 open_count; + CORE_semaphore_Control Semaphore; +} POSIX_Semaphore_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _POSIX_Semaphore_Information; + +/* + * _POSIX_Semaphore_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Semaphore_Manager_initialization( + unsigned32 maximum_semaphorees +); + +/* + * _POSIX_Semaphore_Allocate + * + * DESCRIPTION: + * + * This function allocates a semaphore control block from + * the inactive chain of free semaphore control blocks. + */ + +STATIC INLINE POSIX_Semaphore_Control *_POSIX_Semaphore_Allocate( void ); + +/* + * _POSIX_Semaphore_Free + * + * DESCRIPTION: + * + * This routine frees a semaphore control block to the + * inactive chain of free semaphore control blocks. + */ + +STATIC INLINE void _POSIX_Semaphore_Free ( + POSIX_Semaphore_Control *the_semaphore +); + +/* + * _POSIX_Semaphore_Get + * + * DESCRIPTION: + * + * This function maps semaphore IDs to semaphore control blocks. + * If ID corresponds to a local semaphore, then it returns + * the_semaphore control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the semaphore ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_semaphore is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_semaphore is undefined. + */ + +STATIC INLINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get ( + Objects_Id *id, + Objects_Locations *location +); + +/* + * _POSIX_Semaphore_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_semaphore is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _POSIX_Semaphore_Is_null ( + POSIX_Semaphore_Control *the_semaphore +); + +/* + * _POSIX_Semaphore_Name_to_id + * + * DESCRIPTION: + * + * XXX + */ + +int _POSIX_Semaphore_Name_to_id( + const char *name, + Objects_Id *id +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/semaphoremp.h b/cpukit/posix/include/rtems/posix/semaphoremp.h new file mode 100644 index 0000000000..102b3d08a6 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/semaphoremp.h @@ -0,0 +1,161 @@ +/* semaphoremp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the POSIX Semaphore Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_SEMAPHORE_MP_h +#define __RTEMS_POSIX_SEMAPHORE_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote semaphore operations. + */ + +typedef enum { + POSIX_SEMAPHORE_MP_ANNOUNCE_CREATE = 0, + POSIX_SEMAPHORE_MP_ANNOUNCE_DELETE = 1, + POSIX_SEMAPHORE_MP_EXTRACT_PROXY = 2, + POSIX_SEMAPHORE_MP_OBTAIN_REQUEST = 3, + POSIX_SEMAPHORE_MP_OBTAIN_RESPONSE = 4, + POSIX_SEMAPHORE_MP_RELEASE_REQUEST = 5, + POSIX_SEMAPHORE_MP_RELEASE_RESPONSE = 6, +} POSIX_Semaphore_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote semaphore operations. + */ + +typedef struct { + MP_packet_Prefix Prefix; + POSIX_Semaphore_MP_Remote_operations operation; + Objects_Name name; + boolean wait; /* XXX options */ + Objects_Id proxy_id; +} POSIX_Semaphore_MP_Packet; + +/* + * _POSIX_Semaphore_MP_Send_process_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ + +void _POSIX_Semaphore_MP_Send_process_packet ( + POSIX_Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _POSIX_Semaphore_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +int _POSIX_Semaphore_MP_Send_request_packet ( + POSIX_Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + boolean wait, /* XXX options */ + Watchdog_Interval timeout +); + +/* + * _POSIX_Semaphore_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _POSIX_Semaphore_MP_Send_response_packet ( + POSIX_Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Thread_Control *the_thread +); + +/* + * + * _POSIX_Semaphore_MP_Process_packet + * + * DESCRIPTION: + * + * This routine performs the actions specific to this package for + * the request from another node. + */ + +void _POSIX_Semaphore_MP_Process_packet ( + MP_packet_Prefix *the_packet_prefix +); + +/* + * _POSIX_Semaphore_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * This routine is invoked indirectly by the thread queue + * when a proxy has been removed from the thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Semaphore_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +); + +/* + * _POSIX_Semaphore_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * This routine is invoked when a task is deleted and it + * has a proxy which must be removed from a thread queue and + * the remote node must be informed of this. + */ + +void _POSIX_Semaphore_MP_Send_extract_proxy ( + Thread_Control *the_thread +); + +/* + * _POSIX_Semaphore_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a semaphore mp packet. + */ + +POSIX_Semaphore_MP_Packet *_POSIX_Semaphore_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h new file mode 100644 index 0000000000..39a3c9d51a --- /dev/null +++ b/cpukit/posix/include/rtems/posix/threadsup.h @@ -0,0 +1,29 @@ +/* threadsup.h + * + */ + +#ifndef __RTEMS_POSIX_THREAD_SUPPORT_h +#define __RTEMS_POSIX_THREAD_SUPPORT_h + +#include + +typedef struct { + /* + * POSIX Interrupts + */ + unsigned32 interrupts_installed; + CORE_semaphore_Control Interrupt_Semaphore; + + /* + * POSIX Cancelability + */ + int cancelability_state; + int cancelability_type; + int cancelation_requested; + Chain_Control Cancellation_Handlers; + +} POSIX_API_Thread_Support_Control; + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/rtems/posix/time.h b/cpukit/posix/include/rtems/posix/time.h new file mode 100644 index 0000000000..0b11f2fa54 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/time.h @@ -0,0 +1,14 @@ +/* + * + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_TIME_h +#define __RTEMS_POSIX_TIME_h + +Watchdog_Interval _POSIX_Time_Spec_to_interval( + const struct timespec *time +); + +#endif diff --git a/cpukit/posix/include/sched.h b/cpukit/posix/include/sched.h new file mode 100644 index 0000000000..415663db6c --- /dev/null +++ b/cpukit/posix/include/sched.h @@ -0,0 +1,87 @@ +/* sched.h + * + */ + + +#ifndef __POSIX_SCHEDULING_h +#define __POSIX_SCHEDULING_h + +#include + +#if defined(_POSIX_PRIORITY_SCHEDULING) + +#include +#include +#include +#include + +/* + * 13.3.1 Set Scheduling Parameters, P1003.1b-1993, p. 252 + * + */ + +int sched_setparam( + pid_t pid, + const struct sched_param *param +); + +/* + * 13.3.2 Set Scheduling Parameters, P1003.1b-1993, p. 253 + */ + +int sched_getparam( + pid_t pid, + const struct sched_param *param +); + +/* + * 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 +); + +/* + * 13.3.4 Get Scheduling Policy, P1003.1b-1993, p. 256 + */ + +int sched_getscheduler( + pid_t pid +); + +/* + * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258 + */ + +int sched_get_priority_max( + int policy +); + +int sched_get_priority_min( + int policy +); + +int sched_rr_get_interval( + pid_t pid, + struct timespec *interval +); + +#endif /* _POSIX_PRIORITY_SCHEDULING */ + +#if defined(_POSIX_THREADS) || defined(_POSIX_PRIORITY_SCHEDULING) + +/* + * 13.3.5 Yield Processor, P1003.1b-1993, p. 257 + */ + +int sched_yield( void ); + +#endif /* _POSIX_THREADS or _POSIX_PRIORITY_SCHEDULING */ + +#endif +/* end of include file */ + diff --git a/cpukit/posix/include/semaphore.h b/cpukit/posix/include/semaphore.h new file mode 100644 index 0000000000..fed03f7da3 --- /dev/null +++ b/cpukit/posix/include/semaphore.h @@ -0,0 +1,107 @@ +/* semaphore.h + * + */ + +#ifndef __POSIX_SEMAPHORE_h +#define __POSIX_SEMAPHORE_h + +#include + +#if defined(_POSIX_SEMAPHORES) + +#include + +/* + * 11.1 Semaphore Characteristics, P1003.1b-1993, p.219 + */ + +typedef int sem_t; + +/* + * 11.2.1 Initialize an Unnamed Semaphore, P1003.1b-1993, p.219 + */ + +int sem_init( + sem_t *sem, + int pshared, + unsigned int value +); + +/* + * 11.2.2 Destroy an Unnamed Semaphore, P1003.1b-1993, p.220 + */ + +int sem_destroy( + sem_t *sem +); + +/* + * 11.2.3 Initialize/Open a Named Semaphore, P1003.1b-1993, p.221 + * + * NOTE: Follows open() calling conventions. + */ + +sem_t *sem_open( + const char *name, + int oflag, + ... +); + +/* + * 11.2.4 Close a Named Semaphore, P1003.1b-1993, p.224 + */ + +int sem_close( + sem_t *sem +); + +/* + * 11.2.5 Remove a Named Semaphore, P1003.1b-1993, p.225 + */ + +int sem_unlink( + const char *name +); + +/* + * 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 +); + +int sem_trywait( + sem_t *sem +); + +#if defined(_POSIX_TIMEOUTS) +int sem_timedwait( + sem_t *sem, + const struct timespec *timeout +); +#endif + +/* + * 11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227 + */ + +int sem_post( + sem_t *sem +); + +/* + * 11.2.8 Get the Value of a Semaphore, P1003.1b-1993, p.229 + */ + +int sem_getvalue( + sem_t *sem, + int *sval +); + +#endif /* _POSIX_SEMAPHORES */ + +#endif +/* end of include file */ diff --git a/cpukit/posix/inline/rtems/posix/cond.inl b/cpukit/posix/inline/rtems/posix/cond.inl new file mode 100644 index 0000000000..f6d55af7c6 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/cond.inl @@ -0,0 +1,76 @@ +/* rtems/posix/cond.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX condition variables. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_CONDITION_VARIABLES_inl +#define __RTEMS_POSIX_CONDITION_VARIABLES_inl + +/*PAGE + * + * _POSIX_Condition_variables_Allocate + */ + +STATIC INLINE POSIX_Condition_variables_Control + *_POSIX_Condition_variables_Allocate( void ) +{ + return (POSIX_Condition_variables_Control *) + _Objects_Allocate( &_POSIX_Condition_variables_Information ); +} + +/*PAGE + * + * _POSIX_Condition_variables_Free + */ + +STATIC INLINE void _POSIX_Condition_variables_Free ( + POSIX_Condition_variables_Control *the_condition_variable +) +{ + _Objects_Free( + &_POSIX_Condition_variables_Information, + &the_condition_variable->Object + ); +} + +/*PAGE + * + * _POSIX_Condition_variables_Get + */ + +STATIC INLINE POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get ( + Objects_Id *id, + Objects_Locations *location +) +{ +/* XXX really should validate pointer */ + return (POSIX_Condition_variables_Control *) + _Objects_Get( &_POSIX_Condition_variables_Information, *id, location ); +} + +/*PAGE + * + * _POSIX_Condition_variables_Is_null + */ + +STATIC INLINE boolean _POSIX_Condition_variables_Is_null ( + POSIX_Condition_variables_Control *the_condition_variable +) +{ + return !the_condition_variable; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/intr.inl b/cpukit/posix/inline/rtems/posix/intr.inl new file mode 100644 index 0000000000..56b1c9dd0b --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/intr.inl @@ -0,0 +1,72 @@ +/* rtems/posix/intr.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Interrupt Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_INTERRUPT_inl +#define __RTEMS_POSIX_INTERRUPT_inl + +/*PAGE + * + * _POSIX_Interrupt_Allocate + */ + +STATIC INLINE POSIX_Interrupt_Handler_control * + _POSIX_Interrupt_Allocate( void ) +{ + return (POSIX_Interrupt_Handler_control *) + _Objects_Allocate( &_POSIX_Interrupt_Handlers_Information ); +} + +/*PAGE + * + * _POSIX_Interrupt_Free + */ + +STATIC INLINE void _POSIX_Interrupt_Free ( + POSIX_Interrupt_Handler_control *the_intr +) +{ + _Objects_Free( &_POSIX_Interrupt_Handlers_Information, &the_intr->Object ); +} + +/*PAGE + * + * _POSIX_Interrupt_Get + */ + +STATIC INLINE POSIX_Interrupt_Control *_POSIX_Interrupt_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (POSIX_Interrupt_Control *) + _Objects_Get( &_POSIX_Interrupt_Handlers_Information, id, location ); +} + +/*PAGE + * + * _POSIX_Interrupt_Is_null + */ + +STATIC INLINE boolean _POSIX_Interrupt_Is_null ( + POSIX_Interrupt_Handler_control *the_intr +) +{ + return !the_intr; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/key.inl b/cpukit/posix/inline/rtems/posix/key.inl new file mode 100644 index 0000000000..3b9c1e9e3c --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/key.inl @@ -0,0 +1,70 @@ +/* rtems/posix/key.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX key's. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_KEY_inl +#define __RTEMS_POSIX_KEY_inl + +/*PAGE + * + * _POSIX_Keys_Allocate + */ + +STATIC INLINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void ) +{ + return (POSIX_Keys_Control *) _Objects_Allocate( &_POSIX_Keys_Information ); +} + +/*PAGE + * + * _POSIX_Keys_Free + */ + +STATIC INLINE void _POSIX_Keys_Free ( + POSIX_Keys_Control *the_key +) +{ + _Objects_Free( &_POSIX_Keys_Information, &the_key->Object ); +} + +/*PAGE + * + * _POSIX_Keys_Get + */ + +STATIC INLINE POSIX_Keys_Control *_POSIX_Keys_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (POSIX_Keys_Control *) + _Objects_Get( &_POSIX_Keys_Information, id, location ); +} + +/*PAGE + * + * _POSIX_Keys_Is_null + */ + +STATIC INLINE boolean _POSIX_Keys_Is_null ( + POSIX_Keys_Control *the_key +) +{ + return !the_key; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/mqueue.inl b/cpukit/posix/inline/rtems/posix/mqueue.inl new file mode 100644 index 0000000000..140a37a6a6 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/mqueue.inl @@ -0,0 +1,83 @@ +/* rtems/posix/mqueue.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Message Queue. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_MESSAGE_QUEUE_inl +#define __RTEMS_POSIX_MESSAGE_QUEUE_inl + +/*PAGE + * + * _POSIX_Message_queue_Allocate + */ + +STATIC INLINE POSIX_Message_queue_Control *_POSIX_Message_queue_Allocate( void ) +{ + return (POSIX_Message_queue_Control *) + _Objects_Allocate( &_POSIX_Message_queue_Information ); +} + +/*PAGE + * + * _POSIX_Message_queue_Free + */ + +STATIC INLINE void _POSIX_Message_queue_Free ( + POSIX_Message_queue_Control *the_mq +) +{ + _Objects_Free( &_POSIX_Message_queue_Information, &the_mq->Object ); +} + +/*PAGE + * + * _POSIX_Message_queue_Get + */ + +STATIC INLINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (POSIX_Message_queue_Control *) + _Objects_Get( &_POSIX_Message_queue_Information, id, location ); +} + +/*PAGE + * + * _POSIX_Message_queue_Is_null + */ + +STATIC INLINE boolean _POSIX_Message_queue_Is_null ( + POSIX_Message_queue_Control *the_mq +) +{ + return !the_mq; +} + +/*PAGE + * + * _POSIX_Message_queue_Priority_to_core + */ + +STATIC INLINE Priority_Control _POSIX_Message_queue_Priority_to_core( + unsigned int priority +) +{ + return priority; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/mutex.inl b/cpukit/posix/inline/rtems/posix/mutex.inl new file mode 100644 index 0000000000..f663eb3c7d --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/mutex.inl @@ -0,0 +1,88 @@ +/* rtems/posix/mutex.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX mutex's. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_MUTEX_inl +#define __RTEMS_POSIX_MUTEX_inl + +/*PAGE + * + * _POSIX_Mutex_Allocate + */ + +STATIC INLINE POSIX_Mutex_Control *_POSIX_Mutex_Allocate( void ) +{ + return (POSIX_Mutex_Control *) _Objects_Allocate( &_POSIX_Mutex_Information ); +} + +/*PAGE + * + * _POSIX_Mutex_Free + */ + +STATIC INLINE void _POSIX_Mutex_Free ( + POSIX_Mutex_Control *the_mutex +) +{ + _Objects_Free( &_POSIX_Mutex_Information, &the_mutex->Object ); +} + +/*PAGE + * + * _POSIX_Mutex_Get + */ + +STATIC INLINE POSIX_Mutex_Control *_POSIX_Mutex_Get ( + Objects_Id *id, + Objects_Locations *location +) +{ + int status; + + if ( *id == PTHREAD_MUTEX_INITIALIZER ) { + /* + * Do an "auto-create" here. + */ + + status = pthread_mutex_init( id, 0 ); + if ( status ) { + *location = OBJECTS_ERROR; + return (POSIX_Mutex_Control *) 0; + } + } + + /* + * Now call Objects_Get() + */ + + return (POSIX_Mutex_Control *) + _Objects_Get( &_POSIX_Mutex_Information, *id, location ); +} + +/*PAGE + * + * _POSIX_Mutex_Is_null + */ + +STATIC INLINE boolean _POSIX_Mutex_Is_null ( + POSIX_Mutex_Control *the_mutex +) +{ + return !the_mutex; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/priority.inl b/cpukit/posix/inline/rtems/posix/priority.inl new file mode 100644 index 0000000000..2a61181d46 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/priority.inl @@ -0,0 +1,26 @@ + +#ifndef __RTEMS_POSIX_PRIORITY_inl +#define __RTEMS_POSIX_PRIORITY_inl + +STATIC INLINE boolean _POSIX_Priority_Is_valid( + int priority +) +{ + return (boolean) priority >= 1 && priority <= 255; +} + +STATIC INLINE Priority_Control _POSIX_Priority_To_core( + int priority +) +{ + return (Priority_Control) 256 - priority; +} + +STATIC INLINE int _POSIX_Priority_From_core( + Priority_Control priority +) +{ + return 256 - priority; +} + +#endif diff --git a/cpukit/posix/inline/rtems/posix/pthread.inl b/cpukit/posix/inline/rtems/posix/pthread.inl new file mode 100644 index 0000000000..256372d326 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/pthread.inl @@ -0,0 +1,71 @@ +/* rtems/posix/pthread.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX threads. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_THREADS_inl +#define __RTEMS_POSIX_THREADS_inl + +/*PAGE + * + * _POSIX_Threads_Allocate + */ + +STATIC INLINE POSIX_Threads_Control *_POSIX_Threads_Allocate( void ) +{ + return (POSIX_Threads_Control *) + _Objects_Allocate( &_POSIX_Threads_Information ); +} + +/*PAGE + * + * _POSIX_Threads_Free + */ + +STATIC INLINE void _POSIX_Threads_Free ( + POSIX_Threads_Control *the_pthread +) +{ + _Objects_Free( &_POSIX_Threads_Information, &the_pthread->Object ); +} + +/*PAGE + * + * _POSIX_Threads_Get + */ + +STATIC INLINE POSIX_Threads_Control *_POSIX_Threads_Get ( + Objects_Id *id, + Objects_Locations *location +) +{ + return (POSIX_Threads_Control *) + _Objects_Get( &_POSIX_Threads_Information, *id, location ); +} + +/*PAGE + * + * _POSIX_Threads_Is_null + */ + +STATIC INLINE boolean _POSIX_Threads_Is_null ( + POSIX_Threads_Control *the_pthread +) +{ + return !the_pthread; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/semaphore.inl b/cpukit/posix/inline/rtems/posix/semaphore.inl new file mode 100644 index 0000000000..33af0bd000 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/semaphore.inl @@ -0,0 +1,71 @@ +/* rtems/posix/semaphore.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Semaphores. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_POSIX_SEMAPHORE_inl +#define __RTEMS_POSIX_SEMAPHORE_inl + +/*PAGE + * + * _POSIX_Semaphore_Allocate + */ + +STATIC INLINE POSIX_Semaphore_Control *_POSIX_Semaphore_Allocate( void ) +{ + return (POSIX_Semaphore_Control *) + _Objects_Allocate( &_POSIX_Semaphore_Information ); +} + +/*PAGE + * + * _POSIX_Semaphore_Free + */ + +STATIC INLINE void _POSIX_Semaphore_Free ( + POSIX_Semaphore_Control *the_semaphore +) +{ + _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object ); +} + +/*PAGE + * + * _POSIX_Semaphore_Get + */ + +STATIC INLINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get ( + Objects_Id *id, + Objects_Locations *location +) +{ + return (POSIX_Semaphore_Control *) + _Objects_Get( &_POSIX_Semaphore_Information, *id, location ); +} + +/*PAGE + * + * _POSIX_Semaphore_Is_null + */ + +STATIC INLINE boolean _POSIX_Semaphore_Is_null ( + POSIX_Semaphore_Control *the_semaphore +) +{ + return !the_semaphore; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/src/aio.c b/cpukit/posix/src/aio.c new file mode 100644 index 0000000000..dab31c108f --- /dev/null +++ b/cpukit/posix/src/aio.c @@ -0,0 +1,112 @@ +/* aio.c + * + */ + +#include + +#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/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c new file mode 100644 index 0000000000..32a9a90890 --- /dev/null +++ b/cpukit/posix/src/cancel.c @@ -0,0 +1,226 @@ +/* cancel.c + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*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/cpukit/posix/src/cond.c b/cpukit/posix/src/cond.c new file mode 100644 index 0000000000..061353e858 --- /dev/null +++ b/cpukit/posix/src/cond.c @@ -0,0 +1,398 @@ +/* cond.c + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +/*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/cpukit/posix/src/devctl.c b/cpukit/posix/src/devctl.c new file mode 100644 index 0000000000..e4ff6d3cd8 --- /dev/null +++ b/cpukit/posix/src/devctl.c @@ -0,0 +1,24 @@ +/* devctl.c + * + */ + +#include + +#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/cpukit/posix/src/intr.c b/cpukit/posix/src/intr.c new file mode 100644 index 0000000000..4011cf9a91 --- /dev/null +++ b/cpukit/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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * _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/cpukit/posix/src/key.c b/cpukit/posix/src/key.c new file mode 100644 index 0000000000..b92a976c55 --- /dev/null +++ b/cpukit/posix/src/key.c @@ -0,0 +1,259 @@ +/* key.c + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* + * _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/cpukit/posix/src/mqueue.c b/cpukit/posix/src/mqueue.c new file mode 100644 index 0000000000..f531b94754 --- /dev/null +++ b/cpukit/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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/*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/cpukit/posix/src/mutex.c b/cpukit/posix/src/mutex.c new file mode 100644 index 0000000000..5473d4183c --- /dev/null +++ b/cpukit/posix/src/mutex.c @@ -0,0 +1,569 @@ +/* mutex.c + * + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +/*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/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c new file mode 100644 index 0000000000..48701c3880 --- /dev/null +++ b/cpukit/posix/src/psignal.c @@ -0,0 +1,261 @@ +/* signal.c + * + */ + +#include + +#include + +#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/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c new file mode 100644 index 0000000000..ee1903c3ff --- /dev/null +++ b/cpukit/posix/src/pthread.c @@ -0,0 +1,552 @@ +/* pthread.c + * + */ + +#include +#include +#include + +#include +#include +#include + +/*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/cpukit/posix/src/sched.c b/cpukit/posix/src/sched.c new file mode 100644 index 0000000000..230fe5dbbb --- /dev/null +++ b/cpukit/posix/src/sched.c @@ -0,0 +1,126 @@ +/* sched.c + * + */ + +#include +#include +#include +#include + +#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/cpukit/posix/src/semaphore.c b/cpukit/posix/src/semaphore.c new file mode 100644 index 0000000000..16d44d1894 --- /dev/null +++ b/cpukit/posix/src/semaphore.c @@ -0,0 +1,575 @@ +/* semaphore.c + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/*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/cpukit/posix/src/time.c b/cpukit/posix/src/time.c new file mode 100644 index 0000000000..fb99848c67 --- /dev/null +++ b/cpukit/posix/src/time.c @@ -0,0 +1,192 @@ +/* time.c + * + */ + +#include +#include + +/* + * 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/cpukit/posix/src/types.c b/cpukit/posix/src/types.c new file mode 100644 index 0000000000..34b0905e04 --- /dev/null +++ b/cpukit/posix/src/types.c @@ -0,0 +1,167 @@ +/* types.c + * + */ + +#include + +#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 -- cgit v1.2.3