diff options
Diffstat (limited to 'cpukit/posix')
269 files changed, 19346 insertions, 0 deletions
diff --git a/cpukit/posix/.cvsignore b/cpukit/posix/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/cpukit/posix/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am new file mode 100644 index 0000000000..34e1cfa0ab --- /dev/null +++ b/cpukit/posix/Makefile.am @@ -0,0 +1,195 @@ +## +## $Id$ +## + +include $(top_srcdir)/automake/multilib.am +include $(top_srcdir)/automake/compile.am + +EXTRA_DIST = + +AM_CPPFLAGS += -D__RTEMS_INSIDE__ + +noinst_LIBRARIES = libposix.a +libposix_a_CPPFLAGS = $(AM_CPPFLAGS) +libposix_a_SOURCES = + +# Some POSIX functions that are nice to always have +libposix_a_SOURCES += src/nanosleep.c src/clockgettime.c src/clocksettime.c \ + src/clockgetres.c src/sysconf.c + +include_rtems_posixdir = $(includedir)/rtems/posix + +include_rtems_posix_HEADERS = include/rtems/posix/sigset.h + +if HAS_PTHREADS +# include +include_HEADERS = include/aio.h include/mqueue.h \ + include/semaphore.h + +# include/rtems/posix +include_rtems_posix_HEADERS += include/rtems/posix/aio_misc.h + +include_rtems_posix_HEADERS += include/rtems/posix/cancel.h \ + include/rtems/posix/cond.h include/rtems/posix/config.h \ + include/rtems/posix/key.h include/rtems/posix/mqueue.h \ + include/rtems/posix/mutex.h include/rtems/posix/posixapi.h \ + include/rtems/posix/priority.h include/rtems/posix/psignal.h \ + include/rtems/posix/pthread.h include/rtems/posix/ptimer.h \ + include/rtems/posix/semaphore.h include/rtems/posix/threadsup.h \ + include/rtems/posix/time.h include/rtems/posix/timer.h \ + include/rtems/posix/barrier.h include/rtems/posix/rwlock.h \ + include/rtems/posix/spinlock.h + +include_rtems_posix_HEADERS += inline/rtems/posix/cond.inl \ + inline/rtems/posix/key.inl inline/rtems/posix/mqueue.inl \ + inline/rtems/posix/mutex.inl inline/rtems/posix/pthread.inl \ + inline/rtems/posix/priority.inl inline/rtems/posix/semaphore.inl \ + inline/rtems/posix/timer.inl inline/rtems/posix/barrier.inl \ + inline/rtems/posix/rwlock.inl inline/rtems/posix/spinlock.inl + +## src +libposix_a_SOURCES += src/aio_cancel.c src/aio_error.c src/aio_fsync.c \ + src/aio_read.c src/aio_return.c src/aio_suspend.c src/aio_write.c \ + src/lio_listio.c src/aio_misc.c + +## ENOSYS_C_FILES +libposix_a_SOURCES += src/_execve.c src/execl.c src/execle.c src/execlp.c \ + src/execv.c src/execve.c src/execvp.c +endif + +libposix_a_SOURCES += src/fork.c src/vfork.c + +libposix_a_SOURCES += src/wait.c src/waitpid.c + +if HAS_PTHREADS +libposix_a_SOURCES += src/pthreadatfork.c + +## BARRIER_C_FILES +libposix_a_SOURCES += src/barrierattrdestroy.c src/barrierattrgetpshared.c \ + src/barrierattrinit.c src/barrierattrsetpshared.c src/pbarrier.c \ + src/pbarrierdestroy.c src/pbarrierinit.c \ + src/pbarriertranslatereturncode.c src/pbarrierwait.c + +## CANCEL_C_FILES +libposix_a_SOURCES += src/cancel.c src/canceleval.c src/cancelrun.c \ + src/cleanuppop.c src/cleanuppush.c src/setcancelstate.c \ + src/setcanceltype.c src/testcancel.c + +## CONDITION_VARIABLE_C_FILES +libposix_a_SOURCES += src/cond.c src/condattrdestroy.c \ + src/condattrgetpshared.c src/condattrinit.c src/condattrsetpshared.c \ + src/condbroadcast.c src/conddefaultattributes.c src/conddestroy.c \ + src/condinit.c src/condsignal.c src/condsignalsupp.c \ + src/condtimedwait.c src/condwait.c src/condwaitsupp.c src/condget.c + +## KEY_C_FILES +libposix_a_SOURCES += src/key.c src/keycreate.c src/keydelete.c \ + src/keygetspecific.c src/keyfreememory.c src/keyrundestructors.c \ + src/keysetspecific.c + +## MEMORY_C_FILES +libposix_a_SOURCES += src/mprotect.c + +## MESSAGE_QUEUE_C_FILES +libposix_a_SOURCES += src/mqueue.c src/mqueueclose.c \ + src/mqueuecreatesupp.c src/mqueuedeletesupp.c src/mqueuegetattr.c \ + src/mqueuenametoid.c src/mqueuenotify.c src/mqueueopen.c \ + src/mqueuereceive.c src/mqueuerecvsupp.c src/mqueuesend.c \ + src/mqueuesendsupp.c src/mqueuesetattr.c src/mqueuetimedreceive.c \ + src/mqueuetimedsend.c src/mqueuetranslatereturncode.c \ + src/mqueueunlink.c + +## MUTEX_C_FILES +libposix_a_SOURCES += src/mutexattrdestroy.c src/mutexattrgetprioceiling.c \ + src/mutexattrgetprotocol.c src/mutexattrgetpshared.c \ + src/mutexattrgettype.c src/mutexattrinit.c src/mutexattrsetprioceiling.c \ + src/mutexattrsetprotocol.c src/mutexattrsetpshared.c \ + src/mutexattrsettype.c src/mutex.c src/mutexdestroy.c src/mutexget.c \ + src/mutexgetprioceiling.c src/mutexinit.c src/mutexlock.c \ + src/mutexlocksupp.c src/mutexsetprioceiling.c src/mutextimedlock.c \ + src/mutextranslatereturncode.c src/mutextrylock.c src/mutexunlock.c + +## PTHREAD_C_FILES +libposix_a_SOURCES += src/pthreadatfork.c src/pthreadattrdestroy.c \ + src/pthreadattrgetdetachstate.c src/pthreadattrgetinheritsched.c \ + src/pthreadattrgetschedparam.c src/pthreadattrgetschedpolicy.c \ + src/pthreadattrgetscope.c src/pthreadattrgetstackaddr.c \ + src/pthreadattrgetstack.c src/pthreadattrgetstacksize.c \ + src/pthreadattrinit.c src/pthreadattrsetdetachstate.c \ + src/pthreadattrsetguardsize.c src/pthreadattrsetinheritsched.c \ + src/pthreadattrsetschedparam.c src/pthreadattrsetschedpolicy.c \ + src/pthreadattrsetscope.c src/pthreadattrsetstackaddr.c \ + src/pthreadattrsetstack.c src/pthreadattrsetstacksize.c \ + src/pthreadattrgetguardsize.c src/pthread.c \ + src/pthreadcreate.c src/pthreaddetach.c src/pthreadequal.c \ + src/pthreadexit.c src/pthreadgetcpuclockid.c \ + src/pthreadgetcputime.c src/pthreadgetschedparam.c \ + src/pthreadinitthreads.c src/pthreadjoin.c src/pthreadkill.c \ + src/pthreadonce.c src/pthreadself.c src/pthreadsetcputime.c \ + src/pthreadsetschedparam.c src/pthreadsigmask.c \ + src/psxpriorityisvalid.c src/psxtransschedparam.c + +## PSIGNAL_C_FILES +libposix_a_SOURCES += src/psignal.c src/alarm.c src/kill.c src/killinfo.c \ + src/kill_r.c src/pause.c src/psignalclearprocesssignals.c \ + src/psignalsetprocesssignals.c src/psignalchecksignal.c \ + src/psignalclearsignals.c src/psignalunblockthread.c src/pthreadkill.c \ + src/pthreadsigmask.c src/sigaction.c +endif + +libposix_a_SOURCES += src/sigaddset.c src/sigdelset.c src/sigfillset.c \ + src/sigemptyset.c src/sigismember.c + +libposix_a_SOURCES += src/sigprocmask.c + +if HAS_PTHREADS +libposix_a_SOURCES += src/sigpending.c \ + src/sigqueue.c src/sigsuspend.c src/sigtimedwait.c \ + src/sigwait.c src/sigwaitinfo.c src/signal_2.c src/ualarm.c + +## RWLOCK_C_FILES +libposix_a_SOURCES += src/prwlock.c src/prwlockdestroy.c src/prwlockinit.c \ + src/prwlockrdlock.c src/prwlocktimedrdlock.c src/prwlocktimedwrlock.c \ + src/prwlocktryrdlock.c src/prwlocktrywrlock.c src/prwlockunlock.c \ + src/prwlockwrlock.c src/rwlockattrdestroy.c src/rwlockattrgetpshared.c \ + src/rwlockattrinit.c src/rwlockattrsetpshared.c \ + src/prwlocktranslatereturncode.c + +## SEMAPHORE_C_FILES +libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \ + src/semaphoredeletesupp.c src/semaphorenametoid.c \ + src/semaphoretranslatereturncode.c src/semaphorewaitsupp.c \ + src/semclose.c src/semdestroy.c src/semgetvalue.c src/seminit.c \ + src/semopen.c src/sempost.c src/semtimedwait.c src/semtrywait.c \ + src/semunlink.c src/semwait.c + +## SPINLOCK_C_FILES +libposix_a_SOURCES += src/pspin.c src/pspindestroy.c src/pspininit.c \ + src/pspinlock.c src/pspinlocktranslatereturncode.c src/pspintrylock.c \ + src/pspinunlock.c + +## TIME_C_FILES +libposix_a_SOURCES += src/adjtime.c src/posixtimespecabsolutetimeout.c \ + src/clockgetcpuclockid.c src/clockgetenableattr.c src/clocksetenableattr.c + +## TIMER_C_FILES +libposix_a_SOURCES += src/ptimer.c src/timercreate.c src/timerdelete.c \ + src/timergetoverrun.c src/timergettime.c src/timersettime.c \ + src/timertsr.c src/timerinserthelper.c + +## ITIMER_C_FILES +libposix_a_SOURCES += src/getitimer.c src/setitimer.c + +## SUPPORT_C_FILES +libposix_a_SOURCES += src/psxpriorityisvalid.c + +EXTRA_DIST += src/README.mqueue + +libposix_a_SOURCES += src/sched_getparam.c src/sched_getprioritymax.c \ + src/sched_getprioritymin.c src/sched_getscheduler.c \ + src/sched_rr_get_interval.c src/sched_setparam.c \ + src/sched_setscheduler.c src/sched_yield.c +endif + +include $(srcdir)/preinstall.am +include $(top_srcdir)/automake/local.am diff --git a/cpukit/posix/include/aio.h b/cpukit/posix/include/aio.h new file mode 100644 index 0000000000..becb4abb86 --- /dev/null +++ b/cpukit/posix/include/aio.h @@ -0,0 +1,167 @@ +/** + * @file aio.h + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _AIO_H +#define _AIO_H + +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_POSIX_ASYNCHRONOUS_IO) + +/* + * 6.7.1 Data Definitions for Asynchronous Input and Output, + * P1003.1b-1993, p. 151 + */ + +#include <sys/types.h> +#include <signal.h> +#include <time.h> +#include <fcntl.h> + +/* + * 6.7.1.2 Manifest Constants, P1003.1b-1993, p. 153 + */ + +#define AIO_CANCELED 0 /* all requested operations have been canceled */ +#define AIO_NOTCANCELED 1 /* some of the operations could not be canceled */ + /* since they are in progress */ +#define AIO_ALLDONE 2 /* none of the requested operations could be */ + /* canceled since they are already complete */ + +/* lio_listio() options */ + +/* + * LIO modes + */ +#define LIO_WAIT 0 /* calling process is to suspend until the */ + /* operation is complete */ +#define LIO_NOWAIT 1 /* calling process is to continue execution while */ + /* the operation is performed and no notification */ + /* shall be given when the operation is completed */ + +/* + * LIO opcodes + */ +#define LIO_NOP 0 /* no transfer is requested */ +#define LIO_READ 1 /* request a read() */ +#define LIO_WRITE 2 /* request a write() */ +#define LIO_SYNC 3 /* needed by aio_fsync() */ + +/* + * 6.7.1.1 Asynchronous I/O Control Block, P1003.1b-1993, p. 151 + */ + +struct aiocb { + /* public */ + 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 aio_lio_opcode; /* Operation to be performed */ + /* private */ + int error_code; /* Used for aio_error() */ + ssize_t return_value; /* Used for aio_return() */ +}; + +/* + * 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 + */ + +ssize_t 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( + const 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 */ + +#ifdef __cplusplus +} +#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..f08dc0754b --- /dev/null +++ b/cpukit/posix/include/mqueue.h @@ -0,0 +1,172 @@ +/** + * @file mqueue.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _MQUEUE_H +#define _MQUEUE_H + + +#include <unistd.h> + +#if defined(_POSIX_MESSAGE_PASSING) + +#include <sys/types.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 15.1.1 Data Structures, P1003.1b-1993, p. 271 + */ + +/** + * Message queue id type. + * + * @note Use uint32_t since all POSIX Ids are 32-bit currently. + */ +typedef uint32_t mqd_t; + +/** + * This is the message queue attributes structure. + */ +struct mq_attr { + /** This is the message queue flags */ + long mq_flags; + /** This is the maximum number of messages */ + long mq_maxmsg; + /** This is the maximum message size */ + long mq_msgsize; + /** This is the mumber of messages currently queued */ + long mq_curmsgs; +}; + +/** + * 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 <time.h> + +int mq_timedsend( + mqd_t mqdes, + const char *msg_ptr, + size_t msg_len, + unsigned int msg_prio, + const struct timespec *abstime +); + +#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) + +ssize_t mq_timedreceive( + mqd_t mqdes, + char *msg_ptr, + size_t msg_len, + unsigned int *msg_prio, + const struct timespec *abstime +); + +#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 +); + +#ifdef __cplusplus +} +#endif + +#endif /* _POSIX_MESSAGE_PASSING */ + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/aio_misc.h b/cpukit/posix/include/rtems/posix/aio_misc.h new file mode 100644 index 0000000000..c90d509d44 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/aio_misc.h @@ -0,0 +1,108 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + + +#ifndef _AIO_MISC_H +#define _AIO_MISC_H + +#include <stdio.h> +#include <string.h> +#include <aio.h> +#include <pthread.h> +#include <rtems.h> +#include <rtems/chain.h> +#include <rtems/system.h> +#include <rtems/seterr.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Actual request being processed */ + typedef struct + { + rtems_chain_node next_prio; /* chain requests in order of priority */ + int policy; /* If _POSIX_PRIORITIZED_IO and + _POSIX_PRIORITY_SCHEDULING are defined */ + int priority; /* see above */ + pthread_t caller_thread; /* used for notification */ + struct aiocb *aiocbp; /* aio control block */ + } rtems_aio_request; + + typedef struct + { + rtems_chain_node next_fd; /* order fd chains in queue */ + rtems_chain_control perfd; /* chain of requests for this fd */ + int fildes; /* file descriptor to be processed */ + int new_fd; /* if this is a newly created chain */ + pthread_mutex_t mutex; + pthread_cond_t cond; + + } rtems_aio_request_chain; + + typedef struct + { + pthread_mutex_t mutex; + pthread_cond_t new_req; + pthread_attr_t attr; + + rtems_chain_control work_req; /* chains being worked by active threads */ + rtems_chain_control idle_req; /* fd chains waiting to be processed */ + unsigned int initialized; /* specific value if queue is initialized */ + int active_threads; /* the number of active threads */ + int idle_threads; /* number of idle threads */ + + } rtems_aio_queue; + +extern rtems_aio_queue aio_request_queue; + +#define AIO_QUEUE_INITIALIZED 0xB00B + +#ifndef AIO_MAX_THREADS +#define AIO_MAX_THREADS 5 +#endif + +#ifndef AIO_MAX_QUEUE_SIZE +#define AIO_MAX_QUEUE_SIZE 30 +#endif + +int rtems_aio_init (void); +int rtems_aio_enqueue (rtems_aio_request *req); +rtems_aio_request_chain *rtems_aio_search_fd +( + rtems_chain_control *chain, + int fildes, + int create +); +void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain); +int rtems_aio_remove_req (rtems_chain_control *chain, + struct aiocb *aiocbp); + +#ifdef RTEMS_DEBUG +#include <assert.h> + +#define AIO_assert(_x) assert(_x) +#define AIO_printf(_x) printf(_x) +#else +#define AIO_assert(_x) +#define AIO_printf(_x) +#endif + +#define rtems_aio_set_errno_return_minus_one( _error, _aiocbp ) \ + do { (_aiocbp)->error_code = (_error); \ + (_aiocbp)->return_value = -1; \ + rtems_set_errno_and_return_minus_one (_error);} while(0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/posix/include/rtems/posix/barrier.h b/cpukit/posix/include/rtems/posix/barrier.h new file mode 100644 index 0000000000..6bb2aa2e5c --- /dev/null +++ b/cpukit/posix/include/rtems/posix/barrier.h @@ -0,0 +1,88 @@ +/** + * @file rtems/posix/barrier.h + */ + +/* + * This include file contains all the constants and structures associated + * with the POSIX Barrier Manager. + * + * Directives provided are: + * + * + create a barrier + * + delete a barrier + * + wait for a barrier + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_BARRIER_H +#define _RTEMS_POSIX_BARRIER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/score/corebarrier.h> + +/** + * This type defines the control block used to manage each barrier. + */ + +typedef struct { + /** This is used to manage a barrier as an object. */ + Objects_Control Object; + /** This is used to implement the barrier. */ + CORE_barrier_Control Barrier; +} POSIX_Barrier_Control; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ + +POSIX_EXTERN Objects_Information _POSIX_Barrier_Information; + +/** + * @brief _POSIX_Barrier_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + * + * @param[in] maximum_barriers is the total number of barriers allowed to + * concurrently be active in the system. + */ + +void _POSIX_Barrier_Manager_initialization(void); + +/** + * @brief _POSIX_Barrier_Translate_core_barrier_return_code ( + * + * This routine translates SuperCore Barrier status codes into the + * corresponding POSIX ones. + * + * + * @param[in] the_barrier_status is the SuperCore status. + * + * @return the corresponding POSIX status + */ +int _POSIX_Barrier_Translate_core_barrier_return_code( + CORE_barrier_Status the_barrier_status +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/posix/barrier.inl> +#endif + +#ifdef __cplusplus +} +#endif + +#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..6e6b32a71c --- /dev/null +++ b/cpukit/posix/include/rtems/posix/cancel.h @@ -0,0 +1,62 @@ +/** + * @file rtems/posix/cancel.h + * + * This file contains the prototypes and data types used to implement + * POSIX thread cancelation. + */ + +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_CANCEL_H +#define _RTEMS_POSIX_CANCEL_H + +#include <rtems/posix/threadsup.h> + +/** + * This structure is used to manage the cancelation handlers. + */ +typedef struct { + /** This field is the Chain Node so we can put these on lists. */ + Chain_Node Node; + /** This field is the cancelation routine. */ + void (*routine)( void * ); + /** This field is the argument to the cancelation routine. */ + void *arg; +} POSIX_Cancel_Handler_control; + +/** + * @brief _POSIX_Threads_cancel_run + * + * This support routine runs through the chain of cancel handlers that + * have been registered and executes them. + * + * @param[in] the_thread is the thread whose cancelation handlers + * should be run + */ +void _POSIX_Threads_cancel_run( + Thread_Control *the_thread +); + +/** + * @brief _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch + * + * This routine separates a piece of code that existed as part of + * another routine, but had to be separated to improve coverage. + * + * @param[in] the_thread is the thread to evaluate canceling + */ +void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch ( + Thread_Control *the_thread +); + +#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..5ed8dfeed7 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/cond.h @@ -0,0 +1,181 @@ +/** + * @file rtems/posix/cond.h + */ + +/* + * This include file contains all the private support information for + * POSIX condition variables. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_COND_H +#define _RTEMS_POSIX_COND_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/score/threadq.h> + +/* + * Constant to indicate condition variable does not currently have + * a mutex assigned to it. + */ + +#define POSIX_CONDITION_VARIABLES_NO_MUTEX 0 + +/* + * 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. + */ + +POSIX_EXTERN Objects_Information _POSIX_Condition_variables_Information; + +/* + * The default condition variable attributes structure. + */ + +extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes; + +/* + * _POSIX_Condition_variables_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Condition_variables_Manager_initialization(void); + +/* + * _POSIX_Condition_variables_Allocate + * + * DESCRIPTION: + * + * This function allocates a condition variable control block from + * the inactive chain of free condition variable control blocks. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +#if 0 +RTEMS_INLINE_ROUTINE POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get ( + Objects_Id *id, + Objects_Locations *location +); +#endif + +/* + * _POSIX_Condition_variables_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_condition variable is NULL + * and FALSE otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Condition_variables_Is_null ( + POSIX_Condition_variables_Control *the_condition_variable +); + +/* + * _POSIX_Condition_variables_Signal_support + * + * DESCRIPTION: + * + * 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, + bool is_broadcast +); + +/* + * _POSIX_Condition_variables_Wait_support + * + * DESCRIPTION: + * + * 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, + bool already_timedout +); + +/* + * _POSIX_Condition_variables_Get + * + * DESCRIPTION: + * + * A support routine which translates the condition variable id into + * a local pointer. As a side-effect, it may create the condition + * variable. + */ + +POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get ( + pthread_cond_t *cond, + Objects_Locations *location +); + +#include <rtems/posix/cond.inl> + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/config.h b/cpukit/posix/include/rtems/posix/config.h new file mode 100644 index 0000000000..b6ad91fb34 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/config.h @@ -0,0 +1,77 @@ +/** + * @file rtems/posix/config.h + * + * This include file contains the table of user defined configuration + * parameters specific for the POSIX API. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_CONFIG_H +#define _RTEMS_POSIX_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * XXX + * + * The following records define the Configuration Table. The + * information contained in this table is required in all + * RTEMS systems, whether single or multiprocessor. This + * table primarily defines the following: + * + * + required number of each object type + */ + +/* + * For now, we are only allowing the user to specify the entry point + * and stack size for POSIX initialization threads. + */ + +typedef struct { + void *(*thread_entry)(void *); + int stack_size; +} posix_initialization_threads_table; + +typedef struct { + int maximum_threads; + int maximum_mutexes; + int maximum_condition_variables; + int maximum_keys; + int maximum_timers; + int maximum_queued_signals; + int maximum_message_queues; + int maximum_message_queue_descriptors; + int maximum_semaphores; + int maximum_barriers; + int maximum_rwlocks; + int maximum_spinlocks; + int number_of_initialization_threads; + posix_initialization_threads_table *User_initialization_threads_table; +} posix_api_configuration_table; + +/** + * @brief POSIX API Configuration Table + * + * This is the POSIX API Configuration Table expected to be generated + * by confdefs.h. + */ +extern posix_api_configuration_table Configuration_POSIX_API; + +#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..e39aa98d53 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/key.h @@ -0,0 +1,103 @@ +/** + * @file rtems/posix/key.h + */ + +/* rtems/posix/key.h + * + * This include file contains all the private support information for + * POSIX key. + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_KEY_H +#define _RTEMS_POSIX_KEY_H + +#include <rtems/score/object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This is the 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 { + /** This field is the Object control structure. */ + Objects_Control Object; + /** This field points to the optional destructor method. */ + void (*destructor)( void * ); + /** This field points to the values per thread. */ + void **Values[ OBJECTS_APIS_LAST + 1 ]; +} POSIX_Keys_Control; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +POSIX_EXTERN Objects_Information _POSIX_Keys_Information; + +/** + * @brief _POSIX_Keys_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _POSIX_Key_Manager_initialization(void); + +/** + * @brief _POSIX_Keys_Run_destructors + * + * This function executes all the destructors associated with the thread's + * keys. This function will execute until all values have been set to NULL. + * + * @param[in] thread is the thread whose keys should have all their + * destructors run. + * + * @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 +); + +/** + * @brief Free Key Memory + * + * This memory frees the key table memory associated with @a the_key. + * + * @param[in] the_key is the POSIX key to free the table memory of. + */ +void _POSIX_Keys_Free_memory( + POSIX_Keys_Control *the_key +); + +/** + * @brief _POSIX_Keys_Free + * + * This routine frees a keys control block to the + * inactive chain of free keys control blocks. + * + * @param[in] the_key is the POSIX key to free. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Free ( + POSIX_Keys_Control *the_key +); + +#include <rtems/posix/key.inl> + +#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..1e2e7a7429 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/mqueue.h @@ -0,0 +1,248 @@ +/** + * @file rtems/posix/mqueue.h + * + * This include file contains all the private support information for + * POSIX Message Queues. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_MQUEUE_H +#define _RTEMS_POSIX_MQUEUE_H + +#include <signal.h> +#include <mqueue.h> /* struct mq_attr */ +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Data Structure used to manage a POSIX message queue + */ + +typedef struct { + Objects_Control Object; + int process_shared; + bool named; + bool linked; + uint32_t open_count; + CORE_message_queue_Control Message_queue; + struct sigevent notification; +} POSIX_Message_queue_Control; + +typedef struct { + Objects_Control Object; + POSIX_Message_queue_Control *Queue; + int oflag; +} POSIX_Message_queue_Control_fd; + +/* + * The following defines the information control block used to manage + * this class of objects. The second item is used to manage the set + * of "file descriptors" associated with the message queues. + */ + +POSIX_EXTERN Objects_Information _POSIX_Message_queue_Information; +POSIX_EXTERN Objects_Information _POSIX_Message_queue_Information_fds; + +/* + * _POSIX_Message_queue_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Message_queue_Manager_initialization(void); + +/* + * + * _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, + struct mq_attr *attr, + POSIX_Message_queue_Control **message_queue +); + +/* + * _POSIX_Message_queue_Delete + * + * DESCRIPTION: + * + * This routine supports the mq_unlink and mq_close routines by + * doing most of the work involved with removing a message queue. + */ + +void _POSIX_Message_queue_Delete( + POSIX_Message_queue_Control *the_mq +); + +/* + * _POSIX_Message_queue_Receive_support + * + * DESCRIPTION: + * + * This routine supports the various flavors of receiving a message. + */ + +ssize_t _POSIX_Message_queue_Receive_support( + mqd_t mqdes, + char *msg_ptr, + size_t msg_len, + unsigned int *msg_prio, + bool wait, + Watchdog_Interval timeout +); + +/* + * _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, + size_t msg_len, + uint32_t msg_prio, + bool wait, + 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. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Message_queue_Is_null ( + POSIX_Message_queue_Control *the_mq +); + +/* + * _POSIX_Message_queue_Name_to_id + * + * DESCRIPTION: + * + * This routine looks up the specified name for a message queue and returns the + * id of the message queue associated with it. + */ + +int _POSIX_Message_queue_Name_to_id( + const char *name, + Objects_Id *id +); + +/* + * _POSIX_Message_queue_Priority_to_core + * + * DESCRIPTION: + * + * XXX + */ + +RTEMS_INLINE_ROUTINE CORE_message_queue_Submit_types _POSIX_Message_queue_Priority_to_core( + unsigned int priority +); + +/* + * _POSIX_Message_queue_Priority_from_core + * + * DESCRIPTION: + * + * XXX + */ + +RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core( + CORE_message_queue_Submit_types priority +); + +/*PAGE + * + * _POSIX_Message_queue_Translate_core_message_queue_return_code + * + * DESCRIPTION: + * + * XXX + */ + +int _POSIX_Message_queue_Translate_core_message_queue_return_code( + uint32_t the_message_queue_status +); + + +#include <rtems/posix/mqueue.inl> + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include 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..4309edfaa8 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/mutex.h @@ -0,0 +1,192 @@ +/** + * @file rtems/posix/mutex.h + */ + +/* + * This include file contains all the private support information for + * POSIX mutex's. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_MUTEX_H +#define _RTEMS_POSIX_MUTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/coremutex.h> +#include <pthread.h> + +/* + * 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. + */ + +POSIX_EXTERN Objects_Information _POSIX_Mutex_Information; + +/* + * The default mutex attributes structure. + */ + +POSIX_EXTERN pthread_mutexattr_t _POSIX_Mutex_Default_attributes; + +/* + * _POSIX_Mutex_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Mutex_Manager_initialization(void); + +/* + * _POSIX_Mutex_Allocate + * + * DESCRIPTION: + * + * This function allocates a mutexes control block from + * the inactive chain of free mutexes control blocks. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Free ( + POSIX_Mutex_Control *the_mutex +); + +#if 0 +/* + * _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. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_null ( + POSIX_Mutex_Control *the_mutex +); +#endif + +/* + * _POSIX_Mutex_Lock_support + * + * DESCRIPTION: + * + * A support routine which implements guts of the blocking, non-blocking, and + * timed wait version of mutex lock. + */ + +int _POSIX_Mutex_Lock_support( + pthread_mutex_t *mutex, + bool blocking, + Watchdog_Interval timeout +); + +/* + * _POSIX_Mutex_Translate_core_mutex_return_code + * + * DESCRIPTION: + * + * A support routine which converts core mutex status codes into the + * appropriate POSIX status values. + */ + +int _POSIX_Mutex_Translate_core_mutex_return_code( + CORE_mutex_Status the_mutex_status +); + + +/* + * _POSIX_Mutex_Get + * + * DESCRIPTION: + * + * A support routine which translates the mutex id into a local pointer. + * As a side-effect, it may create the mutex. + * + * NOTE: + * + * This version of the method uses a dispatching critical section. + */ + +POSIX_Mutex_Control *_POSIX_Mutex_Get ( + pthread_mutex_t *mutex, + Objects_Locations *location +); + +/* + * _POSIX_Mutex_Get + * + * DESCRIPTION: + * + * A support routine which translates the mutex id into a local pointer. + * As a side-effect, it may create the mutex. + * + * NOTE: + * + * This version of the method uses an interrupt critical section. + */ + +POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable ( + pthread_mutex_t *mutex, + Objects_Locations *location, + ISR_Level *level +); + +#include <rtems/posix/mutex.inl> + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/posixapi.h b/cpukit/posix/include/rtems/posix/posixapi.h new file mode 100644 index 0000000000..729a6db163 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/posixapi.h @@ -0,0 +1,30 @@ +/** + * @file rtems/posix/posixapi.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_POSIXAPI_H +#define _RTEMS_POSIX_POSIXAPI_H + +#include <rtems/config.h> + +/** + * @brief Initialize POSIX API + * + * This method is responsible for initializing each of the POSIX + * API managers. + */ +void _POSIX_API_Initialize(void); + +#endif +/* end of include 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..5944c4e7c3 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/priority.h @@ -0,0 +1,91 @@ +/** + * @file rtems/posix/priority.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_PRIORITY_H +#define _RTEMS_POSIX_PRIORITY_H + +#include <rtems/score/priority.h> + +/** + * 1003.1b-1993,2.2.2.80 definition of priority, p. 19 + * + * "Numerically higher values represent higher priorities." + * + * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API. + * + * There are only 254 posix priority levels since a task at priority level + * 255 would never run because of the RTEMS idle task. This is necessary + * because GNAT maps the lowest Ada task priority to the lowest thread + * priority. The lowest priority Ada task should get to run, so there is + * a fundamental conflict with having 255 priorities. + * + * But since RTEMS can be configured with fewer than 256 priorities, + * we use the internal constant. + */ +#define POSIX_SCHEDULER_MAXIMUM_PRIORITY (PRIORITY_MAXIMUM - 1) + + +/** + * This is the numerically least important POSIX priority. + */ +#define POSIX_SCHEDULER_MINIMUM_PRIORITY (1) + +/** + * 1003.1b-1993,2.2.2.80 definition of priority, p. 19 + * + * "Numerically higher values represent higher priorities." + * + * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API. + * + * @param[in] priority is the priority to test + * + * @return This method returns true if the priority is valid and + * false otherwise. + */ +bool _POSIX_Priority_Is_valid( + int priority +); + +/** + * @brief Convert POSIX Priority To SuperCore Priority + * + * This method converts a POSIX API priority into onto the corresponding + * SuperCore value. + * + * @param[in] priority is the POSIX API priority. + * + * @return This method returns the corresponding SuperCore priority. + */ +RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core( + int priority +); + +/** + * @brief Convert SuperCore Priority To POSIX Priority + * + * This method converts a SuperCore priority into onto the corresponding + * POSIX API value. + * + * @param[in] priority is the POSIX API priority. + * + * @return This method returns the corresponding POSIX priority. + */ +RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core( + Priority_Control priority +); + +#include <rtems/posix/priority.inl> + +#endif diff --git a/cpukit/posix/include/rtems/posix/psignal.h b/cpukit/posix/include/rtems/posix/psignal.h new file mode 100644 index 0000000000..87b629ef52 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/psignal.h @@ -0,0 +1,121 @@ +/** + * @file rtems/posix/psignal.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_PSIGNAL_H +#define _RTEMS_POSIX_PSIGNAL_H + +#include <rtems/posix/pthread.h> +#include <rtems/posix/sigset.h> + +#define _States_Is_interruptible_signal( _states ) \ + ( ((_states) & \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) + +#define SIGACTION_TERMINATE \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abnormal_termination_handler} } +#define SIGACTION_IGNORE \ + { 0, SIGNAL_ALL_MASK, {SIG_IGN} } +#define SIGACTION_STOP \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} } +#define SIGACTION_CONTINUE \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} } + +#define SIG_ARRAY_MAX (SIGRTMAX + 1) + +/* + * Variables + */ + +extern sigset_t _POSIX_signals_Pending; + +extern const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ]; + +extern struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; + +extern Watchdog_Control _POSIX_signals_Alarm_timer; + +extern Watchdog_Control _POSIX_signals_Ualarm_timer; + +extern Thread_queue_Control _POSIX_signals_Wait_queue; + +extern Chain_Control _POSIX_signals_Inactive_siginfo; + +extern Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; + +/* + * POSIX internal siginfo structure + */ + +typedef struct { + Chain_Node Node; + siginfo_t Info; +} POSIX_signals_Siginfo_node; + +/* + * Internal routines + */ + +void _POSIX_signals_Manager_Initialization(void); + +void _POSIX_signals_Post_switch_extension( + Thread_Control *the_thread +); + +bool _POSIX_signals_Unblock_thread( + Thread_Control *the_thread, + int signo, + siginfo_t *info +); + +bool _POSIX_signals_Check_signal( + POSIX_API_Control *api, + int signo, + bool is_global +); + +bool _POSIX_signals_Clear_signals( + POSIX_API_Control *api, + int signo, + siginfo_t *info, + bool is_global, + bool check_blocked +); + +int killinfo( + pid_t pid, + int sig, + const union sigval *value +); + +void _POSIX_signals_Set_process_signals( + sigset_t mask +); + +void _POSIX_signals_Clear_process_signals( + int signo +); + +/* + * Default signal handlers + */ + +#define _POSIX_signals_Stop_handler NULL +#define _POSIX_signals_Continue_handler NULL + +void _POSIX_signals_Abnormal_termination_handler( int signo ); + +#endif +/* end of file */ diff --git a/cpukit/posix/include/rtems/posix/pthread.h b/cpukit/posix/include/rtems/posix/pthread.h new file mode 100644 index 0000000000..6185afa62c --- /dev/null +++ b/cpukit/posix/include/rtems/posix/pthread.h @@ -0,0 +1,175 @@ +/** + * @file rtems/posix/pthread.h + */ + +/* + * This include file contains all the private support information for + * POSIX threads. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_PTHREAD_H +#define _RTEMS_POSIX_PTHREAD_H + + +#include <rtems/posix/config.h> +#include <rtems/posix/threadsup.h> + +#ifdef __cplusplus +extern "C" { +#endif +/** + * The following sets the minimum stack size for POSIX threads. + */ +#define PTHREAD_MINIMUM_STACK_SIZE (_Stack_Minimum() * 2) + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +POSIX_EXTERN Objects_Information _POSIX_Threads_Information; + +/** + * This variable contains the default POSIX Thread attributes. + */ +extern const pthread_attr_t _POSIX_Threads_Default_attributes; + +/** + * When the user configures a set of POSIX API initialization threads, + * This variable will point to the method used to initialize them. + * + * @note It is instantiated and initialized by confdefs.h based upon + * application requirements. + */ +extern void (*_POSIX_Threads_Initialize_user_threads_p)(void); + +/** + * @brief _POSIX_Threads_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + */ +void _POSIX_Threads_Manager_initialization(void); + +/** + * @brief _POSIX_Threads_Allocate + * + * This function allocates a pthread control block from + * the inactive chain of free pthread control blocks. + * + * @return This method returns a newly allocated thread. + */ +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void ); + +/** + * @brief _POSIX_Threads_Free + * + * This routine frees a pthread control block to the + * inactive chain of free pthread control blocks. + * + * @param[in] the_pthread is the thread to free + */ +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free( + Thread_Control *the_pthread +); + +/** + * @brief _POSIX_Threads_Get + * + * 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. + * + * @param[in] id is the id to lookup + * @param[in] location points to the returned location value + * + * @return This methods returns a pointer to the corresponding Thread_Control. + */ +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get( + pthread_t id, + Objects_Locations *location +); + +/** + * @brief _POSIX_Threads_Is_null + * + * This function returns TRUE if the_pthread is NULL and FALSE otherwise. + * + * @param[in] the_pthread is the thread pointer to check. + * + * @return This method returns true if the thread pointer is null. + */ +RTEMS_INLINE_ROUTINE bool _POSIX_Threads_Is_null( + Thread_Control *the_pthread +); + +/** + * @brief _POSIX_Threads_Sporadic_budget_callout + * + * This routine handles the sporadic scheduling algorithm. + * + * @param[in] the_thread is the thread whose budget has been exceeded. + */ +void _POSIX_Threads_Sporadic_budget_callout( + Thread_Control *the_thread +); + +/** + * _POSIX_Threads_Sporadic_budget_TSR + * + * This routine supports the sporadic scheduling algorithm. It + * is scheduled to be executed at the end of each replenishment + * period. In sporadic scheduling a thread will execute at a + * high priority for a user specified amount of CPU time. When + * it exceeds that amount of CPU time, its priority is automatically + * lowered. This TSR is executed when it is time to replenish + * the thread's processor budget and raise its priority. + * + * @param[in] id is ignored + * @param[in] argument is a pointer to the Thread_Control structure + * for the thread being replenished. + */ +void _POSIX_Threads_Sporadic_budget_TSR( + Objects_Id id, + void *argument +); + +/** + * @brief Translate sched_param into SuperCore Terms + * + * This method translates the POSIX API sched_param into the corresponding + * SuperCore settings. + * + * @param[in] policy is the POSIX scheduling policy + * @param[in] param points to the scheduling parameter structure + * @param[in] budget_algorithm points to the output CPU Budget algorithm + * @param[in] budget_callout points to the output CPU Callout + * + * @return This method returns 0 on success or a POSIX error code. + */ +int _POSIX_Thread_Translate_sched_param( + int policy, + struct sched_param *param, + Thread_CPU_budget_algorithms *budget_algorithm, + Thread_CPU_budget_algorithm_callout *budget_callout +); + +#include <rtems/posix/pthread.inl> + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/ptimer.h b/cpukit/posix/include/rtems/posix/ptimer.h new file mode 100644 index 0000000000..79fba9d819 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/ptimer.h @@ -0,0 +1,94 @@ +/** + * @file rtems/posix/ptimer.h + */ + +/* rtems/posix/ptimer.h + * + * This include file contains all the private support information for + * POSIX timers. + * + * COPYRIGHT (c) 1998. + * Alfonso Escalera Piña + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * ptimer.h,v 1.0 1998/03/31 16:21:16 + */ + +#ifndef _RTEMS_POSIX_PTIMER_H +#define _RTEMS_POSIX_PTIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/posix/config.h> + +/* + * _POSIX_Timers_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _POSIX_Timer_Manager_initialization(void); + +/* + * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264 + * + * timer_create + */ + +int timer_create( + clockid_t clock_id, + struct sigevent *evp, + timer_t *timerid +); + +/* + * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266 + */ + +int timer_delete( + timer_t timerid +); + +/* + * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 + * + * timer_settime + */ + +int timer_settime( + timer_t timerid, + int flags, + const struct itimerspec *value, + struct itimerspec *ovalue +); + +/* + * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 + * + * timer_gettime + */ + +int timer_gettime( + timer_t timerid, + struct itimerspec *value +); + +/* + * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 + * + * timer_getoverrun + * + */ + +int timer_getoverrun( + timer_t timerid +); + +#endif diff --git a/cpukit/posix/include/rtems/posix/rwlock.h b/cpukit/posix/include/rtems/posix/rwlock.h new file mode 100644 index 0000000000..2774e02379 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/rwlock.h @@ -0,0 +1,88 @@ +/** + * @file rtems/posix/rwlock.h + */ + +/* + * This include file contains all the constants and structures associated + * with the POSIX RWLock Manager. + * + * Directives provided are: + * + * + create a RWLock + * + delete a RWLock + * + wait for a RWLock + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_RWLOCK_H +#define _RTEMS_POSIX_RWLOCK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/score/corerwlock.h> + +/** + * This type defines the control block used to manage each RWLock. + */ + +typedef struct { + /** This is used to manage a RWLock as an object. */ + Objects_Control Object; + /** This is used to implement the RWLock. */ + CORE_RWLock_Control RWLock; +} POSIX_RWLock_Control; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ + +POSIX_EXTERN Objects_Information _POSIX_RWLock_Information; + +/** + * @brief _POSIX_RWLock_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + * + * @param[in] maximum_rwlocks is the total number of RWLocks allowed to + * concurrently be active in the system. + */ + +void _POSIX_RWLock_Manager_initialization(void); + +/** + * @brief _POSIX_RWLock_Translate_core_RWLock_return_code ( + * + * This routine translates SuperCore RWLock status codes into the + * corresponding POSIX ones. + * + * + * @param[in] the_RWLock_status is the SuperCore status. + * + * @return the corresponding POSIX status + */ +int _POSIX_RWLock_Translate_core_RWLock_return_code( + CORE_RWLock_Status the_RWLock_status +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/posix/rwlock.inl> +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include 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..5f232eea54 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/semaphore.h @@ -0,0 +1,198 @@ +/** + * @file rtems/posix/semaphore.h + */ + +/* rtems/posix/semaphore.h + * + * This include file contains all the private support information for + * POSIX Semaphores. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_SEMAPHORE_H +#define _RTEMS_POSIX_SEMAPHORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <semaphore.h> +#include <rtems/score/coresem.h> + +/* + * Data Structure used to manage a POSIX semaphore + */ + +typedef struct { + Objects_Control Object; + int process_shared; + bool named; + bool linked; + uint32_t open_count; + CORE_semaphore_Control Semaphore; + /* + * sem_t is 32-bit. If Object_Id is 16-bit, then they are not + * interchangeable. We have to be able to return a pointer to + * a 32-bit form of the 16-bit Id. + */ + #if defined(RTEMS_USE_16_BIT_OBJECT) + sem_t Semaphore_id; + #endif +} POSIX_Semaphore_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +POSIX_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(void); + +/* + * _POSIX_Semaphore_Allocate + * + * DESCRIPTION: + * + * This function allocates a semaphore control block from + * the inactive chain of free semaphore control blocks. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE 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. + */ + +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get ( + sem_t *id, + Objects_Locations *location +); + +/* + * _POSIX_Semaphore_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_semaphore is NULL and FALSE otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_null ( + POSIX_Semaphore_Control *the_semaphore +); + +/* + * _POSIX_Semaphore_Create_support + * + * DESCRIPTION: + * + * This routine supports the sem_init and sem_open routines. + */ + +int _POSIX_Semaphore_Create_support( + const char *name, + int pshared, + unsigned int value, + POSIX_Semaphore_Control **the_sem +); + +/* + * _POSIX_Semaphore_Delete + * + * DESCRIPTION: + * + * This routine supports the sem_close and sem_unlink routines. + */ + +void _POSIX_Semaphore_Delete( + POSIX_Semaphore_Control *the_semaphore +); + +/* + * _POSIX_Semaphore_Wait_support + * + * DESCRIPTION: + * + * This routine supports the sem_wait, sem_trywait, and sem_timedwait + * services. + */ + +int _POSIX_Semaphore_Wait_support( + sem_t *sem, + bool blocking, + Watchdog_Interval timeout +); + +/* + * _POSIX_Semaphore_Name_to_id + * + * DESCRIPTION: + * + * This routine performs name to id translation. + */ + +int _POSIX_Semaphore_Name_to_id( + const char *name, + sem_t *id +); + +/* + * _POSIX_Semaphore_Translate_core_semaphore_return_code + * + * DESCRIPTION: + * + * A support routine which converts core semaphore status codes into the + * appropriate POSIX status values. + */ + +int _POSIX_Semaphore_Translate_core_semaphore_return_code( + CORE_semaphore_Status the_semaphore_status +); + +#include <rtems/posix/semaphore.inl> + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/include/rtems/posix/sigset.h b/cpukit/posix/include/rtems/posix/sigset.h new file mode 100644 index 0000000000..338879e5e2 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/sigset.h @@ -0,0 +1,42 @@ +/** + * @file rtems/posix/sigset.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_SIGSET_H +#define _RTEMS_POSIX_SIGSET_H + +#include <signal.h> // sigset_t + +/* + * Currently 32 signals numbered 1-32 are defined + */ + +#define SIGNAL_EMPTY_MASK 0x00000000L +#define SIGNAL_ALL_MASK 0xffffffffL + +static inline sigset_t signo_to_mask( + uint32_t sig +) +{ + return 1u << (sig - 1); +} + +static inline bool is_valid_signo( + int signo +) +{ + return ((signo) >= 1 && (signo) <= 32 ); +} + +#endif diff --git a/cpukit/posix/include/rtems/posix/spinlock.h b/cpukit/posix/include/rtems/posix/spinlock.h new file mode 100644 index 0000000000..cf6cb6fbd2 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/spinlock.h @@ -0,0 +1,88 @@ +/** + * @file rtems/posix/spinlock.h + */ + +/* + * This include file contains all the constants and structures associated + * with the POSIX Spinlock Manager. + * + * Directives provided are: + * + * + create a spinlock + * + delete a spinlock + * + wait for a spinlock + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_SPINLOCK_H +#define _RTEMS_POSIX_SPINLOCK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/score/corespinlock.h> + +/** + * This type defines the control block used to manage each spinlock. + */ + +typedef struct { + /** This is used to manage a spinlock as an object. */ + Objects_Control Object; + /** This is used to implement the spinlock. */ + CORE_spinlock_Control Spinlock; +} POSIX_Spinlock_Control; + +/** + * The following defines the information control block used to manage + * this class of objects. + */ + +POSIX_EXTERN Objects_Information _POSIX_Spinlock_Information; + +/** + * @brief _POSIX_Spinlock_Manager_initialization + * + * This routine performs the initialization necessary for this manager. + * + * @param[in] maximum_spinlocks is the total number of spinlocks allowed to + * concurrently be active in the system. + */ + +void _POSIX_Spinlock_Manager_initialization(void); + +/** + * @brief _POSIX_Spinlock_Translate_core_spinlock_return_code ( + * + * This routine translates SuperCore Spinlock status codes into the + * corresponding POSIX ones. + * + * + * @param[in] the_spinlock_status is the SuperCore status. + * + * @return the corresponding POSIX status + */ +int _POSIX_Spinlock_Translate_core_spinlock_return_code( + CORE_spinlock_Status the_spinlock_status +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/posix/spinlock.inl> +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include 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..cc3a87e99a --- /dev/null +++ b/cpukit/posix/include/rtems/posix/threadsup.h @@ -0,0 +1,95 @@ +/** + * @file rtems/posix/threadsup.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_THREADSUP_H +#define _RTEMS_POSIX_THREADSUP_H + +#include <sys/signal.h> +#include <rtems/score/coresem.h> +#include <rtems/score/tqdata.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * This defines the POSIX API support structure associated with + * each thread in a system with POSIX configured. + */ +typedef struct { + /** This is the POSIX threads attribute set. */ + pthread_attr_t Attributes; + /** This indicates whether the thread is attached or detached. */ + int detachstate; + /** This is the set of threads waiting for the thread to exit. */ + Thread_queue_Control Join_List; + /** This is the thread's current scheduling policy. */ + int schedpolicy; + /** This is the thread's current set of scheduling parameters. */ + struct sched_param schedparam; + /** + * This is the high priority to execute at when using the sporadic + * scheduler. + */ + int ss_high_priority; + /** + * This is the timer which controls when the thread executes at + * high and low priority when using the sporadic scheduler. + */ + Watchdog_Control Sporadic_timer; + + /** This is the set of signals which are currently blocked. */ + sigset_t signals_blocked; + /** This is the set of signals which are currently pending. */ + sigset_t signals_pending; + + /*******************************************************************/ + /*******************************************************************/ + /*************** POSIX Cancelability ***************/ + /*******************************************************************/ + /*******************************************************************/ + + /** This is the cancelability state. */ + int cancelability_state; + /** This is the cancelability type. */ + int cancelability_type; + /** This indicates if a cancelation has been requested. */ + int cancelation_requested; + /** This is the set of cancelation handlers. */ + Chain_Control Cancellation_Handlers; + +} POSIX_API_Control; + +/*! + * @brief POSIX Thread Exit Shared Helper + * + * This method is a helper routine which ensures that all + * POSIX thread calls which result in a thread exiting will + * do so in the same manner. + * + * @param[in] the_thread is the thread exiting or being canceled + * @param[in] value_ptr is the value to be returned by the thread + */ +void _POSIX_Thread_Exit( + Thread_Control *the_thread, + void *value_ptr +); + +#ifdef __cplusplus +} +#endif + +#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..93e3af0f44 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/time.h @@ -0,0 +1,59 @@ +/** + * @file rtems/posix/time.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_TIME_H +#define _RTEMS_POSIX_TIME_H + +#include <rtems/score/timespec.h> +#include <rtems/score/watchdog.h> + +/** @brief Absolute Timeout Conversion Results + * + * This enumeration defines the possible results of converting + * an absolute time used for timeouts to POSIX blocking calls to + * a number of ticks. + */ +typedef enum { + /** The timeout is invalid. */ + POSIX_ABSOLUTE_TIMEOUT_INVALID, + /** The timeout represents a time that is in the past. */ + POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, + /** The timeout represents a time that is equal to the current time. */ + POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + /** The timeout represents a time that is in the future. */ + POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE, +} POSIX_Absolute_timeout_conversion_results_t; + +/** + * @brief Convert Absolute Timeout to Ticks + * + * This method takes an absolute time being used as a timeout + * to a blocking directive, validates it and returns the number + * of corresponding clock ticks for use by the SuperCore. + * + * @param[in] abstime is the timeout + * @param[in] ticks_out will contain the number of ticks + * + * @return This method returns the number of ticks in @a ticks_out + * and a status value indicating whether the absolute time + * is valid, in the past, equal to the current time or in + * the future as it should be. + */ +POSIX_Absolute_timeout_conversion_results_t _POSIX_Absolute_timeout_to_ticks( + const struct timespec *abstime, + Watchdog_Interval *ticks_out +); + +#endif diff --git a/cpukit/posix/include/rtems/posix/timer.h b/cpukit/posix/include/rtems/posix/timer.h new file mode 100644 index 0000000000..c061e9d6b7 --- /dev/null +++ b/cpukit/posix/include/rtems/posix/timer.h @@ -0,0 +1,107 @@ +/** + * @file rtems/posix/timer.h + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_TIMER_H +#define _RTEMS_POSIX_TIMER_H + +#include <rtems/posix/config.h> +#include <rtems/score/object.h> +#include <rtems/score/watchdog.h> /* Watchdog_Control */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Timer is free */ +#define POSIX_TIMER_STATE_FREE 0x01 + +/* Created timer but not running */ +#define POSIX_TIMER_STATE_CREATE_NEW 0x02 + +/* Created timer and running */ +#define POSIX_TIMER_STATE_CREATE_RUN 0x03 + +/* Created, ran and stopped timer */ +#define POSIX_TIMER_STATE_CREATE_STOP 0x04 + +/* Indicates that the fire time is relative to the current one */ +#define POSIX_TIMER_RELATIVE 0 + +/* + * POSIX defines TIMER_ABSTIME but no constant for relative. So + * we have one internally but we need to be careful it has a different + * value. + */ +#if (POSIX_TIMER_RELATIVE == TIMER_ABSTIME) +#error "POSIX_TIMER_RELATIVE == TIMER_ABSTIME" +#endif + + +/* + * Data for a timer + */ +typedef struct { + Objects_Control Object; + Watchdog_Control Timer; /* Internal Timer */ + pthread_t thread_id; /* Thread identifier */ + char state; /* State of the timer */ + struct sigevent inf; /* Information associated to the timer */ + struct itimerspec timer_data; /* Timing data of the timer */ + uint32_t ticks; /* Number of ticks of the initialization */ + uint32_t overrun; /* Number of expirations of the timer */ + struct timespec time; /* Time at which the timer was started */ +} POSIX_Timer_Control; + +/* + * _POSIX_Timers_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ +void _POSIX_Timer_Manager_initialization(void); + +/* + * Timer TSR + */ +void _POSIX_Timer_TSR(Objects_Id timer, void *data); + +/* + * Watchdog Insert helper + */ +bool _POSIX_Timer_Insert_helper( + Watchdog_Control *timer, + Watchdog_Interval ticks, + Objects_Id id, + Watchdog_Service_routine_entry TSR, + void *arg +); + +/* + * The following defines the information control block used to manage + * this class of objects. + */ +POSIX_EXTERN Objects_Information _POSIX_Timer_Information; + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/posix/timer.inl> +#endif + +#ifdef __cplusplus +} +#endif + +#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..5727456b34 --- /dev/null +++ b/cpukit/posix/include/semaphore.h @@ -0,0 +1,124 @@ +/** + * @file semaphore.h + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _SEMAPHORE_H +#define _SEMAPHORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <unistd.h> + +#if defined(_POSIX_SEMAPHORES) + +#include <sys/time.h> + +/* + * 11.1 Semaphore Characteristics, P1003.1b-1993, p.219 + */ +typedef int sem_t; + +/* + * Bad semaphore Id + */ +#define SEM_FAILED (sem_t *) -1 + +/* + * 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 */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/posix/inline/rtems/posix/barrier.inl b/cpukit/posix/inline/rtems/posix/barrier.inl new file mode 100644 index 0000000000..2557f33cd8 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/barrier.inl @@ -0,0 +1,89 @@ +/** + * @file rtems/posix/barrier.inl + */ + +/* + * This file contains the static inlin implementation of the inlined + * routines from the POSIX Barrier Manager. + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_BARRIER_H +# error "Never use <rtems/posix/barrier.inl> directly; include <rtems/posix/barrier.h> instead." +#endif + +#ifndef _RTEMS_POSIX_BARRIER_INL +#define _RTEMS_POSIX_BARRIER_INL + +#include <pthread.h> + +/** + * @brief _POSIX_Barrier_Allocate + * + * This function allocates a barrier control block from + * the inactive chain of free barrier control blocks. + */ +RTEMS_INLINE_ROUTINE POSIX_Barrier_Control *_POSIX_Barrier_Allocate( void ) +{ + return (POSIX_Barrier_Control *) + _Objects_Allocate( &_POSIX_Barrier_Information ); +} + +/** + * @brief _POSIX_Barrier_Free + * + * This routine frees a barrier control block to the + * inactive chain of free barrier control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Barrier_Free ( + POSIX_Barrier_Control *the_barrier +) +{ + _Objects_Free( &_POSIX_Barrier_Information, &the_barrier->Object ); +} + +/** + * @brief _POSIX_Barrier_Get + * + * This function maps barrier IDs to barrier control blocks. + * If ID corresponds to a local barrier, then it returns + * the_barrier control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the barrier ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_barrier is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_barrier is undefined. + */ +RTEMS_INLINE_ROUTINE POSIX_Barrier_Control *_POSIX_Barrier_Get ( + pthread_barrier_t *barrier, + Objects_Locations *location +) +{ + return (POSIX_Barrier_Control *) _Objects_Get( + &_POSIX_Barrier_Information, + (Objects_Id) *barrier, + location + ); +} + +/** + * @brief _POSIX_Barrier_Is_null + * + * This function returns TRUE if the_barrier is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _POSIX_Barrier_Is_null ( + POSIX_Barrier_Control *the_barrier +) +{ + return ( the_barrier == NULL ); +} + +#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..3b011c0383 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/cond.inl @@ -0,0 +1,70 @@ +/** + * @file rtems/posix/cond.inl + */ + +/* rtems/posix/cond.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX condition variables. + * + * COPYRIGHT (c) 1989-2002. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_COND_H +# error "Never use <rtems/posix/cond.inl> directly; include <rtems/posix/cond.h> instead." +#endif + +#ifndef _RTEMS_POSIX_COND_INL +#define _RTEMS_POSIX_COND_INL + +#include <pthread.h> + +/*PAGE + * + * _POSIX_Condition_variables_Allocate + */ + +RTEMS_INLINE_ROUTINE 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 + */ + +RTEMS_INLINE_ROUTINE 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_Is_null + */ + +RTEMS_INLINE_ROUTINE bool _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/key.inl b/cpukit/posix/inline/rtems/posix/key.inl new file mode 100644 index 0000000000..c5c6324d06 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/key.inl @@ -0,0 +1,86 @@ +/** + * @file rtems/posix/key.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX key's. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_KEY_H +# error "Never use <rtems/posix/key.inl> directly; include <rtems/posix/key.h> instead." +#endif + +#ifndef _RTEMS_POSIX_KEY_INL +#define _RTEMS_POSIX_KEY_INL + +/** + * @brief _POSIX_Keys_Allocate + * + * This function allocates a keys control block from + * the inactive chain of free keys control blocks. + */ + +RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void ) +{ + return (POSIX_Keys_Control *) _Objects_Allocate( &_POSIX_Keys_Information ); +} + +/** + * @brief _POSIX_Keys_Free + * + * This routine frees a keys control block to the + * inactive chain of free keys control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Free ( + POSIX_Keys_Control *the_key +) +{ + _Objects_Free( &_POSIX_Keys_Information, &the_key->Object ); +} + +/** + * @brief _POSIX_Keys_Get + * + * 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. + */ + +RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Get ( + pthread_key_t id, + Objects_Locations *location +) +{ + return (POSIX_Keys_Control *) + _Objects_Get( &_POSIX_Keys_Information, (Objects_Id) id, location ); +} + +/** + * @brief _POSIX_Keys_Is_null + * + * This function returns TRUE if the_key is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _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..62bc3ce327 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/mqueue.inl @@ -0,0 +1,160 @@ +/** + * @file rtems/posix/mqueue.inl + */ + +/* rtems/posix/mqueue.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Message Queue. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_MQUEUE_H +# error "Never use <rtems/posix/mqueue.inl> directly; include <rtems/posix/mqueue.h> instead." +#endif + +#ifndef _RTEMS_POSIX_MQUEUE_INL +#define _RTEMS_POSIX_MQUEUE_INL + +/*PAGE + * + * _POSIX_Message_queue_Allocate + */ + +RTEMS_INLINE_ROUTINE + POSIX_Message_queue_Control *_POSIX_Message_queue_Allocate( void ) +{ + return (POSIX_Message_queue_Control *) + _Objects_Allocate( &_POSIX_Message_queue_Information ); +} + +/*PAGE + * + * _POSIX_Message_queue_Allocate_fd + */ + +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd * + _POSIX_Message_queue_Allocate_fd( void ) +{ + return (POSIX_Message_queue_Control_fd *) + _Objects_Allocate( &_POSIX_Message_queue_Information_fds ); +} + +/*PAGE + * + * _POSIX_Message_queue_Free + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free ( + POSIX_Message_queue_Control *the_mq +) +{ + _Objects_Free( &_POSIX_Message_queue_Information, &the_mq->Object ); +} + +/*PAGE + * + * _POSIX_Message_queue_Free_fd + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free_fd ( + POSIX_Message_queue_Control_fd *the_mq_fd +) +{ + _Objects_Free( &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object ); +} + +/*PAGE + * + * _POSIX_Message_queue_Namespace_remove + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Namespace_remove ( + POSIX_Message_queue_Control *the_mq +) +{ + _Objects_Namespace_remove( + &_POSIX_Message_queue_Information, &the_mq->Object ); +} + +/*PAGE + * + * _POSIX_Message_queue_Get + */ + +RTEMS_INLINE_ROUTINE 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_Get_fd + */ + +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control_fd *_POSIX_Message_queue_Get_fd ( + mqd_t id, + Objects_Locations *location +) +{ + return (POSIX_Message_queue_Control_fd *) _Objects_Get( + &_POSIX_Message_queue_Information_fds, + (Objects_Id)id, + location + ); +} + +/*PAGE + * + * _POSIX_Message_queue_Is_null + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Message_queue_Is_null ( + POSIX_Message_queue_Control *the_mq +) +{ + return !the_mq; +} + +/*PAGE + * + * _POSIX_Message_queue_Priority_to_core + */ + +RTEMS_INLINE_ROUTINE CORE_message_queue_Submit_types _POSIX_Message_queue_Priority_to_core( + unsigned int priority +) +{ + return priority * -1; +} + +/* + * _POSIX_Message_queue_Priority_from_core + * + * DESCRIPTION: + * + * XXX + */ + +RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core( + CORE_message_queue_Submit_types priority +) +{ + /* absolute value without a library dependency */ + return ((priority >= 0) ? priority : -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..b5e3721a3a --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/mutex.inl @@ -0,0 +1,63 @@ +/** + * @file rtems/posix/mutex.inl + */ + +/* rtems/posix/mutex.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX mutex's. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_MUTEX_H +# error "Never use <rtems/posix/mutex.inl> directly; include <rtems/posix/mutex.h> instead." +#endif + +#ifndef _RTEMS_POSIX_MUTEX_INL +#define _RTEMS_POSIX_MUTEX_INL + +/*PAGE + * + * _POSIX_Mutex_Allocate + */ + +RTEMS_INLINE_ROUTINE POSIX_Mutex_Control *_POSIX_Mutex_Allocate( void ) +{ + return (POSIX_Mutex_Control *) _Objects_Allocate( &_POSIX_Mutex_Information ); +} + +/*PAGE + * + * _POSIX_Mutex_Free + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Free ( + POSIX_Mutex_Control *the_mutex +) +{ + _Objects_Free( &_POSIX_Mutex_Information, &the_mutex->Object ); +} + +/*PAGE + * + * _POSIX_Mutex_Is_null + */ + +RTEMS_INLINE_ROUTINE bool _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..9a9f538a61 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/priority.inl @@ -0,0 +1,37 @@ +/** + * @file rtems/posix/priority.inl + */ + +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_PRIORITY_H +# error "Never use <rtems/posix/priority.inl> directly; include <rtems/posix/priority.h> instead." +#endif + +#ifndef _RTEMS_POSIX_PRIORITY_INL +#define _RTEMS_POSIX_PRIORITY_INL + +RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core( + int priority +) +{ + return (Priority_Control) (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1); +} + +RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core( + Priority_Control priority +) +{ + return (POSIX_SCHEDULER_MAXIMUM_PRIORITY - priority + 1); +} + +#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..7f35e9a08b --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/pthread.inl @@ -0,0 +1,77 @@ +/** + * @file rtems/posix/pthread.inl + */ + +/* rtems/posix/pthread.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX threads. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_PTHREAD_H +# error "Never use <rtems/posix/pthread.inl> directly; include <rtems/posix/pthread.h> instead." +#endif + +#ifndef _RTEMS_POSIX_PTHREAD_INL +#define _RTEMS_POSIX_PTHREAD_INL + +/*PAGE + * + * _POSIX_Threads_Allocate + */ + +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void ) +{ + return (Thread_Control *) _Objects_Allocate( &_POSIX_Threads_Information ); +} + +/*PAGE + * + * _POSIX_Threads_Free + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free ( + Thread_Control *the_pthread +) +{ + _Objects_Free( &_POSIX_Threads_Information, &the_pthread->Object ); +} + +/*PAGE + * + * _POSIX_Threads_Get + */ + +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get ( + pthread_t id, + Objects_Locations *location +) +{ + return (Thread_Control *) + _Objects_Get( &_POSIX_Threads_Information, (Objects_Id)id, location ); +} + +/*PAGE + * + * _POSIX_Threads_Is_null + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Threads_Is_null ( + Thread_Control *the_pthread +) +{ + return !the_pthread; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/rwlock.inl b/cpukit/posix/inline/rtems/posix/rwlock.inl new file mode 100644 index 0000000000..ac11d35d3c --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/rwlock.inl @@ -0,0 +1,89 @@ +/** + * @file rtems/posix/RWLock.inl + */ + +/* + * This file contains the static inlin implementation of the inlined + * routines from the POSIX RWLock Manager. + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_RWLOCK_H +# error "Never use <rtems/posix/rwlock.inl> directly; include <rtems/posix/rwlock.h> instead." +#endif + +#ifndef _RTEMS_POSIX_RWLOCK_INL +#define _RTEMS_POSIX_RWLOCK_INL + +#include <pthread.h> + +/** + * @brief _POSIX_RWLock_Allocate + * + * This function allocates a RWLock control block from + * the inactive chain of free RWLock control blocks. + */ +RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Allocate( void ) +{ + return (POSIX_RWLock_Control *) + _Objects_Allocate( &_POSIX_RWLock_Information ); +} + +/** + * @brief _POSIX_RWLock_Free + * + * This routine frees a RWLock control block to the + * inactive chain of free RWLock control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_RWLock_Free ( + POSIX_RWLock_Control *the_RWLock +) +{ + _Objects_Free( &_POSIX_RWLock_Information, &the_RWLock->Object ); +} + +/** + * @brief _POSIX_RWLock_Get + * + * This function maps RWLock IDs to RWLock control blocks. + * If ID corresponds to a local RWLock, then it returns + * the_RWLock control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the RWLock ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_RWLock is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_RWLock is undefined. + */ +RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Get ( + pthread_rwlock_t *RWLock, + Objects_Locations *location +) +{ + return (POSIX_RWLock_Control *) _Objects_Get( + &_POSIX_RWLock_Information, + (Objects_Id) *RWLock, + location + ); +} + +/** + * @brief _POSIX_RWLock_Is_null + * + * This function returns TRUE if the_RWLock is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _POSIX_RWLock_Is_null ( + POSIX_RWLock_Control *the_RWLock +) +{ + return ( the_RWLock == NULL ); +} + +#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..eb885f1aa0 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/semaphore.inl @@ -0,0 +1,92 @@ +/** + * @file rtems/posix/semaphore.inl + */ + +/* rtems/posix/semaphore.inl + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Semaphores. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_SEMAPHORE_H +# error "Never use <rtems/posix/semaphore.inl> directly; include <rtems/posix/semaphore.h> instead." +#endif + +#ifndef _RTEMS_POSIX_SEMAPHORE_INL +#define _RTEMS_POSIX_SEMAPHORE_INL + +/*PAGE + * + * _POSIX_Semaphore_Allocate + */ + +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Allocate( void ) +{ + return (POSIX_Semaphore_Control *) + _Objects_Allocate( &_POSIX_Semaphore_Information ); +} + +/*PAGE + * + * _POSIX_Semaphore_Free + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free ( + POSIX_Semaphore_Control *the_semaphore +) +{ + _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object ); +} + +/*PAGE + * + * _POSIX_Semaphore_Namespace_remove + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Namespace_remove ( + POSIX_Semaphore_Control *the_semaphore +) +{ + _Objects_Namespace_remove( + &_POSIX_Semaphore_Information, &the_semaphore->Object ); +} + + + +/*PAGE + * + * _POSIX_Semaphore_Get + */ +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get ( + sem_t *id, + Objects_Locations *location +) +{ + return (POSIX_Semaphore_Control *) + _Objects_Get( &_POSIX_Semaphore_Information, (Objects_Id)*id, location ); +} + +/*PAGE + * + * _POSIX_Semaphore_Is_null + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_null ( + POSIX_Semaphore_Control *the_semaphore +) +{ + return !the_semaphore; +} + +#endif +/* end of include file */ + diff --git a/cpukit/posix/inline/rtems/posix/spinlock.inl b/cpukit/posix/inline/rtems/posix/spinlock.inl new file mode 100644 index 0000000000..6007258e01 --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/spinlock.inl @@ -0,0 +1,89 @@ +/** + * @file rtems/posix/spinlock.inl + */ + +/* + * This file contains the static inlin implementation of the inlined + * routines from the POSIX Spinlock Manager. + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_SPINLOCK_H +# error "Never use <rtems/posix/spinlock.inl> directly; include <rtems/posix/spinlock.h> instead." +#endif + +#ifndef _RTEMS_POSIX_SPINLOCK_INL +#define _RTEMS_POSIX_SPINLOCK_INL + +#include <pthread.h> + +/** + * @brief _POSIX_Spinlock_Allocate + * + * This function allocates a spinlock control block from + * the inactive chain of free spinlock control blocks. + */ +RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Allocate( void ) +{ + return (POSIX_Spinlock_Control *) + _Objects_Allocate( &_POSIX_Spinlock_Information ); +} + +/** + * @brief _POSIX_Spinlock_Free + * + * This routine frees a spinlock control block to the + * inactive chain of free spinlock control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Spinlock_Free ( + POSIX_Spinlock_Control *the_spinlock +) +{ + _Objects_Free( &_POSIX_Spinlock_Information, &the_spinlock->Object ); +} + +/** + * @brief _POSIX_Spinlock_Get + * + * This function maps spinlock IDs to spinlock control blocks. + * If ID corresponds to a local spinlock, then it returns + * the_spinlock control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the spinlock ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_spinlock is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_spinlock is undefined. + */ +RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get ( + pthread_spinlock_t *spinlock, + Objects_Locations *location +) +{ + return (POSIX_Spinlock_Control *) _Objects_Get( + &_POSIX_Spinlock_Information, + (Objects_Id) *spinlock, + location + ); +} + +/** + * @brief _POSIX_Spinlock_Is_null + * + * This function returns TRUE if the_spinlock is NULL and FALSE otherwise. + */ +RTEMS_INLINE_ROUTINE bool _POSIX_Spinlock_Is_null ( + POSIX_Spinlock_Control *the_spinlock +) +{ + return ( the_spinlock == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/posix/inline/rtems/posix/timer.inl b/cpukit/posix/inline/rtems/posix/timer.inl new file mode 100644 index 0000000000..63db10c8ab --- /dev/null +++ b/cpukit/posix/inline/rtems/posix/timer.inl @@ -0,0 +1,98 @@ +/** + * @file rtems/posix/timer.inl + */ + +/* timer.inl + * + * This file contains the static inline implementation of the inlined routines + * from the POSIX Timer Manager. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_POSIX_TIMER_H +# error "Never use <rtems/posix/timer.inl> directly; include <rtems/posix/timer.h> instead." +#endif + +#ifndef _RTEMS_POSIX_TIMER_INL +#define _RTEMS_POSIX_TIMER_INL + +/*PAGE + * + * _POSIX_Timer_Allocate + * + * DESCRIPTION: + * + * This function allocates a timer control block from + * the inactive chain of free timer control blocks. + */ + +RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Allocate( void ) +{ + return (POSIX_Timer_Control *) _Objects_Allocate( &_POSIX_Timer_Information ); +} + +/*PAGE + * + * _POSIX_Timer_Free + * + * DESCRIPTION: + * + * This routine frees a timer control block to the + * inactive chain of free timer control blocks. + */ + +RTEMS_INLINE_ROUTINE void _POSIX_Timer_Free ( + POSIX_Timer_Control *the_timer +) +{ + _Objects_Free( &_POSIX_Timer_Information, &the_timer->Object ); +} + +/*PAGE + * + * _POSIX_Timer_Get + * + * DESCRIPTION: + * + * This function maps timer IDs to timer control blocks. + * If ID corresponds to a local timer, then it returns + * the timer control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the returned value is undefined. + */ + +RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Get ( + timer_t id, + Objects_Locations *location +) +{ + return (POSIX_Timer_Control *) + _Objects_Get( &_POSIX_Timer_Information, (Objects_Id) id, location ); +} + +/*PAGE + * + * _POSIX_Timer_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_timer is NULL and FALSE otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _POSIX_Timer_Is_null ( + POSIX_Timer_Control *the_timer +) +{ + return (the_timer == NULL); +} + +#endif +/* end of include file */ diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am new file mode 100644 index 0000000000..119790b17e --- /dev/null +++ b/cpukit/posix/preinstall.am @@ -0,0 +1,162 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES = $(PREINSTALL_DIRS) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES = $(PREINSTALL_FILES) + +$(PROJECT_INCLUDE)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE) + @: > $(PROJECT_INCLUDE)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/posix/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems/posix + @: > $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/posix/sigset.h: include/rtems/posix/sigset.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/sigset.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/sigset.h + +if HAS_PTHREADS +$(PROJECT_INCLUDE)/aio.h: include/aio.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/aio.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/aio.h + +$(PROJECT_INCLUDE)/mqueue.h: include/mqueue.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mqueue.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/mqueue.h + +$(PROJECT_INCLUDE)/semaphore.h: include/semaphore.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/semaphore.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/semaphore.h + +$(PROJECT_INCLUDE)/rtems/posix/aio_misc.h: include/rtems/posix/aio_misc.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/aio_misc.h + +$(PROJECT_INCLUDE)/rtems/posix/cancel.h: include/rtems/posix/cancel.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cancel.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cancel.h + +$(PROJECT_INCLUDE)/rtems/posix/cond.h: include/rtems/posix/cond.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.h + +$(PROJECT_INCLUDE)/rtems/posix/config.h: include/rtems/posix/config.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/config.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/config.h + +$(PROJECT_INCLUDE)/rtems/posix/key.h: include/rtems/posix/key.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/key.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/key.h + +$(PROJECT_INCLUDE)/rtems/posix/mqueue.h: include/rtems/posix/mqueue.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mqueue.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mqueue.h + +$(PROJECT_INCLUDE)/rtems/posix/mutex.h: include/rtems/posix/mutex.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mutex.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mutex.h + +$(PROJECT_INCLUDE)/rtems/posix/posixapi.h: include/rtems/posix/posixapi.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/posixapi.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/posixapi.h + +$(PROJECT_INCLUDE)/rtems/posix/priority.h: include/rtems/posix/priority.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priority.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priority.h + +$(PROJECT_INCLUDE)/rtems/posix/psignal.h: include/rtems/posix/psignal.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/psignal.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/psignal.h + +$(PROJECT_INCLUDE)/rtems/posix/pthread.h: include/rtems/posix/pthread.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.h + +$(PROJECT_INCLUDE)/rtems/posix/ptimer.h: include/rtems/posix/ptimer.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/ptimer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/ptimer.h + +$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h + +$(PROJECT_INCLUDE)/rtems/posix/threadsup.h: include/rtems/posix/threadsup.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/threadsup.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/threadsup.h + +$(PROJECT_INCLUDE)/rtems/posix/time.h: include/rtems/posix/time.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/time.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/time.h + +$(PROJECT_INCLUDE)/rtems/posix/timer.h: include/rtems/posix/timer.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/timer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timer.h + +$(PROJECT_INCLUDE)/rtems/posix/barrier.h: include/rtems/posix/barrier.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/barrier.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/barrier.h + +$(PROJECT_INCLUDE)/rtems/posix/rwlock.h: include/rtems/posix/rwlock.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/rwlock.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlock.h + +$(PROJECT_INCLUDE)/rtems/posix/spinlock.h: include/rtems/posix/spinlock.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlock.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/spinlock.h + +$(PROJECT_INCLUDE)/rtems/posix/cond.inl: inline/rtems/posix/cond.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/cond.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/cond.inl + +$(PROJECT_INCLUDE)/rtems/posix/key.inl: inline/rtems/posix/key.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/key.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/key.inl + +$(PROJECT_INCLUDE)/rtems/posix/mqueue.inl: inline/rtems/posix/mqueue.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mqueue.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mqueue.inl + +$(PROJECT_INCLUDE)/rtems/posix/mutex.inl: inline/rtems/posix/mutex.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/mutex.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/mutex.inl + +$(PROJECT_INCLUDE)/rtems/posix/pthread.inl: inline/rtems/posix/pthread.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.inl + +$(PROJECT_INCLUDE)/rtems/posix/priority.inl: inline/rtems/posix/priority.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/priority.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/priority.inl + +$(PROJECT_INCLUDE)/rtems/posix/semaphore.inl: inline/rtems/posix/semaphore.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.inl + +$(PROJECT_INCLUDE)/rtems/posix/timer.inl: inline/rtems/posix/timer.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/timer.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/timer.inl + +$(PROJECT_INCLUDE)/rtems/posix/barrier.inl: inline/rtems/posix/barrier.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/barrier.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/barrier.inl + +$(PROJECT_INCLUDE)/rtems/posix/rwlock.inl: inline/rtems/posix/rwlock.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/rwlock.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/rwlock.inl + +$(PROJECT_INCLUDE)/rtems/posix/spinlock.inl: inline/rtems/posix/spinlock.inl $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/spinlock.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/spinlock.inl +endif diff --git a/cpukit/posix/src/.cvsignore b/cpukit/posix/src/.cvsignore new file mode 100644 index 0000000000..000074c626 --- /dev/null +++ b/cpukit/posix/src/.cvsignore @@ -0,0 +1,4 @@ +stamp-h +stamp-h.in +config.h +config.h.in diff --git a/cpukit/posix/src/README.mqueue b/cpukit/posix/src/README.mqueue new file mode 100644 index 0000000000..12c8afc03e --- /dev/null +++ b/cpukit/posix/src/README.mqueue @@ -0,0 +1,38 @@ +# +# $Id$ +# + +This program should print out the default attribute settings for a +POSIX message queue. + +#include <mqueue.h> +#include <stdio.h> + +main() +{ + mqd_t mqfd; + struct mq_attr mqstat; + int status; + + /* this should create it */ + mqfd = mq_open("myipc",O_WRONLY|O_CREAT,NULL); + if ( (int)mqfd == -1 ) { + perror( "Unable to open message queue" ); + exit( 1 ); + } + + status = mq_getattr(mqfd, &mqstat); + if ( !status ) { + printf( "mq_maxmsg: %d\n", mqstat.mq_maxmsg ); + printf( "mq_msgsize: %d\n", mqstat.mq_msgsize ); + printf( "mq_curmsgs: %d\n", mqstat.mq_curmsgs ); + } else { + perror( "Unable to get attributes on message queue" ); + exit( 1 ); + } + + /* this should delete it */ + (void) mq_close( mqfd ); + exit( 0 ); +} + diff --git a/cpukit/posix/src/_execve.c b/cpukit/posix/src/_execve.c new file mode 100644 index 0000000000..0bd8c2e7d1 --- /dev/null +++ b/cpukit/posix/src/_execve.c @@ -0,0 +1,28 @@ +/* + * execve() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <rtems/seterr.h> + +int _execve( + const char *path __attribute__((unused)), + char *const argv[] __attribute__((unused)), + char *const envp[] __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/adjtime.c b/cpukit/posix/src/adjtime.c new file mode 100644 index 0000000000..89ccd7950d --- /dev/null +++ b/cpukit/posix/src/adjtime.c @@ -0,0 +1,104 @@ +/* + * adjime() function + * + * This method was initially added as part of porting NTP to RTEMS. + * It is a BSD compatability function and now is available on + * GNU/Linux. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <sys/time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/seterr.h> +#include <rtems/score/tod.h> +#include <rtems/posix/time.h> +#include <rtems/score/thread.h> +#include <rtems/score/timespec.h> + +/* + * At one point there was a static variable named adjustment + * used by this implementation. I don't see any reason for it + * to be here based upon the GNU/Linux documentation. + */ + +int adjtime( + struct timeval *delta, + struct timeval *olddelta +) +{ + struct timespec ts; + long adjustment; + + /* + * Simple validations + */ + if ( !delta ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( delta->tv_usec >= TOD_MICROSECONDS_PER_SECOND ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( olddelta ) { + olddelta->tv_sec = 0; + olddelta->tv_usec = 0; + } + + /* convert delta to microseconds */ + adjustment = (delta->tv_sec * TOD_MICROSECONDS_PER_SECOND); + adjustment += delta->tv_usec; + + /* too small to account for */ + if ( adjustment < rtems_configuration_get_microseconds_per_tick() ) + return 0; + + /* + * This prevents context switches while we are adjusting the TOD + */ + + _Thread_Disable_dispatch(); + + _TOD_Get( &ts ); + + ts.tv_sec += delta->tv_sec; + ts.tv_nsec += delta->tv_usec * TOD_NANOSECONDS_PER_MICROSECOND; + + /* if adjustment is too much positive */ + while ( ts.tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) { + ts.tv_nsec -= TOD_NANOSECONDS_PER_SECOND; + ts.tv_sec++; + } + + /* if adjustment is too much negative */ + while ( ts.tv_nsec <= (-1 * TOD_NANOSECONDS_PER_SECOND) ) { + ts.tv_nsec += TOD_NANOSECONDS_PER_SECOND; + ts.tv_sec--; + } + + _TOD_Set( &ts ); + + _Thread_Enable_dispatch(); + + /* set the user's output */ + if ( olddelta ) + *olddelta = *delta; + + return 0; +} diff --git a/cpukit/posix/src/aio_cancel.c b/cpukit/posix/src/aio_cancel.c new file mode 100644 index 0000000000..56b7b01079 --- /dev/null +++ b/cpukit/posix/src/aio_cancel.c @@ -0,0 +1,126 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <rtems/posix/aio_misc.h> +#include <errno.h> +#include <stdlib.h> +#include <rtems/system.h> +#include <rtems/seterr.h> + +/* + * aio_cancel + * + * Cancel an asynchronous I/O request + * + * Input parameters: + * fildes - file descriptor + * aiocbp - asynchronous I/O control block + * + * Output parameters: + * AIO_CANCELED - if the requested operation(s) + * were canceled + * AIO_NOTCANCELED - if at least one of the requested + * operation(s) cannot be canceled + */ + + +int aio_cancel(int fildes, struct aiocb *aiocbp) +{ + rtems_aio_request_chain *r_chain; + int result; + + pthread_mutex_lock (&aio_request_queue.mutex); + + if (fcntl (fildes, F_GETFD) < 0) { + pthread_mutex_unlock(&aio_request_queue.mutex); + rtems_set_errno_and_return_minus_one (EBADF); + } + + /* if aiocbp is NULL remove all request for given file descriptor */ + if (aiocbp == NULL) { + AIO_printf ("Cancel all requests\n"); + + r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0); + if (r_chain == NULL) { + AIO_printf ("Request chain not on [WQ]\n"); + + if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) { + r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0); + if (r_chain == NULL) { + pthread_mutex_unlock(&aio_request_queue.mutex); + return AIO_ALLDONE; + } + + AIO_printf ("Request chain on [IQ]\n"); + + rtems_chain_extract (&r_chain->next_fd); + rtems_aio_remove_fd (r_chain); + pthread_mutex_destroy (&r_chain->mutex); + pthread_cond_destroy (&r_chain->mutex); + free (r_chain); + + pthread_mutex_unlock (&aio_request_queue.mutex); + return AIO_CANCELED; + } + + pthread_mutex_unlock (&aio_request_queue.mutex); + return AIO_ALLDONE; + } + + AIO_printf ("Request chain on [WQ]\n"); + + pthread_mutex_lock (&r_chain->mutex); + rtems_chain_extract (&r_chain->next_fd); + rtems_aio_remove_fd (r_chain); + pthread_mutex_unlock (&r_chain->mutex); + pthread_mutex_unlock (&aio_request_queue.mutex); + return AIO_CANCELED; + } else { + AIO_printf ("Cancel request\n"); + + if (aiocbp->aio_fildes != fildes) { + pthread_mutex_unlock (&aio_request_queue.mutex); + rtems_set_errno_and_return_minus_one (EINVAL); + } + + r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0); + if (r_chain == NULL) { + if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) { + r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0); + if (r_chain == NULL) { + pthread_mutex_unlock (&aio_request_queue.mutex); + rtems_set_errno_and_return_minus_one (EINVAL); + } + + AIO_printf ("Request on [IQ]\n"); + + result = rtems_aio_remove_req (&r_chain->perfd, aiocbp); + pthread_mutex_unlock (&aio_request_queue.mutex); + return result; + } else { + pthread_mutex_unlock (&aio_request_queue.mutex); + return AIO_ALLDONE; + } + } + AIO_printf ("Request on [WQ]\n"); + + pthread_mutex_lock (&r_chain->mutex); + result = rtems_aio_remove_req (&r_chain->perfd, aiocbp); + pthread_mutex_unlock (&r_chain->mutex); + pthread_mutex_unlock (&aio_request_queue.mutex); + return result; + } + return AIO_ALLDONE; +} diff --git a/cpukit/posix/src/aio_error.c b/cpukit/posix/src/aio_error.c new file mode 100644 index 0000000000..1c0e582bc9 --- /dev/null +++ b/cpukit/posix/src/aio_error.c @@ -0,0 +1,38 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> + +/* + * aio_error + * + * Retrieve errors status for an asynchronous I/O operation + * + * Input parameters: + * aiocbp - asynchronous I/O control block + * + * Output parameters: + * aiocbp->error_code + */ + + +int +aio_error (const struct aiocb *aiocbp) +{ + return aiocbp->error_code; +} diff --git a/cpukit/posix/src/aio_fsync.c b/cpukit/posix/src/aio_fsync.c new file mode 100644 index 0000000000..4a28b194b5 --- /dev/null +++ b/cpukit/posix/src/aio_fsync.c @@ -0,0 +1,63 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> +#include <stdlib.h> +#include <rtems/posix/aio_misc.h> +#include <rtems/system.h> +#include <rtems/seterr.h> + +/* + * aio_fsync + * + * Asynchronous file synchronization + * + * Input parameters: + * op - O_SYNC + * aiocbp - asynchronous I/O control block + * + * Output parameters: + * -1 - request could not pe enqueued + * - FD not opened for write + * - not enough memory + * - op is not O_SYNC + * 0 - otherwise + */ + +int aio_fsync( + int op, + struct aiocb *aiocbp +) +{ + rtems_aio_request *req; + int mode; + + if (op != O_SYNC) + rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp); + + mode = fcntl (aiocbp->aio_fildes, F_GETFL); + if (!(((mode & O_ACCMODE) == O_WRONLY) || ((mode & O_ACCMODE) == O_RDWR))) + rtems_aio_set_errno_return_minus_one (EBADF, aiocbp); + + req = malloc (sizeof (rtems_aio_request)); + if (req == NULL) + rtems_aio_set_errno_return_minus_one (EAGAIN, aiocbp); + + req->aiocbp = aiocbp; + req->aiocbp->aio_lio_opcode = LIO_SYNC; + + return rtems_aio_enqueue (req); + +} diff --git a/cpukit/posix/src/aio_misc.c b/cpukit/posix/src/aio_misc.c new file mode 100644 index 0000000000..fa731b8d90 --- /dev/null +++ b/cpukit/posix/src/aio_misc.c @@ -0,0 +1,556 @@ +/* + * Copyright 2010-2011, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include <pthread.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <rtems/posix/aio_misc.h> +#include <errno.h> + +static void *rtems_aio_handle (void *arg); + +rtems_aio_queue aio_request_queue; + +/* + * rtems_aio_init + * + * Initialize the request queue for aio + * + * Input parameters: + * NONE + * + * Output parameters: + * 0 - if initialization succeeded + */ + +int +rtems_aio_init (void) +{ + int result = 0; + + result = pthread_attr_init (&aio_request_queue.attr); + if (result != 0) + return result; + + result = + pthread_attr_setdetachstate (&aio_request_queue.attr, + PTHREAD_CREATE_DETACHED); + if (result != 0) + pthread_attr_destroy (&aio_request_queue.attr); + + + result = pthread_mutex_init (&aio_request_queue.mutex, NULL); + if (result != 0) + pthread_attr_destroy (&aio_request_queue.attr); + + + result = pthread_cond_init (&aio_request_queue.new_req, NULL); + if (result != 0) { + pthread_mutex_destroy (&aio_request_queue.mutex); + pthread_attr_destroy (&aio_request_queue.attr); + } + + rtems_chain_initialize_empty (&aio_request_queue.work_req); + rtems_chain_initialize_empty (&aio_request_queue.idle_req); + + aio_request_queue.active_threads = 0; + aio_request_queue.idle_threads = 0; + aio_request_queue.initialized = AIO_QUEUE_INITIALIZED; + + return result; +} + +/* + * rtems_aio_search_fd + * + * Search and create chain of requests for given FD + * + * Input parameters: + * chain - chain of FD chains + * fildes - file descriptor to search + * create - if 1 search and create + * - if 0 just search + * + * Output parameters: + * r_chain - NULL if create == 0 and there is + * no chain for given fildes + * - pointer to chain is there exists + * a chain for given fildes + * - pointer to newly create chain if + * create == 1 + * + */ + +rtems_aio_request_chain * +rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create) +{ + rtems_aio_request_chain *r_chain; + rtems_chain_node *node; + + node = rtems_chain_first (chain); + r_chain = (rtems_aio_request_chain *) node; + + while (r_chain->fildes < fildes && !rtems_chain_is_tail (chain, node)) { + node = rtems_chain_next (node); + r_chain = (rtems_aio_request_chain *) node; + } + + if (r_chain->fildes == fildes) + r_chain->new_fd = 0; + else { + if (create == 0) + r_chain = NULL; + else { + r_chain = malloc (sizeof (rtems_aio_request_chain)); + rtems_chain_initialize_empty (&r_chain->perfd); + + if (rtems_chain_is_empty (chain)) + rtems_chain_prepend (chain, &r_chain->next_fd); + else + rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd); + + r_chain->new_fd = 1; + r_chain->fildes = fildes; + } + } + return r_chain; +} + +/* + * rtems_aio_move_to_work + * + * Move chain of requests from IQ to WQ + * + * Input parameters: + * r_chain - chain of requests + * + * Output paramteres: + * NONE + */ + +void +rtems_aio_move_to_work (rtems_aio_request_chain *r_chain) +{ + rtems_aio_request_chain *temp; + rtems_chain_node *node; + + node = rtems_chain_first (&aio_request_queue.work_req); + temp = (rtems_aio_request_chain *) node; + + while (temp->fildes < r_chain->fildes && + !rtems_chain_is_tail (&aio_request_queue.work_req, node)) { + node = rtems_chain_next (node); + temp = (rtems_aio_request_chain *) node; + } + + rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd); +} + + +/* + * rtems_aio_insert_prio + * + * Add request to given FD chain. The chain is ordered + * by priority + * + * Input parameters: + * chain - chain of requests for a given FD + * req - request (see aio_misc.h) + * + * Output parameters: + * NONE + */ + +void +rtems_aio_insert_prio (rtems_chain_control *chain, rtems_aio_request *req) +{ + rtems_chain_node *node; + + AIO_printf ("FD exists \n"); + node = rtems_chain_first (chain); + + if (rtems_chain_is_empty (chain)) { + AIO_printf ("First in chain \n"); + rtems_chain_prepend (chain, &req->next_prio); + } else { + AIO_printf ("Add by priority \n"); + int prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio; + + while (req->aiocbp->aio_reqprio > prio && + !rtems_chain_is_tail (chain, node)) { + node = rtems_chain_next (node); + prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio; + } + + rtems_chain_insert (node->previous, &req->next_prio); + + } +} + +/* + * rtems_aio_remove_fd + * + * Removes all the requests in a fd chain + * + * Input parameters: + * r_chain - pointer to the fd chain request + * + * Output parameters: + * NONE + */ + +void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain) +{ + rtems_chain_control *chain; + rtems_chain_node *node; + chain = &r_chain->perfd; + node = rtems_chain_first (chain); + + while (!rtems_chain_is_tail (chain, node)) + { + rtems_chain_extract (node); + rtems_aio_request *req = (rtems_aio_request *) node; + node = rtems_chain_next (node); + req->aiocbp->error_code = ECANCELED; + req->aiocbp->return_value = -1; + free (req); + } +} + +/* + * rtems_aio_remove_req + * + * Removes request from given chain + * + * Input parameters: + * chain - pointer to fd chain which may contain + * the request + * aiocbp - pointer to request that needs to be + * canceled + * + * Output parameters: + * AIO_NOTCANCELED - if request was not canceled + * AIO_CANCELED - if request was canceled + */ + +int rtems_aio_remove_req (rtems_chain_control *chain, struct aiocb *aiocbp) +{ + if (rtems_chain_is_empty (chain)) + return AIO_ALLDONE; + + rtems_chain_node *node = rtems_chain_first (chain); + rtems_aio_request *current; + + current = (rtems_aio_request *) node; + + while (!rtems_chain_is_tail (chain, node) && current->aiocbp != aiocbp) { + node = rtems_chain_next (node); + current = (rtems_aio_request *) node; + } + + if (rtems_chain_is_tail (chain, node)) + return AIO_NOTCANCELED; + else + { + rtems_chain_extract (node); + current->aiocbp->error_code = ECANCELED; + current->aiocbp->return_value = -1; + free (current); + } + + return AIO_CANCELED; +} + +/* + * rtems_aio_enqueue + * + * Enqueue requests, and creates threads to process them + * + * Input parameters: + * req - see aio_misc.h + * + * Output parameters: + * 0 - if request was added to queue + * errno - otherwise + */ + +int +rtems_aio_enqueue (rtems_aio_request *req) +{ + + rtems_aio_request_chain *r_chain; + rtems_chain_control *chain; + pthread_t thid; + int result, policy; + struct sched_param param; + + /* The queue should be initialized */ + AIO_assert (aio_request_queue.initialized == AIO_QUEUE_INITIALIZED); + + result = pthread_mutex_lock (&aio_request_queue.mutex); + if (result != 0) { + free (req); + return result; + } + + /* _POSIX_PRIORITIZED_IO and _POSIX_PRIORITY_SCHEDULING are defined, + we can use aio_reqprio to lower the priority of the request */ + pthread_getschedparam (pthread_self(), &policy, ¶m); + + req->caller_thread = pthread_self (); + req->priority = param.sched_priority - req->aiocbp->aio_reqprio; + req->policy = policy; + req->aiocbp->error_code = EINPROGRESS; + req->aiocbp->return_value = 0; + + if ((aio_request_queue.idle_threads == 0) && + aio_request_queue.active_threads < AIO_MAX_THREADS) + /* we still have empty places on the active_threads chain */ + { + chain = &aio_request_queue.work_req; + r_chain = rtems_aio_search_fd (chain, req->aiocbp->aio_fildes, 1); + + if (r_chain->new_fd == 1) { + rtems_chain_prepend (&r_chain->perfd, &req->next_prio); + r_chain->new_fd = 0; + pthread_mutex_init (&r_chain->mutex, NULL); + pthread_cond_init (&r_chain->cond, NULL); + + AIO_printf ("New thread \n"); + result = pthread_create (&thid, &aio_request_queue.attr, + rtems_aio_handle, (void *) r_chain); + if (result != 0) { + pthread_mutex_unlock (&aio_request_queue.mutex); + return result; + } + ++aio_request_queue.active_threads; + } + else { + /* put request in the fd chain it belongs to */ + pthread_mutex_lock (&r_chain->mutex); + rtems_aio_insert_prio (&r_chain->perfd, req); + pthread_cond_signal (&r_chain->cond); + pthread_mutex_unlock (&r_chain->mutex); + } + } + else + { + /* the maximum number of threads has been already created + even though some of them might be idle. + The request belongs to one of the active fd chain */ + r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, + req->aiocbp->aio_fildes, 0); + if (r_chain != NULL) + { + pthread_mutex_lock (&r_chain->mutex); + rtems_aio_insert_prio (&r_chain->perfd, req); + pthread_cond_signal (&r_chain->cond); + pthread_mutex_unlock (&r_chain->mutex); + + } else { + + /* or to the idle chain */ + chain = &aio_request_queue.idle_req; + r_chain = rtems_aio_search_fd (chain, req->aiocbp->aio_fildes, 1); + + if (r_chain->new_fd == 1) { + /* If this is a new fd chain we signal the idle threads that + might be waiting for requests */ + AIO_printf (" New chain on waiting queue \n "); + rtems_chain_prepend (&r_chain->perfd, &req->next_prio); + r_chain->new_fd = 0; + pthread_mutex_init (&r_chain->mutex, NULL); + pthread_cond_init (&r_chain->cond, NULL); + } else + /* just insert the request in the existing fd chain */ + rtems_aio_insert_prio (&r_chain->perfd, req); + if (aio_request_queue.idle_threads > 0) + pthread_cond_signal (&aio_request_queue.new_req); + } + } + + pthread_mutex_unlock (&aio_request_queue.mutex); + return 0; +} + +/* + * rtems_aio_handle + * + * Thread processing requests + * + * Input parameters: + * arg - the chain for the fd to be worked on + * + * Output parameters: + * NULL - if error + */ + +static void * +rtems_aio_handle (void *arg) +{ + + rtems_aio_request_chain *r_chain = arg; + rtems_aio_request *req; + rtems_chain_control *chain; + rtems_chain_node *node; + int result, policy; + struct sched_param param; + + AIO_printf ("Thread started\n"); + + while (1) { + + /* acquire the mutex of the current fd chain. + we don't need to lock the queue mutex since we can + add requests to idle fd chains or even active ones + if the working request has been extracted from the + chain */ + result = pthread_mutex_lock (&r_chain->mutex); + if (result != 0) + return NULL; + + chain = &r_chain->perfd; + + /* If the locked chain is not empty, take the first + request extract it, unlock the chain and process + the request, in this way the user can supply more + requests to this fd chain */ + if (!rtems_chain_is_empty (chain)) { + + AIO_printf ("Get new request from not empty chain\n"); + node = rtems_chain_first (chain); + req = (rtems_aio_request *) node; + + /* See _POSIX_PRIORITIZE_IO and _POSIX_PRIORITY_SCHEDULING + discussion in rtems_aio_enqueue () */ + pthread_getschedparam (pthread_self(), &policy, ¶m); + param.sched_priority = req->priority; + pthread_setschedparam (pthread_self(), req->policy, ¶m); + + rtems_chain_extract (node); + + pthread_mutex_unlock (&r_chain->mutex); + + switch (req->aiocbp->aio_lio_opcode) { + case LIO_READ: + AIO_printf ("read\n"); + result = pread (req->aiocbp->aio_fildes, + (void *) req->aiocbp->aio_buf, + req->aiocbp->aio_nbytes, req->aiocbp->aio_offset); + break; + + case LIO_WRITE: + AIO_printf ("write\n"); + result = pwrite (req->aiocbp->aio_fildes, + (void *) req->aiocbp->aio_buf, + req->aiocbp->aio_nbytes, req->aiocbp->aio_offset); + break; + + case LIO_SYNC: + AIO_printf ("sync\n"); + result = fsync (req->aiocbp->aio_fildes); + break; + + default: + result = -1; + } + if (result == -1) { + req->aiocbp->return_value = -1; + req->aiocbp->error_code = errno; + } else { + req->aiocbp->return_value = result; + req->aiocbp->error_code = 0; + } + + // notification needed for lio + + } else { + /* If the fd chain is empty we unlock the fd chain + and we lock the queue chain, this will ensure that + we have at most one request comming to our fd chain + when we check. + + If there was no request added sleep for 3 seconds and + wait for a signal on chain, this will unlock the queue. + The fd chain is already unlocked */ + + struct timespec timeout; + + AIO_printf ("Chain is empty [WQ], wait for work\n"); + + pthread_mutex_unlock (&r_chain->mutex); + pthread_mutex_lock (&aio_request_queue.mutex); + + if (rtems_chain_is_empty (chain)) + { + clock_gettime (CLOCK_REALTIME, &timeout); + timeout.tv_sec += 3; + timeout.tv_nsec = 0; + result = pthread_cond_timedwait (&r_chain->cond, + &aio_request_queue.mutex, + &timeout); + + /* If no requests were added to the chain we delete the fd chain from + the queue and start working with idle fd chains */ + if (result == ETIMEDOUT) { + rtems_chain_extract (&r_chain->next_fd); + pthread_mutex_destroy (&r_chain->mutex); + pthread_cond_destroy (&r_chain->cond); + free (r_chain); + + /* If the idle chain is empty sleep for 3 seconds and wait for a + signal. The thread now becomes idle. */ + if (rtems_chain_is_empty (&aio_request_queue.idle_req)) { + AIO_printf ("Chain is empty [IQ], wait for work\n"); + + ++aio_request_queue.idle_threads; + --aio_request_queue.active_threads; + clock_gettime (CLOCK_REALTIME, &timeout); + timeout.tv_sec += 3; + timeout.tv_nsec = 0; + + result = pthread_cond_timedwait (&aio_request_queue.new_req, + &aio_request_queue.mutex, + &timeout); + + /* If no new fd chain was added in the idle requests + then this thread is finished */ + if (result == ETIMEDOUT) { + AIO_printf ("Etimeout\n"); + --aio_request_queue.idle_threads; + pthread_mutex_unlock (&aio_request_queue.mutex); + return NULL; + } + } + /* Otherwise move this chain to the working chain and + start the loop all over again */ + AIO_printf ("Work on idle\n"); + --aio_request_queue.idle_threads; + ++aio_request_queue.active_threads; + + node = rtems_chain_first (&aio_request_queue.idle_req); + rtems_chain_extract (node); + + r_chain = (rtems_aio_request_chain *) node; + rtems_aio_move_to_work (r_chain); + + } + } + /* If there was a request added in the initial fd chain then release + the mutex and process it */ + pthread_mutex_unlock (&aio_request_queue.mutex); + + } + } + + AIO_printf ("Thread finished\n"); + return NULL; +} diff --git a/cpukit/posix/src/aio_read.c b/cpukit/posix/src/aio_read.c new file mode 100644 index 0000000000..43536fff74 --- /dev/null +++ b/cpukit/posix/src/aio_read.c @@ -0,0 +1,65 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> +#include <fcntl.h> +#include <rtems/posix/aio_misc.h> +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <stdlib.h> + +/* + * aio_read + * + * Asynchronous write to a file + * + * Input parameters: + * aiocbp - asynchronous I/O control block + * + * Output parameters: + * -1 - request could not pe enqueued + * - FD not opened for write + * - invalid aio_reqprio or aio_offset or + * aio_nbytes + * - not enough memory + * 0 - otherwise + */ + +int +aio_read (struct aiocb *aiocbp) +{ + rtems_aio_request *req; + int mode; + + mode = fcntl (aiocbp->aio_fildes, F_GETFL); + if (!(((mode & O_ACCMODE) == O_RDONLY) || ((mode & O_ACCMODE) == O_RDWR))) + rtems_aio_set_errno_return_minus_one (EBADF, aiocbp); + + if (aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX) + rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp); + + if (aiocbp->aio_offset < 0) + rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp); + + req = malloc (sizeof (rtems_aio_request)); + if (req == NULL) + rtems_aio_set_errno_return_minus_one (EAGAIN, aiocbp); + + req->aiocbp = aiocbp; + req->aiocbp->aio_lio_opcode = LIO_READ; + + return rtems_aio_enqueue (req); +} diff --git a/cpukit/posix/src/aio_return.c b/cpukit/posix/src/aio_return.c new file mode 100644 index 0000000000..2a9e56ae7a --- /dev/null +++ b/cpukit/posix/src/aio_return.c @@ -0,0 +1,37 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> + +/* + * aio_return + * + * Retrieve return status of an asynchronous I/O operation + * + * Input parameters: + * aiocbp - asynchronous I/O control block + * + * Output parameters: + * aiocbp->return_value + */ + +ssize_t +aio_return (const struct aiocb *aiocbp) +{ + return aiocbp->return_value; +} diff --git a/cpukit/posix/src/aio_suspend.c b/cpukit/posix/src/aio_suspend.c new file mode 100644 index 0000000000..28ed3565e5 --- /dev/null +++ b/cpukit/posix/src/aio_suspend.c @@ -0,0 +1,31 @@ +/* + * 6.7.7 Wait for Asynchronous I/O Request, P1003.1b-1993, p. 164 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> + +int aio_suspend( + const struct aiocb * const list[] __attribute__((unused)), + int nent __attribute__((unused)), + const struct timespec *timeout __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/aio_write.c b/cpukit/posix/src/aio_write.c new file mode 100644 index 0000000000..03f6b90c64 --- /dev/null +++ b/cpukit/posix/src/aio_write.c @@ -0,0 +1,65 @@ +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> +#include <fcntl.h> +#include <rtems/posix/aio_misc.h> +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <stdlib.h> + +/* + * aio_write + * + * Asynchronous write to a file + * + * Input parameters: + * aiocbp - asynchronous I/O control block + * + * Output parameters: + * -1 - request could not be enqueued + * - FD not opened for write + * - invalid aio_reqprio or aio_offset or + * aio_nbytes + * - not enough memory + * 0 - otherwise + */ + +int +aio_write (struct aiocb *aiocbp) +{ + rtems_aio_request *req; + int mode; + + mode = fcntl (aiocbp->aio_fildes, F_GETFL); + if (!(((mode & O_ACCMODE) == O_WRONLY) || ((mode & O_ACCMODE) == O_RDWR))) + rtems_aio_set_errno_return_minus_one (EBADF, aiocbp); + + if (aiocbp->aio_reqprio < 0 || aiocbp->aio_reqprio > AIO_PRIO_DELTA_MAX) + rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp); + + if (aiocbp->aio_offset < 0) + rtems_aio_set_errno_return_minus_one (EINVAL, aiocbp); + + req = malloc (sizeof (rtems_aio_request)); + if (req == NULL) + rtems_aio_set_errno_return_minus_one (EAGAIN, aiocbp); + + req->aiocbp = aiocbp; + req->aiocbp->aio_lio_opcode = LIO_WRITE; + + return rtems_aio_enqueue (req); +} diff --git a/cpukit/posix/src/alarm.c b/cpukit/posix/src/alarm.c new file mode 100644 index 0000000000..ec381878a5 --- /dev/null +++ b/cpukit/posix/src/alarm.c @@ -0,0 +1,76 @@ +/* + * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79 + */ + +/* COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +/*PAGE + * + * _POSIX_signals_Alarm_TSR + */ + +void _POSIX_signals_Alarm_TSR( + Objects_Id id __attribute__((unused)), + void *argument __attribute__((unused)) +) +{ + int status; + + status = kill( getpid(), SIGALRM ); + /* XXX can't print from an ISR, should this be fatal? */ +} + +unsigned int alarm( + unsigned int seconds +) +{ + unsigned int remaining = 0; + Watchdog_Control *the_timer; + + the_timer = &_POSIX_signals_Alarm_timer; + + /* + * Initialize the timer used to implement alarm(). + */ + + if ( !the_timer->routine ) { + _Watchdog_Initialize( the_timer, _POSIX_signals_Alarm_TSR, 0, NULL ); + } else { + Watchdog_States state; + + state = _Watchdog_Remove( the_timer ); + if ( (state == WATCHDOG_ACTIVE) || (state == WATCHDOG_REMOVE_IT) ) { + /* + * The stop_time and start_time fields are snapshots of ticks since + * boot. Since alarm() is dealing in seconds, we must account for + * this. + */ + + remaining = the_timer->initial - + ((the_timer->stop_time - the_timer->start_time) / TOD_TICKS_PER_SECOND); + } + } + + if ( seconds ) + _Watchdog_Insert_seconds( the_timer, seconds ); + + return remaining; +} diff --git a/cpukit/posix/src/barrierattrdestroy.c b/cpukit/posix/src/barrierattrdestroy.c new file mode 100644 index 0000000000..8821866af9 --- /dev/null +++ b/cpukit/posix/src/barrierattrdestroy.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*PAGE + * + * Barrier Initialization Attributes + */ + +int pthread_barrierattr_destroy( + pthread_barrierattr_t *attr +) +{ + if ( !attr || attr->is_initialized == false ) + return EINVAL; + + attr->is_initialized = false; + return 0; +} diff --git a/cpukit/posix/src/barrierattrgetpshared.c b/cpukit/posix/src/barrierattrgetpshared.c new file mode 100644 index 0000000000..0d8d7f1d33 --- /dev/null +++ b/cpukit/posix/src/barrierattrgetpshared.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +/*PAGE + * + * Barrier Attributes Get Process Shared + */ + +int pthread_barrierattr_getpshared( + const pthread_barrierattr_t *attr, + int *pshared +) +{ + if ( !attr ) + return EINVAL; + + if ( !attr->is_initialized ) + return EINVAL; + + *pshared = attr->process_shared; + return 0; +} diff --git a/cpukit/posix/src/barrierattrinit.c b/cpukit/posix/src/barrierattrinit.c new file mode 100644 index 0000000000..b1a6e980c9 --- /dev/null +++ b/cpukit/posix/src/barrierattrinit.c @@ -0,0 +1,36 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> + +/*PAGE + * + * Barrier Attributes Initialization + */ + +int pthread_barrierattr_init( + pthread_barrierattr_t *attr +) +{ + if ( !attr ) + return EINVAL; + + attr->is_initialized = true; + attr->process_shared = PTHREAD_PROCESS_PRIVATE; + return 0; +} diff --git a/cpukit/posix/src/barrierattrsetpshared.c b/cpukit/posix/src/barrierattrsetpshared.c new file mode 100644 index 0000000000..a899bb91c2 --- /dev/null +++ b/cpukit/posix/src/barrierattrsetpshared.c @@ -0,0 +1,44 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +/*PAGE + * + * Barrier Attributes Set Process Shared + */ + +int pthread_barrierattr_setpshared( + pthread_barrierattr_t *attr, + int pshared +) +{ + if ( !attr ) + return EINVAL; + + if ( !attr->is_initialized ) + return EINVAL; + + switch ( pshared ) { + case PTHREAD_PROCESS_SHARED: + case PTHREAD_PROCESS_PRIVATE: + attr->process_shared = pshared; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/cancel.c b/cpukit/posix/src/cancel.c new file mode 100644 index 0000000000..0167c0a328 --- /dev/null +++ b/cpukit/posix/src/cancel.c @@ -0,0 +1,67 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +/* + * 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_Control *thread_support; + Objects_Locations location; + + /* + * Don't even think about deleting a resource from an ISR. + */ + + if ( _ISR_Is_in_progress() ) + return EPROTO; + + the_thread = _Thread_Get( thread, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + thread_support->cancelation_requested = 1; + + /* This enables dispatch implicitly */ + _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( the_thread ); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/canceleval.c b/cpukit/posix/src/canceleval.c new file mode 100644 index 0000000000..f2e6d9c4c8 --- /dev/null +++ b/cpukit/posix/src/canceleval.c @@ -0,0 +1,38 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> + +void _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch( + Thread_Control *the_thread +) +{ + POSIX_API_Control *thread_support; + + thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && + thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS && + thread_support->cancelation_requested ) { + _Thread_Unnest_dispatch(); + _POSIX_Thread_Exit( the_thread, PTHREAD_CANCELED ); + } else + _Thread_Enable_dispatch(); + +} diff --git a/cpukit/posix/src/cancelrun.c b/cpukit/posix/src/cancelrun.c new file mode 100644 index 0000000000..8ac96a762d --- /dev/null +++ b/cpukit/posix/src/cancelrun.c @@ -0,0 +1,54 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +void _POSIX_Threads_cancel_run( + Thread_Control *the_thread +) +{ + POSIX_Cancel_Handler_control *handler; + Chain_Control *handler_stack; + POSIX_API_Control *thread_support; + ISR_Level level; + + thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + handler_stack = &thread_support->Cancellation_Handlers; + + 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 )->previous; + _Chain_Extract_unprotected( &handler->Node ); + _ISR_Enable( level ); + + (*handler->routine)( handler->arg ); + + _Workspace_Free( handler ); + } +} diff --git a/cpukit/posix/src/cleanuppop.c b/cpukit/posix/src/cleanuppop.c new file mode 100644 index 0000000000..cc327fa33d --- /dev/null +++ b/cpukit/posix/src/cleanuppop.c @@ -0,0 +1,77 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +/*PAGE + * + * 18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184 + */ + +void pthread_cleanup_pop( + int execute +) +{ + POSIX_Cancel_Handler_control *handler; + POSIX_Cancel_Handler_control tmp_handler; + Chain_Control *handler_stack; + POSIX_API_Control *thread_support; + ISR_Level level; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + handler_stack = &thread_support->Cancellation_Handlers; + + /* + * We need interrupts disabled to safely check the chain and pull + * the last element off. But we also need dispatching disabled to + * ensure that we do not get prempted and deleted while we are holding + * memory that needs to be freed. + */ + + _Thread_Disable_dispatch(); + _ISR_Disable( level ); + + if ( _Chain_Is_empty( handler_stack ) ) { + _Thread_Enable_dispatch(); + _ISR_Enable( level ); + return; + } + + handler = (POSIX_Cancel_Handler_control *) + _Chain_Tail( handler_stack )->previous; + _Chain_Extract_unprotected( &handler->Node ); + + _ISR_Enable( level ); + + tmp_handler = *handler; + + _Workspace_Free( handler ); + + _Thread_Enable_dispatch(); + + if ( execute ) + (*tmp_handler.routine)( tmp_handler.arg ); +} diff --git a/cpukit/posix/src/cleanuppush.c b/cpukit/posix/src/cleanuppush.c new file mode 100644 index 0000000000..71079200ef --- /dev/null +++ b/cpukit/posix/src/cleanuppush.c @@ -0,0 +1,64 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +/*PAGE + * + * 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_Control *thread_support; + + /* + * The POSIX standard does not address what to do when the routine + * is NULL. It also does not address what happens when we cannot + * allocate memory or anything else bad happens. + */ + if ( !routine ) + return; + + _Thread_Disable_dispatch(); + handler = _Workspace_Allocate( sizeof( POSIX_Cancel_Handler_control ) ); + + if ( handler ) { + 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 ); + } + _Thread_Enable_dispatch(); +} diff --git a/cpukit/posix/src/clockgetcpuclockid.c b/cpukit/posix/src/clockgetcpuclockid.c new file mode 100644 index 0000000000..b4472f8a10 --- /dev/null +++ b/cpukit/posix/src/clockgetcpuclockid.c @@ -0,0 +1,38 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 20.1.3 Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55 + */ + +int clock_getcpuclockid( + pid_t pid, + clockid_t *clock_id +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/clockgetenableattr.c b/cpukit/posix/src/clockgetenableattr.c new file mode 100644 index 0000000000..95efe0de3b --- /dev/null +++ b/cpukit/posix/src/clockgetenableattr.c @@ -0,0 +1,38 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58 + */ + +int clock_getenable_attr( + clockid_t clock_id, + int *attr +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/clockgetres.c b/cpukit/posix/src/clockgetres.c new file mode 100644 index 0000000000..7507bee614 --- /dev/null +++ b/cpukit/posix/src/clockgetres.c @@ -0,0 +1,65 @@ +/* + * $Id$ + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> + +/*PAGE + * + * 14.2.1 Clocks, P1003.1b-1993, p. 263 + */ + +int clock_getres( + clockid_t clock_id, + struct timespec *res +) +{ + if ( !res ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + switch ( clock_id ) { + + /* + * All time in rtems is based on the same clock tick. + */ + + case CLOCK_REALTIME: + case CLOCK_PROCESS_CPUTIME: + case CLOCK_THREAD_CPUTIME: + if ( res ) { + res->tv_sec = rtems_configuration_get_microseconds_per_tick() / + TOD_MICROSECONDS_PER_SECOND; + res->tv_nsec = rtems_configuration_get_nanoseconds_per_tick(); + } + break; + + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + + } + return 0; +} diff --git a/cpukit/posix/src/clockgettime.c b/cpukit/posix/src/clockgettime.c new file mode 100644 index 0000000000..852ac8e039 --- /dev/null +++ b/cpukit/posix/src/clockgettime.c @@ -0,0 +1,65 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> + +/*PAGE + * + * 14.2.1 Clocks, P1003.1b-1993, p. 263 + */ + +int clock_gettime( + clockid_t clock_id, + struct timespec *tp +) +{ + if ( !tp ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( clock_id == CLOCK_REALTIME ) { + _TOD_Get(tp); + return 0; + } +#ifdef CLOCK_MONOTONIC + if ( clock_id == CLOCK_MONOTONIC ) { + _TOD_Get_uptime_as_timespec( tp ); + return 0; + } +#endif + +#ifdef _POSIX_CPUTIME + if ( clock_id == CLOCK_PROCESS_CPUTIME ) { + _TOD_Get_uptime_as_timespec( tp ); + return 0; + } +#endif + +#ifdef _POSIX_THREAD_CPUTIME + if ( clock_id == CLOCK_THREAD_CPUTIME ) + rtems_set_errno_and_return_minus_one( ENOSYS ); +#endif + + rtems_set_errno_and_return_minus_one( EINVAL ); + + return 0; +} diff --git a/cpukit/posix/src/clocksetenableattr.c b/cpukit/posix/src/clocksetenableattr.c new file mode 100644 index 0000000000..f11f8d14e8 --- /dev/null +++ b/cpukit/posix/src/clocksetenableattr.c @@ -0,0 +1,38 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58 + */ + +int clock_setenable_attr( + clockid_t clock_id, + int attr +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/clocksettime.c b/cpukit/posix/src/clocksettime.c new file mode 100644 index 0000000000..aa3743d9f9 --- /dev/null +++ b/cpukit/posix/src/clocksettime.c @@ -0,0 +1,59 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> + +/*PAGE + * + * 14.2.1 Clocks, P1003.1b-1993, p. 263 + */ + +int clock_settime( + clockid_t clock_id, + const struct timespec *tp +) +{ + if ( !tp ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( clock_id == CLOCK_REALTIME ) { + if ( tp->tv_sec < TOD_SECONDS_1970_THROUGH_1988 ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + _Thread_Disable_dispatch(); + _TOD_Set( tp ); + _Thread_Enable_dispatch(); + } +#ifdef _POSIX_CPUTIME + else if ( clock_id == CLOCK_PROCESS_CPUTIME ) + rtems_set_errno_and_return_minus_one( ENOSYS ); +#endif +#ifdef _POSIX_THREAD_CPUTIME + else if ( clock_id == CLOCK_THREAD_CPUTIME ) + rtems_set_errno_and_return_minus_one( ENOSYS ); +#endif + else + rtems_set_errno_and_return_minus_one( EINVAL ); + + return 0; +} diff --git a/cpukit/posix/src/cond.c b/cpukit/posix/src/cond.c new file mode 100644 index 0000000000..954fb34b78 --- /dev/null +++ b/cpukit/posix/src/cond.c @@ -0,0 +1,59 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*PAGE + * + * _POSIX_Condition_variables_Manager_initialization + * + * This routine initializes all condition variable manager related data + * structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _POSIX_Condition_variables_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Condition_variables_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_CONDITION_VARIABLES, /* object class */ + Configuration_POSIX_API.maximum_condition_variables, + /* maximum objects of this class */ + sizeof( POSIX_Condition_variables_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/condattrdestroy.c b/cpukit/posix/src/condattrdestroy.c new file mode 100644 index 0000000000..821f93fba9 --- /dev/null +++ b/cpukit/posix/src/condattrdestroy.c @@ -0,0 +1,42 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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; +} diff --git a/cpukit/posix/src/condattrgetpshared.c b/cpukit/posix/src/condattrgetpshared.c new file mode 100644 index 0000000000..0710fcc120 --- /dev/null +++ b/cpukit/posix/src/condattrgetpshared.c @@ -0,0 +1,43 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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; +} diff --git a/cpukit/posix/src/condattrinit.c b/cpukit/posix/src/condattrinit.c new file mode 100644 index 0000000000..f06683ad47 --- /dev/null +++ b/cpukit/posix/src/condattrinit.c @@ -0,0 +1,42 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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; +} diff --git a/cpukit/posix/src/condattrsetpshared.c b/cpukit/posix/src/condattrsetpshared.c new file mode 100644 index 0000000000..33a4d28a7c --- /dev/null +++ b/cpukit/posix/src/condattrsetpshared.c @@ -0,0 +1,50 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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; + + switch ( pshared ) { + case PTHREAD_PROCESS_SHARED: + case PTHREAD_PROCESS_PRIVATE: + attr->process_shared = pshared; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/condbroadcast.c b/cpukit/posix/src/condbroadcast.c new file mode 100644 index 0000000000..73875f7952 --- /dev/null +++ b/cpukit/posix/src/condbroadcast.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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 ); +} diff --git a/cpukit/posix/src/conddefaultattributes.c b/cpukit/posix/src/conddefaultattributes.c new file mode 100644 index 0000000000..7d83bf473c --- /dev/null +++ b/cpukit/posix/src/conddefaultattributes.c @@ -0,0 +1,35 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*PAGE + * + * The default condition variable attributes structure. + */ + +const pthread_condattr_t _POSIX_Condition_variables_Default_attributes = { + true, /* is_initialized */ + PTHREAD_PROCESS_PRIVATE /* process_shared */ +}; diff --git a/cpukit/posix/src/conddestroy.c b/cpukit/posix/src/conddestroy.c new file mode 100644 index 0000000000..d01364f0ef --- /dev/null +++ b/cpukit/posix/src/conddestroy.c @@ -0,0 +1,67 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*PAGE + * + * 11.4.2 Initializing and Destroying a Condition Variable, + * P1003.1c/Draft 10, p. 87 + */ + +int pthread_cond_destroy( + pthread_cond_t *cond +) +{ + POSIX_Condition_variables_Control *the_cond; + Objects_Locations location; + + the_cond = _POSIX_Condition_variables_Get( cond, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + if ( _Thread_queue_First( &the_cond->Wait_queue ) ) { + _Thread_Enable_dispatch(); + return EBUSY; + } + + _Objects_Close( + &_POSIX_Condition_variables_Information, + &the_cond->Object + ); + + _POSIX_Condition_variables_Free( the_cond ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/condget.c b/cpukit/posix/src/condget.c new file mode 100644 index 0000000000..0305b45e3b --- /dev/null +++ b/cpukit/posix/src/condget.c @@ -0,0 +1,60 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get ( + pthread_cond_t *cond, + Objects_Locations *location +) +{ + int status; + + if ( !cond ) { + *location = OBJECTS_ERROR; + return (POSIX_Condition_variables_Control *) 0; + } + + if ( *cond == PTHREAD_COND_INITIALIZER ) { + /* + * Do an "auto-create" here. + */ + + status = pthread_cond_init( cond, 0 ); + if ( status ) { + *location = OBJECTS_ERROR; + return (POSIX_Condition_variables_Control *) 0; + } + } + + /* + * Now call Objects_Get() + */ + return (POSIX_Condition_variables_Control *)_Objects_Get( + &_POSIX_Condition_variables_Information, + (Objects_Id) *cond, + location + ); +} + diff --git a/cpukit/posix/src/condinit.c b/cpukit/posix/src/condinit.c new file mode 100644 index 0000000000..8bdbe2be00 --- /dev/null +++ b/cpukit/posix/src/condinit.c @@ -0,0 +1,84 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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; + + /* + * Be careful about attributes when global!!! + */ + if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED ) + return EINVAL; + + if ( !the_attr->is_initialized ) + return EINVAL; + + _Thread_Disable_dispatch(); + + the_cond = _POSIX_Condition_variables_Allocate(); + + if ( !the_cond ) { + _Thread_Enable_dispatch(); + return ENOMEM; + } + + the_cond->process_shared = the_attr->process_shared; + + the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX; + + _Thread_queue_Initialize( + &the_cond->Wait_queue, + THREAD_QUEUE_DISCIPLINE_FIFO, + STATES_WAITING_FOR_CONDITION_VARIABLE | STATES_INTERRUPTIBLE_BY_SIGNAL, + ETIMEDOUT + ); + + _Objects_Open_u32( + &_POSIX_Condition_variables_Information, + &the_cond->Object, + 0 + ); + + *cond = the_cond->Object.id; + + _Thread_Enable_dispatch(); + + return 0; +} diff --git a/cpukit/posix/src/condsignal.c b/cpukit/posix/src/condsignal.c new file mode 100644 index 0000000000..fd607fd641 --- /dev/null +++ b/cpukit/posix/src/condsignal.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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 ); +} diff --git a/cpukit/posix/src/condsignalsupp.c b/cpukit/posix/src/condsignalsupp.c new file mode 100644 index 0000000000..47e23b5b8e --- /dev/null +++ b/cpukit/posix/src/condsignalsupp.c @@ -0,0 +1,66 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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, + bool 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_LOCAL: + do { + the_thread = _Thread_queue_Dequeue( &the_cond->Wait_queue ); + if ( !the_thread ) + the_cond->Mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX; + } while ( is_broadcast && the_thread ); + + _Thread_Enable_dispatch(); + + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/condtimedwait.c b/cpukit/posix/src/condtimedwait.c new file mode 100644 index 0000000000..4134a73f8a --- /dev/null +++ b/cpukit/posix/src/condtimedwait.c @@ -0,0 +1,70 @@ +/* + * $Id$ + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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 +) +{ + Watchdog_Interval ticks; + bool already_timedout; + POSIX_Absolute_timeout_conversion_results_t status; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + */ + already_timedout = false; + status = _POSIX_Absolute_timeout_to_ticks(abstime, &ticks); + if ( status == POSIX_ABSOLUTE_TIMEOUT_INVALID ) + return EINVAL; + + if ( status == POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST || + status == POSIX_ABSOLUTE_TIMEOUT_IS_NOW ) + already_timedout = true; + + return _POSIX_Condition_variables_Wait_support( + cond, + mutex, + ticks, + already_timedout + ); +} diff --git a/cpukit/posix/src/condwait.c b/cpukit/posix/src/condwait.c new file mode 100644 index 0000000000..2d925a3b80 --- /dev/null +++ b/cpukit/posix/src/condwait.c @@ -0,0 +1,43 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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, + false + ); +} diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c new file mode 100644 index 0000000000..745d224d3d --- /dev/null +++ b/cpukit/posix/src/condwaitsupp.c @@ -0,0 +1,122 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*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, + bool already_timedout +) +{ + register POSIX_Condition_variables_Control *the_cond; + Objects_Locations location; + int status; + int mutex_status; + + if ( !_POSIX_Mutex_Get( mutex, &location ) ) { + return EINVAL; + } + + _Thread_Unnest_dispatch(); + + the_cond = _POSIX_Condition_variables_Get( cond, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + if ( the_cond->Mutex && ( the_cond->Mutex != *mutex ) ) { + _Thread_Enable_dispatch(); + return EINVAL; + } + + (void) pthread_mutex_unlock( mutex ); +/* XXX ignore this for now since behavior is undefined + if ( mutex_status ) { + _Thread_Enable_dispatch(); + return EINVAL; + } +*/ + + if ( !already_timedout ) { + the_cond->Mutex = *mutex; + + _Thread_queue_Enter_critical_section( &the_cond->Wait_queue ); + _Thread_Executing->Wait.return_code = 0; + _Thread_Executing->Wait.queue = &the_cond->Wait_queue; + _Thread_Executing->Wait.id = *cond; + + _Thread_queue_Enqueue( &the_cond->Wait_queue, timeout ); + + _Thread_Enable_dispatch(); + + /* + * Switch ourself out because we blocked as a result of the + * _Thread_queue_Enqueue. + */ + + /* + * If the thread is interrupted, while in the thread queue, by + * a POSIX signal, then pthread_cond_wait returns spuriously, + * according to the POSIX standard. It means that pthread_cond_wait + * returns a success status, except for the fact that it was not + * woken up a pthread_cond_signal or a pthread_cond_broadcast. + */ + status = _Thread_Executing->Wait.return_code; + if ( status == EINTR ) + status = 0; + + } else { + _Thread_Enable_dispatch(); + status = ETIMEDOUT; + } + + /* + * When we get here the dispatch disable level is 0. + */ + + mutex_status = pthread_mutex_lock( mutex ); + if ( mutex_status ) + return EINVAL; + + return status; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/execl.c b/cpukit/posix/src/execl.c new file mode 100644 index 0000000000..9edaba341d --- /dev/null +++ b/cpukit/posix/src/execl.c @@ -0,0 +1,32 @@ +/* + * execl() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_EXECL + +#include <errno.h> +#include <rtems/seterr.h> + +int execl( + const char *path, + const char *arg, + ... +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} + +#endif diff --git a/cpukit/posix/src/execle.c b/cpukit/posix/src/execle.c new file mode 100644 index 0000000000..947a4e104f --- /dev/null +++ b/cpukit/posix/src/execle.c @@ -0,0 +1,32 @@ +/* + * execle() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_EXECLE + +#include <errno.h> +#include <rtems/seterr.h> + +int execle( + const char *path, + char const *arg, + ... +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} + +#endif diff --git a/cpukit/posix/src/execlp.c b/cpukit/posix/src/execlp.c new file mode 100644 index 0000000000..fabc6986bb --- /dev/null +++ b/cpukit/posix/src/execlp.c @@ -0,0 +1,32 @@ +/* + * execlp() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_EXECLP + +#include <errno.h> +#include <rtems/seterr.h> + +int execlp( + const char *file, + const char *arg, + ... +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} + +#endif diff --git a/cpukit/posix/src/execv.c b/cpukit/posix/src/execv.c new file mode 100644 index 0000000000..46595232ad --- /dev/null +++ b/cpukit/posix/src/execv.c @@ -0,0 +1,31 @@ +/* + * execv() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_EXECV + +#include <errno.h> +#include <rtems/seterr.h> + +int execv( + const char *file, + char *const argv[] +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} + +#endif diff --git a/cpukit/posix/src/execve.c b/cpukit/posix/src/execve.c new file mode 100644 index 0000000000..b89009866e --- /dev/null +++ b/cpukit/posix/src/execve.c @@ -0,0 +1,32 @@ +/* + * execve() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_EXECVE + +#include <errno.h> +#include <rtems/seterr.h> + +int execve( + const char *path, + char *const argv[], + char *const envp[] +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} + +#endif diff --git a/cpukit/posix/src/execvp.c b/cpukit/posix/src/execvp.c new file mode 100644 index 0000000000..720543fcdf --- /dev/null +++ b/cpukit/posix/src/execvp.c @@ -0,0 +1,31 @@ +/* + * execvp() - POSIX 1003.1b 3.1.2 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_EXECVP + +#include <errno.h> +#include <rtems/seterr.h> + +int execvp( + const char *path, + char *const argv[] +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} + +#endif diff --git a/cpukit/posix/src/fork.c b/cpukit/posix/src/fork.c new file mode 100644 index 0000000000..f0023e2978 --- /dev/null +++ b/cpukit/posix/src/fork.c @@ -0,0 +1,25 @@ +/* + * fork() - POSIX 1003.1b 3.1.1 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <errno.h> +#include <rtems/seterr.h> + +int fork( void ) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/getitimer.c b/cpukit/posix/src/getitimer.c new file mode 100644 index 0000000000..8d1bb97904 --- /dev/null +++ b/cpukit/posix/src/getitimer.c @@ -0,0 +1,39 @@ +/* + * COPYRIGHT (c) 1989-20089 + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <sys/time.h> +#include <errno.h> +#include <rtems/seterr.h> + +int getitimer( + int which, + struct itimerval *value +) +{ + if ( !value ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + switch ( which ) { + case ITIMER_REAL: + case ITIMER_VIRTUAL: + case ITIMER_PROF: + rtems_set_errno_and_return_minus_one( ENOSYS ); + default: + break; + } + rtems_set_errno_and_return_minus_one( EINVAL ); +} + diff --git a/cpukit/posix/src/key.c b/cpukit/posix/src/key.c new file mode 100644 index 0000000000..a32853cac4 --- /dev/null +++ b/cpukit/posix/src/key.c @@ -0,0 +1,58 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <string.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/key.h> + +/* + * _POSIX_Key_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _POSIX_Key_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Keys_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_KEYS, /* object class */ + Configuration_POSIX_API.maximum_keys, + /* maximum objects of this class */ + sizeof( POSIX_Keys_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/keycreate.c b/cpukit/posix/src/keycreate.c new file mode 100644 index 0000000000..1fc87641e5 --- /dev/null +++ b/cpukit/posix/src/keycreate.c @@ -0,0 +1,99 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <string.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/key.h> + +/* + * 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; + uint32_t the_api; + uint32_t bytes_to_allocate; + + + _Thread_Disable_dispatch(); + + the_key = _POSIX_Keys_Allocate(); + + if ( !the_key ) { + _Thread_Enable_dispatch(); + return EAGAIN; + } + + the_key->destructor = destructor; + + /* + * This is a bit more complex than one might initially expect because + * APIs are optional. + * + * NOTE: Currently RTEMS Classic API tasks are always enabled. + */ + for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ ) { + the_key->Values[ the_api ] = NULL; + + #if defined(RTEMS_DEBUG) + /* + * Since the removal of ITRON, this cannot occur. + */ + if ( !_Objects_Information_table[ the_api ] ) + continue; + + /* + * Currently all managers are installed if the API is installed. + * This would be a horrible implementation error. + */ + if (_Objects_Information_table[ the_api ][ 1 ] == NULL ) + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + true, + INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY + ); + #endif + + bytes_to_allocate = sizeof( void * ) * + (_Objects_Information_table[ the_api ][ 1 ]->maximum + 1); + table = _Workspace_Allocate( bytes_to_allocate ); + if ( !table ) { + _POSIX_Keys_Free_memory( the_key ); + + _POSIX_Keys_Free( the_key ); + _Thread_Enable_dispatch(); + return ENOMEM; + } + + the_key->Values[ the_api ] = table; + memset( table, '\0', bytes_to_allocate ); + } + + _Objects_Open_u32( &_POSIX_Keys_Information, &the_key->Object, 0 ); + *key = the_key->Object.id; + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/keydelete.c b/cpukit/posix/src/keydelete.c new file mode 100644 index 0000000000..99b6e7eedd --- /dev/null +++ b/cpukit/posix/src/keydelete.c @@ -0,0 +1,60 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <string.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/key.h> + +/* + * 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 + */ +int pthread_key_delete( + pthread_key_t key +) +{ + POSIX_Keys_Control *the_key; + Objects_Locations location; + + the_key = _POSIX_Keys_Get( key, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Close( &_POSIX_Keys_Information, &the_key->Object ); + + _POSIX_Keys_Free_memory( the_key ); + + /* + * NOTE: The destructor is not called and it is the responsibility + * of the application to free the memory. + */ + _POSIX_Keys_Free( the_key ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never happen */ +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/keyfreememory.c b/cpukit/posix/src/keyfreememory.c new file mode 100644 index 0000000000..b6449ffa21 --- /dev/null +++ b/cpukit/posix/src/keyfreememory.c @@ -0,0 +1,29 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/key.h> + +void _POSIX_Keys_Free_memory( + POSIX_Keys_Control *the_key +) +{ + uint32_t the_api; + + for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ ) + _Workspace_Free( the_key->Values[ the_api ] ); +} diff --git a/cpukit/posix/src/keygetspecific.c b/cpukit/posix/src/keygetspecific.c new file mode 100644 index 0000000000..e0acff1455 --- /dev/null +++ b/cpukit/posix/src/keygetspecific.c @@ -0,0 +1,59 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <string.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/key.h> + +/*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; + uint32_t api; + uint32_t index; + Objects_Locations location; + void *key_data; + + the_key = _POSIX_Keys_Get( key, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = _Objects_Get_API( _Thread_Executing->Object.id ); + index = _Objects_Get_index( _Thread_Executing->Object.id ); + key_data = (void *) the_key->Values[ api ][ index ]; + _Thread_Enable_dispatch(); + return key_data; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never happen */ +#endif + case OBJECTS_ERROR: + break; + } + + return NULL; +} diff --git a/cpukit/posix/src/keyrundestructors.c b/cpukit/posix/src/keyrundestructors.c new file mode 100644 index 0000000000..cc8bad94e8 --- /dev/null +++ b/cpukit/posix/src/keyrundestructors.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010 embedded brains GmbH. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/posix/key.h> + +/*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. + */ + +void _POSIX_Keys_Run_destructors( + Thread_Control *thread +) +{ + Objects_Maximum thread_index = _Objects_Get_index( thread->Object.id ); + Objects_APIs thread_api = _Objects_Get_API( thread->Object.id ); + bool done = false; + + /* + * The standard allows one to avoid a potential infinite loop and limit the + * number of iterations. An infinite loop may happen if destructors set + * thread specific data. This can be considered dubious. + * + * Reference: 17.1.1.2 P1003.1c/Draft 10, p. 163, line 99. + */ + while ( !done ) { + Objects_Maximum index = 0; + Objects_Maximum max = _POSIX_Keys_Information.maximum; + + done = true; + + for ( index = 1 ; index <= max ; ++index ) { + POSIX_Keys_Control *key = (POSIX_Keys_Control *) + _POSIX_Keys_Information.local_table [ index ]; + + if ( key != NULL && key->destructor != NULL ) { + void *value = key->Values [ thread_api ][ thread_index ]; + + if ( value != NULL ) { + key->Values [ thread_api ][ thread_index ] = NULL; + (*key->destructor)( value ); + done = false; + } + } + } + } +} diff --git a/cpukit/posix/src/keysetspecific.c b/cpukit/posix/src/keysetspecific.c new file mode 100644 index 0000000000..8f85ffbcf9 --- /dev/null +++ b/cpukit/posix/src/keysetspecific.c @@ -0,0 +1,59 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <limits.h> +#include <pthread.h> +#include <string.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/key.h> + +/*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; + uint32_t api; + uint32_t index; + Objects_Locations location; + + the_key = _POSIX_Keys_Get( key, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = _Objects_Get_API( _Thread_Executing->Object.id ); + index = _Objects_Get_index( _Thread_Executing->Object.id ); + the_key->Values[ api ][ index ] = (void *) value; + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never happen */ +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/kill.c b/cpukit/posix/src/kill.c new file mode 100644 index 0000000000..34ea487806 --- /dev/null +++ b/cpukit/posix/src/kill.c @@ -0,0 +1,32 @@ +/* + * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +int kill( + pid_t pid, + int sig +) +{ + return killinfo( pid, sig, NULL ); +} + diff --git a/cpukit/posix/src/kill_r.c b/cpukit/posix/src/kill_r.c new file mode 100644 index 0000000000..2da710f799 --- /dev/null +++ b/cpukit/posix/src/kill_r.c @@ -0,0 +1,37 @@ +/* + * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +#if defined(RTEMS_NEWLIB) + +#include <reent.h> + +int _kill_r( + struct _reent *ptr, + pid_t pid, + int sig +) +{ + return killinfo( pid, sig, NULL ); +} +#endif diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c new file mode 100644 index 0000000000..b1569e791b --- /dev/null +++ b/cpukit/posix/src/killinfo.c @@ -0,0 +1,351 @@ +/* + * kill() support routine + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/seterr.h> +#include <rtems/score/isr.h> + +/* + * If you enable this, then you get printk() feedback on each path + * and the input to the decision that lead to the decision. Hopefully + * this will help in debugging the algorithm that distributes process + * signals to individual threads. + */ + +/* #define DEBUG_SIGNAL_PROCESSING */ +#if defined(DEBUG_SIGNAL_PROCESSING) + #include <rtems/bspIo.h> + #define DEBUG_STEP(_x) printk(_x) +#else + #define DEBUG_STEP(_x) +#endif + +/* + * 3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68 + * + * NOTE: Behavior of kill() depends on _POSIX_SAVED_IDS. + */ + +#define _POSIX_signals_Is_interested( _api, _mask ) \ + ( ~(_api)->signals_blocked & (_mask) ) + +int killinfo( + pid_t pid, + int sig, + const union sigval *value +) +{ + sigset_t mask; + POSIX_API_Control *api; + uint32_t the_api; + uint32_t index; + uint32_t maximum; + Objects_Information *the_info; + Objects_Control **object_table; + Thread_Control *the_thread; + Thread_Control *interested; + Priority_Control interested_priority; + Chain_Control *the_chain; + Chain_Node *the_node; + siginfo_t siginfo_struct; + siginfo_t *siginfo; + POSIX_signals_Siginfo_node *psiginfo; + + /* + * Only supported for the "calling process" (i.e. this node). + */ + if ( pid != getpid() ) + rtems_set_errno_and_return_minus_one( ESRCH ); + + /* + * Validate the signal passed. + */ + if ( !sig ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !is_valid_signo(sig) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * If the signal is being ignored, then we are out of here. + */ + if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) + return 0; + + /* + * P1003.1c/Draft 10, p. 33 says that certain signals should always + * be directed to the executing thread such as those caused by hardware + * faults. + */ + if ( (sig == SIGFPE) || (sig == SIGILL) || (sig == SIGSEGV ) ) + return pthread_kill( pthread_self(), sig ); + + mask = signo_to_mask( sig ); + + /* + * Build up a siginfo structure + */ + siginfo = &siginfo_struct; + siginfo->si_signo = sig; + siginfo->si_code = SI_USER; + if ( !value ) { + siginfo->si_value.sival_int = 0; + } else { + siginfo->si_value = *value; + } + + _Thread_Disable_dispatch(); + + /* + * Is the currently executing thread interested? If so then it will + * get it an execute it as soon as the dispatcher executes. + */ + the_thread = _Thread_Executing; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + if ( _POSIX_signals_Is_interested( api, mask ) ) { + goto process_it; + } + + /* + * Is an interested thread waiting for this signal (sigwait())? + * + * There is no requirement on the order of threads pending on a sigwait(). + */ + + /* XXX violation of visibility -- need to define thread queue support */ + + the_chain = &_POSIX_signals_Wait_queue.Queues.Fifo; + + for ( the_node = _Chain_First( the_chain ); + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_thread = (Thread_Control *)the_node; + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + #if defined(DEBUG_SIGNAL_PROCESSING) + printk( "Waiting Thread=%p option=0x%08x mask=0x%08x blocked=0x%08x\n", + the_thread, the_thread->Wait.option, mask, api->signals_blocked); + #endif + + /* + * Is this thread is actually blocked waiting for the signal? + */ + if (the_thread->Wait.option & mask) + goto process_it; + + /* + * Is this thread is blocked waiting for another signal but has + * not blocked this one? + */ + if (~api->signals_blocked & mask) + goto process_it; + } + + /* + * Is any other thread interested? The highest priority interested + * thread is selected. In the event of a tie, then the following + * additional criteria is used: + * + * + ready thread over blocked + * + blocked on call interruptible by signal (can return EINTR) + * + blocked on call not interruptible by signal + * + * This looks at every thread in the system regardless of the creating API. + * + * NOTES: + * + * + rtems internal threads do not receive signals. + */ + interested = NULL; + interested_priority = PRIORITY_MAXIMUM + 1; + + for (the_api = OBJECTS_CLASSIC_API; the_api <= OBJECTS_APIS_LAST; the_api++) { + + /* + * This can occur when no one is interested and an API is not configured. + */ + if ( !_Objects_Information_table[ the_api ] ) + continue; + + the_info = _Objects_Information_table[ the_api ][ 1 ]; + + #if defined(RTEMS_DEBUG) + /* + * This cannot happen in the current (as of June 2009) implementation + * of initialization but at some point, the object information + * structure for a particular manager may not be installed. + */ + if ( !the_info ) + continue; + #endif + + maximum = the_info->maximum; + object_table = the_info->local_table; + + for ( index = 1 ; index <= maximum ; index++ ) { + the_thread = (Thread_Control *) object_table[ index ]; + + if ( !the_thread ) + continue; + + #if defined(DEBUG_SIGNAL_PROCESSING) + printk("\n 0x%08x/0x%08x %d/%d 0x%08x 1", + the_thread->Object.id, + ((interested) ? interested->Object.id : 0), + the_thread->current_priority, interested_priority, + the_thread->current_state + ); + #endif + + /* + * If this thread is of lower priority than the interested thread, + * go on to the next thread. + */ + if ( the_thread->current_priority > interested_priority ) + continue; + DEBUG_STEP("2"); + + /* + * If this thread is not interested, then go on to the next thread. + */ + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + #if defined(RTEMS_DEBUG) + if ( !api ) + continue; + #endif + + if ( !_POSIX_signals_Is_interested( api, mask ) ) + continue; + DEBUG_STEP("3"); + + /* + * Now we know the thread under consideration is interested. + * If the thread under consideration is of higher priority, then + * it becomes the interested thread. + * + * NOTE: We initialized interested_priority to PRIORITY_MAXIMUM + 1 + * so we never have to worry about deferencing a NULL + * interested thread. + */ + if ( the_thread->current_priority < interested_priority ) { + interested = the_thread; + interested_priority = the_thread->current_priority; + continue; + } + DEBUG_STEP("4"); + + /* + * Now the thread and the interested thread have the same priority. + * We have to sort through the combinations of blocked/not blocked + * and blocking interruptibutable by signal. + * + * If the interested thread is ready, don't think about changing. + */ + + if ( interested && !_States_Is_ready( interested->current_state ) ) { + /* preferred ready over blocked */ + DEBUG_STEP("5"); + if ( _States_Is_ready( the_thread->current_state ) ) { + interested = the_thread; + interested_priority = the_thread->current_priority; + continue; + } + + DEBUG_STEP("6"); + /* prefer blocked/interruptible over blocked/not interruptible */ + if ( !_States_Is_interruptible_by_signal(interested->current_state) ) { + DEBUG_STEP("7"); + if ( _States_Is_interruptible_by_signal(the_thread->current_state) ) { + DEBUG_STEP("8"); + interested = the_thread; + interested_priority = the_thread->current_priority; + continue; + } + } + } + } + } + + if ( interested ) { + the_thread = interested; + goto process_it; + } + + /* + * OK so no threads were interested right now. It will be left on the + * global pending until a thread receives it. The global set of threads + * can change interest in this signal in one of the following ways: + * + * + a thread is created with the signal unblocked, + * + pthread_sigmask() unblocks the signal, + * + sigprocmask() unblocks the signal, OR + * + sigaction() which changes the handler to SIG_IGN. + */ + the_thread = NULL; + goto post_process_signal; + + /* + * We found a thread which was interested, so now we mark that this + * thread needs to do the post context switch extension so it can + * evaluate the signals pending. + */ +process_it: + + /* + * Returns true if the signal was synchronously given to a thread + * blocked waiting for the signal. + */ + if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) { + _Thread_Enable_dispatch(); + return 0; + } + +post_process_signal: + + /* + * We may have woken up a thread but we definitely need to post the + * signal to the process wide information set. + */ + _POSIX_signals_Set_process_signals( mask ); + + if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) { + + psiginfo = (POSIX_signals_Siginfo_node *) + _Chain_Get( &_POSIX_signals_Inactive_siginfo ); + if ( !psiginfo ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EAGAIN ); + } + + psiginfo->Info = *siginfo; + + _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node ); + } + + DEBUG_STEP("\n"); + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/lio_listio.c b/cpukit/posix/src/lio_listio.c new file mode 100644 index 0000000000..4444b10302 --- /dev/null +++ b/cpukit/posix/src/lio_listio.c @@ -0,0 +1,32 @@ +/* + * 6.7.4 List Directed I/O, P1003.1b-1993, p. 158 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <aio.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> + +int lio_listio( + int mode __attribute__((unused)), + struct aiocb * const list[] __attribute__((unused)), + int nent __attribute__((unused)), + struct sigevent *sig __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/mprotect.c b/cpukit/posix/src/mprotect.c new file mode 100644 index 0000000000..d3fa8bf9c9 --- /dev/null +++ b/cpukit/posix/src/mprotect.c @@ -0,0 +1,36 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +/*PAGE + * + * 12.2.3 Change Memory Protection, P1003.1b-1996, p. 277. + * + * This is not a functional version but the SPARC backend for at least + * gcc 2.8.1 plus gnat 3.13p and gcc 3.0.1 require it to be there and + * return 0. + * + * As of gcc 4.2.2, the gcc SPARC backend doesn't appear to have a + * way to call this for RTEMS anymore but it doesn't hurt to leave it. + */ + +int mprotect( + const void *addr __attribute__((unused)), + size_t len __attribute__((unused)), + int prot __attribute__((unused)) ) +{ + return 0; +} diff --git a/cpukit/posix/src/mqueue.c b/cpukit/posix/src/mqueue.c new file mode 100644 index 0000000000..5229bd4d67 --- /dev/null +++ b/cpukit/posix/src/mqueue.c @@ -0,0 +1,87 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * _POSIX_Message_queue_Manager_initialization + * + * This routine initializes all message_queue manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _POSIX_Message_queue_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Message_queue_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_MESSAGE_QUEUES, /* object class */ + Configuration_POSIX_API.maximum_message_queues, + /* maximum objects of this class */ + sizeof( POSIX_Message_queue_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); + _Objects_Initialize_information( + &_POSIX_Message_queue_Information_fds, + OBJECTS_POSIX_API, + OBJECTS_POSIX_MESSAGE_QUEUE_FDS, + Configuration_POSIX_API.maximum_message_queue_descriptors, + sizeof( POSIX_Message_queue_Control_fd ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + NAME_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/mqueueclose.c b/cpukit/posix/src/mqueueclose.c new file mode 100644 index 0000000000..35b4dc3ec1 --- /dev/null +++ b/cpukit/posix/src/mqueueclose.c @@ -0,0 +1,85 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/* + * + * 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275 + */ + +int mq_close( + mqd_t mqdes +) +{ + POSIX_Message_queue_Control *the_mq; + POSIX_Message_queue_Control_fd *the_mq_fd; + Objects_Locations location; + + the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); + if ( location == OBJECTS_LOCAL ) { + /* OBJECTS_LOCAL: + * + * First update the actual message queue to reflect this descriptor + * being disassociated. This may result in the queue being really + * deleted. + */ + + the_mq = the_mq_fd->Queue; + the_mq->open_count -= 1; + _POSIX_Message_queue_Delete( the_mq ); + + /* + * Now close this file descriptor. + */ + + _Objects_Close( + &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object ); + _POSIX_Message_queue_Free_fd( the_mq_fd ); + + _Thread_Enable_dispatch(); + return 0; + } + + /* + * OBJECTS_REMOTE: + * OBJECTS_ERROR: + */ + rtems_set_errno_and_return_minus_one( EBADF ); +} diff --git a/cpukit/posix/src/mqueuecreatesupp.c b/cpukit/posix/src/mqueuecreatesupp.c new file mode 100644 index 0000000000..90bab33ed7 --- /dev/null +++ b/cpukit/posix/src/mqueuecreatesupp.c @@ -0,0 +1,153 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/* pure ANSI mode does not have this prototype */ +size_t strnlen(const char *, size_t); + +/*PAGE + * + * _POSIX_Message_queue_Create_support + * + * This routine does the actual creation and initialization of + * a poxix message queue. + */ + +int _POSIX_Message_queue_Create_support( + const char *name_arg, + int pshared, + struct mq_attr *attr_ptr, + POSIX_Message_queue_Control **message_queue +) +{ + POSIX_Message_queue_Control *the_mq; + CORE_message_queue_Attributes *the_mq_attr; + struct mq_attr attr; + char *name; + size_t n; + + n = strnlen( name_arg, NAME_MAX ); + /* length of name has already been validated */ + + _Thread_Disable_dispatch(); + + /* + * There is no real basis for the default values. They will work + * but were not compared against any existing implementation for + * compatibility. See README.mqueue for an example program we + * think will print out the defaults. Report anything you find with it. + */ + if ( attr_ptr == NULL ) { + attr.mq_maxmsg = 10; + attr.mq_msgsize = 16; + } else { + if ( attr_ptr->mq_maxmsg <= 0 ){ + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + if ( attr_ptr->mq_msgsize <= 0 ){ + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + attr = *attr_ptr; + } + + the_mq = _POSIX_Message_queue_Allocate(); + if ( !the_mq ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( ENFILE ); + } + + the_mq->process_shared = pshared; + the_mq->named = true; + the_mq->open_count = 1; + the_mq->linked = true; + + /* + * Make a copy of the user's string for name just in case it was + * dynamically constructed. + */ + name = _Workspace_Allocate(n+1); + if (!name) { + _POSIX_Message_queue_Free( the_mq ); + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( ENOMEM ); + } + strncpy( name, name_arg, n+1 ); + + /* + * NOTE: That thread blocking discipline should be based on the + * current scheduling policy. + * + * Joel: Cite POSIX or OpenGroup on above statement so we can determine + * if it is a real requirement. + */ + the_mq_attr = &the_mq->Message_queue.Attributes; + the_mq_attr->discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO; + + if ( !_CORE_message_queue_Initialize( + &the_mq->Message_queue, + the_mq_attr, + attr.mq_maxmsg, + attr.mq_msgsize + ) ) { + + _POSIX_Message_queue_Free( the_mq ); + _Workspace_Free(name); + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( ENOSPC ); + } + + _Objects_Open_string( + &_POSIX_Message_queue_Information, + &the_mq->Object, + name + ); + + *message_queue = the_mq; + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/mqueuedeletesupp.c b/cpukit/posix/src/mqueuedeletesupp.c new file mode 100644 index 0000000000..4c95b08c95 --- /dev/null +++ b/cpukit/posix/src/mqueuedeletesupp.c @@ -0,0 +1,82 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> +#if defined(RTEMS_DEBUG) + #include <rtems/bspIo.h> +#endif + +/*PAGE + * + * _POSIX_Message_queue_Delete + */ + +void _POSIX_Message_queue_Delete( + POSIX_Message_queue_Control *the_mq +) +{ + if ( !the_mq->linked && !the_mq->open_count ) { + Objects_Control *the_object = &the_mq->Object; + + #if defined(RTEMS_DEBUG) + /* + * the name memory will have been freed by unlink. + */ + if ( the_object->name.name_p ) { + printk( + "POSIX MQ name (%p) not freed by unlink\n", + (void *)the_object->name.name_p + ); + _Workspace_Free( (void *)the_object->name.name_p ); + } + #endif + + _Objects_Close( &_POSIX_Message_queue_Information, the_object ); + + _CORE_message_queue_Close( + &the_mq->Message_queue, + NULL, /* no MP support */ + CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED + ); + + _POSIX_Message_queue_Free( the_mq ); + + } +} diff --git a/cpukit/posix/src/mqueuegetattr.c b/cpukit/posix/src/mqueuegetattr.c new file mode 100644 index 0000000000..16a5c50b5f --- /dev/null +++ b/cpukit/posix/src/mqueuegetattr.c @@ -0,0 +1,88 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 15.2.8 Get Message Queue Attributes, P1003.1b-1993, p. 283 + */ + +int mq_getattr( + mqd_t mqdes, + struct mq_attr *mqstat +) +{ + POSIX_Message_queue_Control *the_mq; + POSIX_Message_queue_Control_fd *the_mq_fd; + Objects_Locations location; + CORE_message_queue_Attributes *the_mq_attr; + + if ( !mqstat ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + the_mq = the_mq_fd->Queue; + + /* + * Return the old values. + */ + + the_mq_attr = &the_mq->Message_queue.Attributes; + + mqstat->mq_flags = the_mq_fd->oflag; + 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; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EBADF ); +} diff --git a/cpukit/posix/src/mqueuenametoid.c b/cpukit/posix/src/mqueuenametoid.c new file mode 100644 index 0000000000..f52e3383c2 --- /dev/null +++ b/cpukit/posix/src/mqueuenametoid.c @@ -0,0 +1,67 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/* pure ANSI mode does not have this prototype */ +size_t strnlen(const char *, size_t); + +/* + * _POSIX_Message_queue_Name_to_id + * + * Look up the specified name and attempt to locate the id + * for the associated message queue. + */ +int _POSIX_Message_queue_Name_to_id( + const char *name, + Objects_Id *id +) +{ + Objects_Name_or_id_lookup_errors status; + Objects_Id the_id; + + if ( !name ) + return EINVAL; + + if ( !name[0] ) + return EINVAL; + + if ( strnlen( name, NAME_MAX ) >= NAME_MAX ) + return ENAMETOOLONG; + + status = _Objects_Name_to_id_string( + &_POSIX_Message_queue_Information, + name, + &the_id + ); + *id = the_id; + + if ( status == OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL ) + return 0; + + return ENOENT; +} diff --git a/cpukit/posix/src/mqueuenotify.c b/cpukit/posix/src/mqueuenotify.c new file mode 100644 index 0000000000..1b9660ccbf --- /dev/null +++ b/cpukit/posix/src/mqueuenotify.c @@ -0,0 +1,116 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> +#include <sys/types.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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; + + kill( getpid(), the_mq->notification.sigev_signo ); + + _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL ); +} + +/*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 +) +{ + POSIX_Message_queue_Control *the_mq; + POSIX_Message_queue_Control_fd *the_mq_fd; + Objects_Locations location; + + the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + the_mq = the_mq_fd->Queue; + + if ( notification ) { + if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EBUSY ); + } + + _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; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EBADF ); +} diff --git a/cpukit/posix/src/mqueueopen.c b/cpukit/posix/src/mqueueopen.c new file mode 100644 index 0000000000..2b96236fb5 --- /dev/null +++ b/cpukit/posix/src/mqueueopen.c @@ -0,0 +1,155 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/* + * 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 = NULL; + int status; + Objects_Id the_mq_id; + POSIX_Message_queue_Control *the_mq; + POSIX_Message_queue_Control_fd *the_mq_fd; + Objects_Locations location; + + _Thread_Disable_dispatch(); + + if ( oflag & O_CREAT ) { + va_start(arg, oflag); + mode = (mode_t) va_arg( arg, unsigned int ); + attr = (struct mq_attr *) va_arg( arg, struct mq_attr * ); + va_end(arg); + } + + the_mq_fd = _POSIX_Message_queue_Allocate_fd(); + if ( !the_mq_fd ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( ENFILE ); + } + the_mq_fd->oflag = oflag; + + 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 ) { + /* + * Unless provided a valid name that did not already exist + * and we are willing to create then it is an error. + */ + if ( !( status == ENOENT && (oflag & O_CREAT) ) ) { + _POSIX_Message_queue_Free_fd( the_mq_fd ); + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one_cast( status, mqd_t ); + } + + } else { /* name -> ID translation succeeded */ + /* + * Check for existence with creation. + */ + if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) { + _POSIX_Message_queue_Free_fd( the_mq_fd ); + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one_cast( EEXIST, mqd_t ); + } + + /* + * In this case we need to do an ID->pointer conversion to + * check the mode. + */ + the_mq = _POSIX_Message_queue_Get( the_mq_id, &location ); + the_mq->open_count += 1; + the_mq_fd->Queue = the_mq; + _Objects_Open_string( + &_POSIX_Message_queue_Information_fds, + &the_mq_fd->Object, + NULL + ); + _Thread_Enable_dispatch(); + _Thread_Enable_dispatch(); + return (mqd_t)the_mq_fd->Object.id; + + } + + /* + * 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 */ + attr, + &the_mq + ); + + /* + * errno was set by Create_support, so don't set it again. + */ + if ( status == -1 ) { + _POSIX_Message_queue_Free_fd( the_mq_fd ); + _Thread_Enable_dispatch(); + return (mqd_t) -1; + } + + the_mq_fd->Queue = the_mq; + _Objects_Open_string( + &_POSIX_Message_queue_Information_fds, + &the_mq_fd->Object, + NULL + ); + + _Thread_Enable_dispatch(); + + return (mqd_t) the_mq_fd->Object.id; +} diff --git a/cpukit/posix/src/mqueuereceive.c b/cpukit/posix/src/mqueuereceive.c new file mode 100644 index 0000000000..46b46b8359 --- /dev/null +++ b/cpukit/posix/src/mqueuereceive.c @@ -0,0 +1,64 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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, + true, + THREAD_QUEUE_WAIT_FOREVER + ); +} diff --git a/cpukit/posix/src/mqueuerecvsupp.c b/cpukit/posix/src/mqueuerecvsupp.c new file mode 100644 index 0000000000..9c3fb47371 --- /dev/null +++ b/cpukit/posix/src/mqueuerecvsupp.c @@ -0,0 +1,128 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/* + * _POSIX_Message_queue_Receive_support + * + * NOTE: XXX Document how size, priority, length, and the buffer go + * through the layers. + */ + +ssize_t _POSIX_Message_queue_Receive_support( + mqd_t mqdes, + char *msg_ptr, + size_t msg_len, + unsigned int *msg_prio, + bool wait, + Watchdog_Interval timeout +) +{ + POSIX_Message_queue_Control *the_mq; + POSIX_Message_queue_Control_fd *the_mq_fd; + Objects_Locations location; + size_t length_out; + bool do_wait; + + the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( (the_mq_fd->oflag & O_ACCMODE) == O_WRONLY ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EBADF ); + } + + the_mq = the_mq_fd->Queue; + + if ( msg_len < the_mq->Message_queue.maximum_message_size ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EMSGSIZE ); + } + + /* + * Now if something goes wrong, we return a "length" of -1 + * to indicate an error. + */ + + length_out = -1; + + /* + * A timed receive with a bad time will do a poll regardless. + */ + if ( wait ) + do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? false : true; + else + do_wait = wait; + + /* + * Now perform the actual message receive + */ + _CORE_message_queue_Seize( + &the_mq->Message_queue, + mqdes, + msg_ptr, + &length_out, + do_wait, + timeout + ); + + _Thread_Enable_dispatch(); + *msg_prio = + _POSIX_Message_queue_Priority_from_core(_Thread_Executing->Wait.count); + + if ( !_Thread_Executing->Wait.return_code ) + return length_out; + + rtems_set_errno_and_return_minus_one( + _POSIX_Message_queue_Translate_core_message_queue_return_code( + _Thread_Executing->Wait.return_code + ) + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EBADF ); +} diff --git a/cpukit/posix/src/mqueuesend.c b/cpukit/posix/src/mqueuesend.c new file mode 100644 index 0000000000..312b04dac2 --- /dev/null +++ b/cpukit/posix/src/mqueuesend.c @@ -0,0 +1,64 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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, + true, + THREAD_QUEUE_WAIT_FOREVER + ); +} diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c new file mode 100644 index 0000000000..13e91756e8 --- /dev/null +++ b/cpukit/posix/src/mqueuesendsupp.c @@ -0,0 +1,133 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + + +/*PAGE + * + * _POSIX_Message_queue_Send_support + */ + +int _POSIX_Message_queue_Send_support( + mqd_t mqdes, + const char *msg_ptr, + size_t msg_len, + uint32_t msg_prio, + bool wait, + Watchdog_Interval timeout +) +{ + POSIX_Message_queue_Control *the_mq; + POSIX_Message_queue_Control_fd *the_mq_fd; + Objects_Locations location; + CORE_message_queue_Status msg_status; + bool do_wait; + + /* + * Validate the priority. + * XXX - Do not validate msg_prio is not less than 0. + */ + + if ( msg_prio > MQ_PRIO_MAX ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( (the_mq_fd->oflag & O_ACCMODE) == O_RDONLY ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EBADF ); + } + + the_mq = the_mq_fd->Queue; + + /* + * A timed receive with a bad time will do a poll regardless. + */ + if ( wait ) + do_wait = (the_mq_fd->oflag & O_NONBLOCK) ? false : true; + else + do_wait = wait; + + /* + * Now perform the actual message receive + */ + msg_status = _CORE_message_queue_Submit( + &the_mq->Message_queue, + (void *)msg_ptr, + msg_len, + mqdes, /* mqd_t is an object id */ + NULL, + _POSIX_Message_queue_Priority_to_core( msg_prio ), + do_wait, + timeout /* no timeout */ + ); + + _Thread_Enable_dispatch(); + + /* + * If we had to block, then this is where the task returns + * after it wakes up. The returned status is correct for + * non-blocking operations but if we blocked, then we need + * to look at the status in our TCB. + */ + + if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) + msg_status = _Thread_Executing->Wait.return_code; + + if ( !msg_status ) + return msg_status; + + rtems_set_errno_and_return_minus_one( + _POSIX_Message_queue_Translate_core_message_queue_return_code( + msg_status + ) + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EBADF ); +} diff --git a/cpukit/posix/src/mqueuesetattr.c b/cpukit/posix/src/mqueuesetattr.c new file mode 100644 index 0000000000..683c3887b2 --- /dev/null +++ b/cpukit/posix/src/mqueuesetattr.c @@ -0,0 +1,90 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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 +) +{ + POSIX_Message_queue_Control_fd *the_mq_fd; + CORE_message_queue_Control *the_core_mq; + Objects_Locations location; + + if ( !mqstat ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + the_core_mq = &the_mq_fd->Queue->Message_queue; + + /* + * Return the old values. + */ + + if ( omqstat ) { + omqstat->mq_flags = the_mq_fd->oflag; + omqstat->mq_msgsize = the_core_mq->maximum_message_size; + omqstat->mq_maxmsg = the_core_mq->maximum_pending_messages; + omqstat->mq_curmsgs = the_core_mq->number_of_pending_messages; + } + + the_mq_fd->oflag = mqstat->mq_flags; + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EBADF ); +} diff --git a/cpukit/posix/src/mqueuetimedreceive.c b/cpukit/posix/src/mqueuetimedreceive.c new file mode 100644 index 0000000000..678d364cdf --- /dev/null +++ b/cpukit/posix/src/mqueuetimedreceive.c @@ -0,0 +1,88 @@ +/* + * 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. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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_timedreceive( + mqd_t mqdes, + char *msg_ptr, + size_t msg_len, + unsigned int *msg_prio, + const struct timespec *abstime +) +{ + Watchdog_Interval ticks; + bool do_wait = true; + POSIX_Absolute_timeout_conversion_results_t status; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + * + * If the status is POSIX_ABSOLUTE_TIMEOUT_INVALID, + * POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, or POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + * then we should not wait. + */ + status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ); + if ( status != POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) + do_wait = false; + + return _POSIX_Message_queue_Receive_support( + mqdes, + msg_ptr, + msg_len, + msg_prio, + do_wait, + ticks + ); +} diff --git a/cpukit/posix/src/mqueuetimedsend.c b/cpukit/posix/src/mqueuetimedsend.c new file mode 100644 index 0000000000..9048e8f077 --- /dev/null +++ b/cpukit/posix/src/mqueuetimedsend.c @@ -0,0 +1,88 @@ +/* + * 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. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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 *abstime +) +{ + Watchdog_Interval ticks; + bool do_wait = true; + POSIX_Absolute_timeout_conversion_results_t status; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + * + * If the status is POSIX_ABSOLUTE_TIMEOUT_INVALID, + * POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, or POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + * then we should not wait. + */ + status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ); + if ( status != POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) + do_wait = false; + + return _POSIX_Message_queue_Send_support( + mqdes, + msg_ptr, + msg_len, + msg_prio, + do_wait, + ticks + ); +} diff --git a/cpukit/posix/src/mqueuetranslatereturncode.c b/cpukit/posix/src/mqueuetranslatereturncode.c new file mode 100644 index 0000000000..9fe57a9920 --- /dev/null +++ b/cpukit/posix/src/mqueuetranslatereturncode.c @@ -0,0 +1,62 @@ +/* + * POSIX Message Queue Error Translation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/coremsg.h> + + +/*PAGE + * + * _POSIX_Message_queue_Translate_core_message_queue_return_code + * + * Input parameters: + * the_message_queue_status - message_queue status code to translate + * + * Output parameters: + * status code - translated POSIX status code + * + */ + +static + int _POSIX_Message_queue_Return_codes[CORE_MESSAGE_QUEUE_STATUS_LAST + 1] = { + 0, /* CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL */ + EMSGSIZE, /* CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE */ + EAGAIN, /* CORE_MESSAGE_QUEUE_STATUS_TOO_MANY */ + ENOMEM, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED */ + EAGAIN, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT */ + EBADF, /* CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED */ + ETIMEDOUT, /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */ + ENOSYS /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT */ +}; + + +int _POSIX_Message_queue_Translate_core_message_queue_return_code( + uint32_t the_message_queue_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_message_queue_status > CORE_MESSAGE_QUEUE_STATUS_LAST ) + return EINVAL; + #endif + return _POSIX_Message_queue_Return_codes[the_message_queue_status]; +} diff --git a/cpukit/posix/src/mqueueunlink.c b/cpukit/posix/src/mqueueunlink.c new file mode 100644 index 0000000000..67bb26928f --- /dev/null +++ b/cpukit/posix/src/mqueueunlink.c @@ -0,0 +1,75 @@ +/* + * 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. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <pthread.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <mqueue.h> + +#include <rtems/system.h> +#include <rtems/score/watchdog.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/time.h> + +/*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; + + _Thread_Disable_dispatch(); + + status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id ); + if ( status != 0 ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( status ); + } + + the_mq = (POSIX_Message_queue_Control *) _Objects_Get_local_object( + &_POSIX_Message_queue_Information, + _Objects_Get_index( the_mq_id ) + ); + + the_mq->linked = false; + _POSIX_Message_queue_Namespace_remove( the_mq ); + _POSIX_Message_queue_Delete( the_mq ); + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/mutex.c b/cpukit/posix/src/mutex.c new file mode 100644 index 0000000000..6046b219f5 --- /dev/null +++ b/cpukit/posix/src/mutex.c @@ -0,0 +1,79 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * _POSIX_Mutex_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(void) +{ + pthread_mutexattr_t *default_attr = &_POSIX_Mutex_Default_attributes; + + /* + * Since the maximum priority is run-time configured, this + * structure cannot be initialized statically. + */ + default_attr->is_initialized = true; + default_attr->process_shared = PTHREAD_PROCESS_PRIVATE; + default_attr->prio_ceiling = POSIX_SCHEDULER_MAXIMUM_PRIORITY; + default_attr->protocol = PTHREAD_PRIO_NONE; + default_attr->recursive = false; + #if defined(_UNIX98_THREAD_MUTEX_ATTRIBUTES) + default_attr->type = PTHREAD_MUTEX_DEFAULT; + #endif + + /* + * Initialize the POSIX mutex object class information structure. + */ + _Objects_Initialize_information( + &_POSIX_Mutex_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_MUTEXES, /* object class */ + Configuration_POSIX_API.maximum_mutexes, + /* maximum objects of this class */ + sizeof( POSIX_Mutex_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/mutexattrdestroy.c b/cpukit/posix/src/mutexattrdestroy.c new file mode 100644 index 0000000000..86e8c4597c --- /dev/null +++ b/cpukit/posix/src/mutexattrdestroy.c @@ -0,0 +1,40 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 + */ + +int pthread_mutexattr_destroy( + pthread_mutexattr_t *attr +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + attr->is_initialized = false; + return 0; +} diff --git a/cpukit/posix/src/mutexattrgetprioceiling.c b/cpukit/posix/src/mutexattrgetprioceiling.c new file mode 100644 index 0000000000..65944687aa --- /dev/null +++ b/cpukit/posix/src/mutexattrgetprioceiling.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 + */ + +int pthread_mutexattr_getprioceiling( + const pthread_mutexattr_t *attr, + int *prioceiling +) +{ + if ( !attr || !attr->is_initialized || !prioceiling ) + return EINVAL; + + *prioceiling = attr->prio_ceiling; + return 0; +} diff --git a/cpukit/posix/src/mutexattrgetprotocol.c b/cpukit/posix/src/mutexattrgetprotocol.c new file mode 100644 index 0000000000..6cd09979c8 --- /dev/null +++ b/cpukit/posix/src/mutexattrgetprotocol.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 + */ + +int pthread_mutexattr_getprotocol( + const pthread_mutexattr_t *attr, + int *protocol +) +{ + if ( !attr || !attr->is_initialized || !protocol ) + return EINVAL; + + *protocol = attr->protocol; + return 0; +} diff --git a/cpukit/posix/src/mutexattrgetpshared.c b/cpukit/posix/src/mutexattrgetpshared.c new file mode 100644 index 0000000000..162de9fe4d --- /dev/null +++ b/cpukit/posix/src/mutexattrgetpshared.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 + */ + +int pthread_mutexattr_getpshared( + const pthread_mutexattr_t *attr, + int *pshared +) +{ + if ( !attr || !attr->is_initialized || !pshared ) + return EINVAL; + + *pshared = attr->process_shared; + return 0; +} diff --git a/cpukit/posix/src/mutexattrgettype.c b/cpukit/posix/src/mutexattrgettype.c new file mode 100644 index 0000000000..59b69de0d9 --- /dev/null +++ b/cpukit/posix/src/mutexattrgettype.c @@ -0,0 +1,45 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +#if defined(_UNIX98_THREAD_MUTEX_ATTRIBUTES) +int pthread_mutexattr_gettype( + const pthread_mutexattr_t *attr, + int *type +) +{ + if ( !attr ) + return EINVAL; + + if ( !attr->is_initialized ) + return EINVAL; + + if ( !type ) + return EINVAL; + + *type = attr->type; + return 0; +} +#endif + diff --git a/cpukit/posix/src/mutexattrinit.c b/cpukit/posix/src/mutexattrinit.c new file mode 100644 index 0000000000..9f6988fab2 --- /dev/null +++ b/cpukit/posix/src/mutexattrinit.c @@ -0,0 +1,40 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 + */ + +int pthread_mutexattr_init( + pthread_mutexattr_t *attr +) +{ + if ( !attr ) + return EINVAL; + + *attr = _POSIX_Mutex_Default_attributes; + return 0; +} diff --git a/cpukit/posix/src/mutexattrsetprioceiling.c b/cpukit/posix/src/mutexattrsetprioceiling.c new file mode 100644 index 0000000000..aee51cc6e5 --- /dev/null +++ b/cpukit/posix/src/mutexattrsetprioceiling.c @@ -0,0 +1,44 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 + */ + +int pthread_mutexattr_setprioceiling( + pthread_mutexattr_t *attr, + int prioceiling +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + if ( !_POSIX_Priority_Is_valid( prioceiling ) ) + return EINVAL; + + attr->prio_ceiling = prioceiling; + return 0; +} diff --git a/cpukit/posix/src/mutexattrsetprotocol.c b/cpukit/posix/src/mutexattrsetprotocol.c new file mode 100644 index 0000000000..54d0c4ab8d --- /dev/null +++ b/cpukit/posix/src/mutexattrsetprotocol.c @@ -0,0 +1,49 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128 + */ + +int pthread_mutexattr_setprotocol( + pthread_mutexattr_t *attr, + int protocol +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( protocol ) { + case PTHREAD_PRIO_NONE: + case PTHREAD_PRIO_INHERIT: + case PTHREAD_PRIO_PROTECT: + attr->protocol = protocol; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/mutexattrsetpshared.c b/cpukit/posix/src/mutexattrsetpshared.c new file mode 100644 index 0000000000..58dc5fd9d0 --- /dev/null +++ b/cpukit/posix/src/mutexattrsetpshared.c @@ -0,0 +1,48 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.1 Mutex Initialization Attributes, P1003.1c/Draft 10, p. 81 + */ + +int pthread_mutexattr_setpshared( + pthread_mutexattr_t *attr, + int pshared +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( pshared ) { + case PTHREAD_PROCESS_SHARED: + case PTHREAD_PROCESS_PRIVATE: + attr->process_shared = pshared; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/mutexattrsettype.c b/cpukit/posix/src/mutexattrsettype.c new file mode 100644 index 0000000000..1cfb94d4d9 --- /dev/null +++ b/cpukit/posix/src/mutexattrsettype.c @@ -0,0 +1,47 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +#if defined(_UNIX98_THREAD_MUTEX_ATTRIBUTES) +int pthread_mutexattr_settype( + pthread_mutexattr_t *attr, + int type +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( type ) { + case PTHREAD_MUTEX_NORMAL: + case PTHREAD_MUTEX_RECURSIVE: + case PTHREAD_MUTEX_ERRORCHECK: + case PTHREAD_MUTEX_DEFAULT: + attr->type = type; + return 0; + + default: + return EINVAL; + } +} +#endif diff --git a/cpukit/posix/src/mutexdestroy.c b/cpukit/posix/src/mutexdestroy.c new file mode 100644 index 0000000000..f8c01549c7 --- /dev/null +++ b/cpukit/posix/src/mutexdestroy.c @@ -0,0 +1,68 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 + */ + +int pthread_mutex_destroy( + pthread_mutex_t *mutex +) +{ + register POSIX_Mutex_Control *the_mutex; + Objects_Locations location; + + the_mutex = _POSIX_Mutex_Get( mutex, &location ); + switch ( location ) { + + case OBJECTS_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, NULL, EINVAL ); + + _POSIX_Mutex_Free( the_mutex ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/mutexget.c b/cpukit/posix/src/mutexget.c new file mode 100644 index 0000000000..71e46766ba --- /dev/null +++ b/cpukit/posix/src/mutexget.c @@ -0,0 +1,91 @@ +/* + * Convert POSIX Mutex ID to local object pointer + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> + + +/* + * _POSIX_Mutex_Get_support + * + * NOTE: The support macro makes it possible for both to use exactly + * the same code to check for NULL id pointer and + * PTHREAD_MUTEX_INITIALIZER without adding overhead. + */ + +#define ___POSIX_Mutex_Get_support_error_check( _id, _location ) \ + do { \ + if ( !_id ) { \ + *_location = OBJECTS_ERROR; \ + return (POSIX_Mutex_Control *) 0; \ + } \ + } while (0) + +#define ___POSIX_Mutex_Get_support_auto_initialization( _id, _location ) \ + do { \ + int _status; \ + \ + if ( *_id == PTHREAD_MUTEX_INITIALIZER ) { \ + /* \ + * Do an "auto-create" here. \ + */ \ + \ + _status = pthread_mutex_init( (pthread_mutex_t *)_id, 0 ); \ + if ( _status ) { \ + *_location = OBJECTS_ERROR; \ + return (POSIX_Mutex_Control *) 0; \ + } \ + } \ + } while (0) + +POSIX_Mutex_Control *_POSIX_Mutex_Get ( + pthread_mutex_t *mutex, + Objects_Locations *location +) +{ + ___POSIX_Mutex_Get_support_error_check( mutex, location ); + + ___POSIX_Mutex_Get_support_auto_initialization( mutex, location ); + + return (POSIX_Mutex_Control *) + _Objects_Get( &_POSIX_Mutex_Information, (Objects_Id) *mutex, location ); +} + +POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable ( + pthread_mutex_t *mutex, + Objects_Locations *location, + ISR_Level *level +) +{ + ___POSIX_Mutex_Get_support_error_check( mutex, location ); + + ___POSIX_Mutex_Get_support_auto_initialization( mutex, location ); + + return (POSIX_Mutex_Control *) _Objects_Get_isr_disable( + &_POSIX_Mutex_Information, + (Objects_Id) *mutex, + location, + level + ); +} diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c new file mode 100644 index 0000000000..58537d9242 --- /dev/null +++ b/cpukit/posix/src/mutexgetprioceiling.c @@ -0,0 +1,63 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131 + */ + +int pthread_mutex_getprioceiling( + pthread_mutex_t *mutex, + int *prioceiling +) +{ + register POSIX_Mutex_Control *the_mutex; + Objects_Locations location; + + if ( !prioceiling ) + return EINVAL; + + the_mutex = _POSIX_Mutex_Get( mutex, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + *prioceiling = _POSIX_Priority_From_core( + the_mutex->Mutex.Attributes.priority_ceiling + ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c new file mode 100644 index 0000000000..d6102d44a1 --- /dev/null +++ b/cpukit/posix/src/mutexinit.c @@ -0,0 +1,188 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 + * + * NOTE: XXX Could be optimized so all the attribute error checking + * is not performed when attr is NULL. + */ + +int pthread_mutex_init( + pthread_mutex_t *mutex, + const pthread_mutexattr_t *attr +) +{ + POSIX_Mutex_Control *the_mutex; + CORE_mutex_Attributes *the_mutex_attr; + const pthread_mutexattr_t *the_attr; + CORE_mutex_Disciplines the_discipline; + + if ( attr ) the_attr = attr; + else the_attr = &_POSIX_Mutex_Default_attributes; + + /* Check for NULL mutex */ + if ( !mutex ) + return EINVAL; + + /* + * This code should eventually be removed. + * + * Although the POSIX specification says: + * + * "Attempting to initialize an already initialized mutex results + * in undefined behavior." + * + * Trying to keep the caller from doing the create when *mutex + * is actually a valid ID causes grief. All it takes is the wrong + * value in an uninitialized variable to make this fail. As best + * I can tell, RTEMS was the only pthread implementation to choose + * this option for "undefined behavior" and doing so has created + * portability problems. In particular, Rosimildo DaSilva + * <rdasilva@connecttel.com> saw seemingly random failures in the + * RTEMS port of omniORB2 when this code was enabled. + * + * Joel Sherrill <joel@OARcorp.com> 14 May 1999 + * NOTE: Be careful to avoid infinite recursion on call to this + * routine in _POSIX_Mutex_Get. + */ + #if 0 + { + POSIX_Mutex_Control *mutex_in_use; + Objects_Locations location; + + if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) { + + /* EBUSY if *mutex is a valid id */ + + mutex_in_use = _POSIX_Mutex_Get( mutex, &location ); + switch ( location ) { + case OBJECTS_LOCAL: + _Thread_Enable_dispatch(); + return EBUSY; + #if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: + #endif + case OBJECTS_ERROR: + break; + } + } + } + #endif + + if ( !the_attr->is_initialized ) + return EINVAL; + + /* + * We only support process private mutexes. + */ + if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED ) + return ENOSYS; + + if ( the_attr->process_shared != PTHREAD_PROCESS_PRIVATE ) + 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; + } + + /* + * Validate the priority ceiling field -- should always be valid. + */ + if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) ) + return EINVAL; + +#if defined(_UNIX98_THREAD_MUTEX_ATTRIBUTES) + /* + * Validate the mutex type and set appropriate SuperCore mutex + * attributes. + */ + switch ( the_attr->type ) { + case PTHREAD_MUTEX_NORMAL: + case PTHREAD_MUTEX_RECURSIVE: + case PTHREAD_MUTEX_ERRORCHECK: + case PTHREAD_MUTEX_DEFAULT: + break; + + default: + return EINVAL; + } +#endif + + /* + * Enter a dispatching critical section and begin to do the real work. + */ + _Thread_Disable_dispatch(); + + the_mutex = _POSIX_Mutex_Allocate(); + + if ( !the_mutex ) { + _Thread_Enable_dispatch(); + return EAGAIN; + } + + the_mutex->process_shared = the_attr->process_shared; + + the_mutex_attr = &the_mutex->Mutex.Attributes; + + if ( the_attr->recursive ) + the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES; + else + the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR; + the_mutex_attr->only_owner_release = true; + 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, + the_mutex_attr, + CORE_MUTEX_UNLOCKED + ); + + _Objects_Open_u32( &_POSIX_Mutex_Information, &the_mutex->Object, 0 ); + + *mutex = the_mutex->Object.id; + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/mutexlock.c b/cpukit/posix/src/mutexlock.c new file mode 100644 index 0000000000..85d1bd623b --- /dev/null +++ b/cpukit/posix/src/mutexlock.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 + * + * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 + */ + +int pthread_mutex_lock( + pthread_mutex_t *mutex +) +{ + return _POSIX_Mutex_Lock_support( mutex, true, THREAD_QUEUE_WAIT_FOREVER ); +} diff --git a/cpukit/posix/src/mutexlocksupp.c b/cpukit/posix/src/mutexlocksupp.c new file mode 100644 index 0000000000..43c80d054e --- /dev/null +++ b/cpukit/posix/src/mutexlocksupp.c @@ -0,0 +1,70 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * _POSIX_Mutex_Lock_support + * + * A support routine which implements guts of the blocking, non-blocking, and + * timed wait version of mutex lock. + */ + +int _POSIX_Mutex_Lock_support( + pthread_mutex_t *mutex, + bool blocking, + Watchdog_Interval timeout +) +{ + register POSIX_Mutex_Control *the_mutex; + Objects_Locations location; + ISR_Level level; + + the_mutex = _POSIX_Mutex_Get_interrupt_disable( mutex, &location, &level ); + switch ( location ) { + + case OBJECTS_LOCAL: + _CORE_mutex_Seize( + &the_mutex->Mutex, + the_mutex->Object.id, + blocking, + timeout, + level + ); + return _POSIX_Mutex_Translate_core_mutex_return_code( + (CORE_mutex_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c new file mode 100644 index 0000000000..f132b38e04 --- /dev/null +++ b/cpukit/posix/src/mutexsetprioceiling.c @@ -0,0 +1,91 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*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; + + if ( !old_ceiling ) + return EINVAL; + + if ( !_POSIX_Priority_Is_valid( prioceiling ) ) + return EINVAL; + + the_priority = _POSIX_Priority_To_core( prioceiling ); + + /* + * Must acquire the mutex before we can change it's ceiling. + * POSIX says block until we acquire it. + */ + (void) pthread_mutex_lock( mutex ); + + /* + * Do not worry about the return code from this. The Get operation + * will also fail if it is a bad id or was deleted between the two + * operations. + * + * NOTE: This makes it easier to get 100% binary coverage since the + * bad Id case is handled by the switch. + */ + the_mutex = _POSIX_Mutex_Get( mutex, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + *old_ceiling = _POSIX_Priority_From_core( + the_mutex->Mutex.Attributes.priority_ceiling + ); + the_mutex->Mutex.Attributes.priority_ceiling = the_priority; + /* + * We are required to unlock the mutex before we return. + */ + _CORE_mutex_Surrender( + &the_mutex->Mutex, + the_mutex->Object.id, + NULL + ); + _Thread_Enable_dispatch(); + + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* impossible to get here */ +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/mutextimedlock.c b/cpukit/posix/src/mutextimedlock.c new file mode 100644 index 0000000000..7773d84af6 --- /dev/null +++ b/cpukit/posix/src/mutextimedlock.c @@ -0,0 +1,83 @@ +/* + * Mutex Timed Lock + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 + * + * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 + */ + +int pthread_mutex_timedlock( + pthread_mutex_t *mutex, + const struct timespec *abstime +) +{ + Watchdog_Interval ticks; + bool do_wait = true; + POSIX_Absolute_timeout_conversion_results_t status; + int lock_status; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + * + * If the status is POSIX_ABSOLUTE_TIMEOUT_INVALID, + * POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, or POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + * then we should not wait. + */ + status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ); + if ( status != POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) + do_wait = false; + + lock_status = _POSIX_Mutex_Lock_support( mutex, do_wait, ticks ); + /* + * This service only gives us the option to block. We used a polling + * attempt to lock if the abstime was not in the future. If we did + * not obtain the mutex, then not look at the status immediately, + * make sure the right reason is returned. + */ + if ( !do_wait && (lock_status == EBUSY) ) { + if ( status == POSIX_ABSOLUTE_TIMEOUT_INVALID ) + return EINVAL; + if ( status == POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST || + status == POSIX_ABSOLUTE_TIMEOUT_IS_NOW ) + return ETIMEDOUT; + } + + return lock_status; +} diff --git a/cpukit/posix/src/mutextranslatereturncode.c b/cpukit/posix/src/mutextranslatereturncode.c new file mode 100644 index 0000000000..48b9a9a199 --- /dev/null +++ b/cpukit/posix/src/mutextranslatereturncode.c @@ -0,0 +1,61 @@ +/* + * POSIX Mutex Error Translation + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> + +/* + * _POSIX_Mutex_Translate_core_mutex_return_code + * + * Input parameters: + * the_mutex_status - mutex status code to translate + * + * Output parameters: + * status code - translated POSIX status code + * + */ + +static int _POSIX_Mutex_Return_codes[CORE_MUTEX_STATUS_LAST + 1] = { + 0, /* CORE_MUTEX_STATUS_SUCCESSFUL */ + EBUSY, /* CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT */ + EDEADLK, /* CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED */ + EPERM, /* CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE */ + EINVAL, /* CORE_MUTEX_WAS_DELETED */ + ETIMEDOUT, /* CORE_MUTEX_TIMEOUT */ +#ifdef __RTEMS_STRICT_ORDER_MUTEX__ + EDEADLK, /* CORE_MUTEX_RELEASE_NOT_ORDER */ +#endif + EINVAL /* CORE_MUTEX_STATUS_CEILING_VIOLATED */ +}; + + +int _POSIX_Mutex_Translate_core_mutex_return_code( + CORE_mutex_Status the_mutex_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_mutex_status > CORE_MUTEX_STATUS_LAST ) + return EINVAL; + #endif + return _POSIX_Mutex_Return_codes[the_mutex_status]; +} diff --git a/cpukit/posix/src/mutextrylock.c b/cpukit/posix/src/mutextrylock.c new file mode 100644 index 0000000000..d44f216614 --- /dev/null +++ b/cpukit/posix/src/mutextrylock.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 + * + * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 + */ + +int pthread_mutex_trylock( + pthread_mutex_t *mutex +) +{ + return _POSIX_Mutex_Lock_support( mutex, false, THREAD_QUEUE_WAIT_FOREVER ); +} diff --git a/cpukit/posix/src/mutexunlock.c b/cpukit/posix/src/mutexunlock.c new file mode 100644 index 0000000000..cdcd03f50c --- /dev/null +++ b/cpukit/posix/src/mutexunlock.c @@ -0,0 +1,64 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/score/coremutex.h> +#include <rtems/score/watchdog.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/posix/mutex.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 + * + * NOTE: P1003.4b/D8 adds pthread_mutex_timedlock(), p. 29 + */ + +int pthread_mutex_unlock( + pthread_mutex_t *mutex +) +{ + register POSIX_Mutex_Control *the_mutex; + Objects_Locations location; + CORE_mutex_Status status; + + the_mutex = _POSIX_Mutex_Get( mutex, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_mutex_Surrender( + &the_mutex->Mutex, + the_mutex->Object.id, + NULL + ); + _Thread_Enable_dispatch(); + return _POSIX_Mutex_Translate_core_mutex_return_code( status ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c new file mode 100644 index 0000000000..dc81a378d5 --- /dev/null +++ b/cpukit/posix/src/nanosleep.c @@ -0,0 +1,107 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/seterr.h> +#include <rtems/score/timespec.h> + +/*PAGE + * + * 14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269 + */ + +int nanosleep( + const struct timespec *rqtp, + struct timespec *rmtp +) +{ + Watchdog_Interval ticks; + + + /* + * Return EINVAL if the delay interval is negative. + * + * NOTE: This behavior is beyond the POSIX specification. + * FSU and GNU/Linux pthreads shares this behavior. + */ + if ( !_Timespec_Is_valid( rqtp ) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + ticks = _Timespec_To_ticks( rqtp ); + + /* + * A nanosleep for zero time is implemented as a yield. + * This behavior is also beyond the POSIX specification but is + * consistent with the RTEMS API and yields desirable behavior. + */ + + if ( !ticks ) { + _Thread_Disable_dispatch(); + _Scheduler_Yield(); + _Thread_Enable_dispatch(); + if ( rmtp ) { + rmtp->tv_sec = 0; + rmtp->tv_nsec = 0; + } + return 0; + } + + /* + * Block for the desired amount of time + */ + _Thread_Disable_dispatch(); + _Thread_Set_state( + _Thread_Executing, + STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL + ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); + _Thread_Enable_dispatch(); + + /* calculate time remaining */ + + if ( rmtp ) { + ticks -= + _Thread_Executing->Timer.stop_time - _Thread_Executing->Timer.start_time; + + _Timespec_From_ticks( ticks, rmtp ); + + /* + * Only when POSIX is enabled, can a sleep be interrupted. + */ + #if defined(RTEMS_POSIX_API) + /* + * If there is time remaining, then we were interrupted by a signal. + */ + if ( ticks ) + rtems_set_errno_and_return_minus_one( EINTR ); + #endif + } + + return 0; +} diff --git a/cpukit/posix/src/pause.c b/cpukit/posix/src/pause.c new file mode 100644 index 0000000000..e4a8782bc4 --- /dev/null +++ b/cpukit/posix/src/pause.c @@ -0,0 +1,40 @@ +/* + * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +/* + * 3.4.2 Suspend Process Execution, P1003.1b-1993, p. 81 + */ + +int pause( void ) +{ + sigset_t all_signals; + int status; + + (void) sigfillset( &all_signals ); + + status = sigtimedwait( &all_signals, NULL, NULL ); + + return status; +} diff --git a/cpukit/posix/src/pbarrier.c b/cpukit/posix/src/pbarrier.c new file mode 100644 index 0000000000..d131000e89 --- /dev/null +++ b/cpukit/posix/src/pbarrier.c @@ -0,0 +1,57 @@ +/* + * Barrier Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Barrier Manager. + * + * Directives provided are: + * + * + create a barrier + * + get an ID of a barrier + * + delete a barrier + * + acquire a barrier + * + release a barrier + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/posix/barrier.h> + +/** + * @brief _POSIX_Barrier_Manager_initialization + */ + +void _POSIX_Barrier_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Barrier_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_BARRIERS, /* object class */ + Configuration_POSIX_API.maximum_barriers, + /* maximum objects of this class */ + sizeof( POSIX_Barrier_Control ),/* size of this object's control block */ + true, /* true if the name is a string */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/pbarrierdestroy.c b/cpukit/posix/src/pbarrierdestroy.c new file mode 100644 index 0000000000..0caf8a1586 --- /dev/null +++ b/cpukit/posix/src/pbarrierdestroy.c @@ -0,0 +1,73 @@ +/* + * POSIX Barrier Manager -- Destroy a Barrier + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/barrier.h> + +/* + * pthread_barrier_destroy + * + * This directive allows a thread to delete a barrier specified by + * the barrier id. The barrier is freed back to the inactive + * barrier chain. + * + * Input parameters: + * barrier - barrier id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_barrier_destroy( + pthread_barrier_t *barrier +) +{ + POSIX_Barrier_Control *the_barrier = NULL; + Objects_Locations location; + + if ( !barrier ) + return EINVAL; + + the_barrier = _POSIX_Barrier_Get( barrier, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) { + _Thread_Enable_dispatch(); + return EBUSY; + } + + _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object ); + + _POSIX_Barrier_Free( the_barrier ); + + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/pbarrierinit.c b/cpukit/posix/src/pbarrierinit.c new file mode 100644 index 0000000000..a2a77f83a5 --- /dev/null +++ b/cpukit/posix/src/pbarrierinit.c @@ -0,0 +1,116 @@ +/* + * POSIX Barrier Manager -- Initialize a Barrier Instance + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/barrier.h> + +/* + * pthread_barrier_init + * + * This directive creates a barrier. A barrier id is returned. + * + * Input parameters: + * barrier - pointer to barrier id + * attr - barrier attributes + * count - number of threads before automatic release + * + * Output parameters: + * barrier - barrier id + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_barrier_init( + pthread_barrier_t *barrier, + const pthread_barrierattr_t *attr, + unsigned int count +) +{ + POSIX_Barrier_Control *the_barrier; + CORE_barrier_Attributes the_attributes; + pthread_barrierattr_t my_attr; + const pthread_barrierattr_t *the_attr; + + /* + * Error check parameters + */ + if ( !barrier ) + return EINVAL; + + if ( count == 0 ) + return EINVAL; + + /* + * If the user passed in NULL, use the default attributes + */ + if ( attr ) { + the_attr = attr; + } else { + (void) pthread_barrierattr_init( &my_attr ); + the_attr = &my_attr; + } + + /* + * Now start error checking the attributes that we are going to use + */ + if ( !the_attr->is_initialized ) + return EINVAL; + + switch ( the_attr->process_shared ) { + case PTHREAD_PROCESS_PRIVATE: /* only supported values */ + break; + case PTHREAD_PROCESS_SHARED: + default: + return EINVAL; + } + + /* + * Convert from POSIX attributes to Core Barrier attributes + */ + the_attributes.discipline = CORE_BARRIER_AUTOMATIC_RELEASE; + the_attributes.maximum_count = count; + + /* + * Enter dispatching critical section to allocate and initialize barrier + */ + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_barrier = _POSIX_Barrier_Allocate(); + + if ( !the_barrier ) { + _Thread_Enable_dispatch(); + return EAGAIN; + } + + _CORE_barrier_Initialize( &the_barrier->Barrier, &the_attributes ); + + _Objects_Open_u32( + &_POSIX_Barrier_Information, + &the_barrier->Object, + 0 + ); + + /* + * Exit the critical section and return the user an operational barrier + */ + *barrier = the_barrier->Object.id; + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/pbarriertranslatereturncode.c b/cpukit/posix/src/pbarriertranslatereturncode.c new file mode 100644 index 0000000000..0351fc5a65 --- /dev/null +++ b/cpukit/posix/src/pbarriertranslatereturncode.c @@ -0,0 +1,56 @@ +/* + * Barrier Manager -- Translate SuperCore Status + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/barrier.h> + +/* + * _POSIX_Barrier_Translate_core_barrier_return_code + * + * Input parameters: + * the_barrier_status - barrier status code to translate + * + * Output parameters: + * status code - translated POSIX status code + * + */ + +static int _POSIX_Barrier_Return_codes[CORE_BARRIER_STATUS_LAST + 1] = { + 0, /* CORE_BARRIER_STATUS_SUCCESSFUL */ + PTHREAD_BARRIER_SERIAL_THREAD, + /* CORE_BARRIER_STATUS_AUTOMATICALLY_RELEASED */ + -1, /* CORE_BARRIER_WAS_DELETED */ + 0 /* CORE_BARRIER_TIMEOUT */ +}; + + +int _POSIX_Barrier_Translate_core_barrier_return_code( + CORE_barrier_Status the_barrier_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_barrier_status > CORE_BARRIER_STATUS_LAST ) + return EINVAL; + #endif + return _POSIX_Barrier_Return_codes[the_barrier_status]; +} diff --git a/cpukit/posix/src/pbarrierwait.c b/cpukit/posix/src/pbarrierwait.c new file mode 100644 index 0000000000..71533b65b1 --- /dev/null +++ b/cpukit/posix/src/pbarrierwait.c @@ -0,0 +1,71 @@ +/* + * POSIX Barrier Manager -- Wait at a Barrier + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/barrier.h> + +/* + * pthread_barrier_wait + * + * This directive allows a thread to wait at a barrier. + * + * Input parameters: + * barrier - barrier id + * + * Output parameters: + * 0 - if successful + * PTHREAD_BARRIER_SERIAL_THREAD - if successful + * error code - if unsuccessful + */ + +int pthread_barrier_wait( + pthread_barrier_t *barrier +) +{ + POSIX_Barrier_Control *the_barrier = NULL; + Objects_Locations location; + + if ( !barrier ) + return EINVAL; + + the_barrier = _POSIX_Barrier_Get( barrier, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _CORE_barrier_Wait( + &the_barrier->Barrier, + the_barrier->Object.id, + true, + 0, + NULL + ); + _Thread_Enable_dispatch(); + return _POSIX_Barrier_Translate_core_barrier_return_code( + _Thread_Executing->Wait.return_code ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/posixtimespecabsolutetimeout.c b/cpukit/posix/src/posixtimespecabsolutetimeout.c new file mode 100644 index 0000000000..27d5db5abe --- /dev/null +++ b/cpukit/posix/src/posixtimespecabsolutetimeout.c @@ -0,0 +1,88 @@ +/* + * Convert abstime timeout to ticks + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/* + * The abstime is a walltime. We turn it into an interval. + */ +POSIX_Absolute_timeout_conversion_results_t _POSIX_Absolute_timeout_to_ticks( + const struct timespec *abstime, + Watchdog_Interval *ticks_out +) +{ + struct timespec current_time; + struct timespec difference; + + + /* + * Make sure there is always a value returned. + */ + *ticks_out = 0; + + /* + * Is the absolute time even valid? + */ + if ( !_Timespec_Is_valid(abstime) ) + return POSIX_ABSOLUTE_TIMEOUT_INVALID; + + /* + * Is the absolute time in the past? + */ + _TOD_Get( ¤t_time ); + + if ( _Timespec_Less_than( abstime, ¤t_time ) ) + return POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST; + + /* + * How long until the requested absolute time? + */ + _Timespec_Subtract( ¤t_time, abstime, &difference ); + + /* + * Internally the SuperCore uses ticks, so convert to them. + */ + *ticks_out = _Timespec_To_ticks( &difference ); + + /* + * If the difference was 0, then the future is now. It is so bright + * we better wear shades. + */ + if ( !*ticks_out ) + return POSIX_ABSOLUTE_TIMEOUT_IS_NOW; + + /* + * This is the case we were expecting and it took this long to + * get here. + */ + return POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE; +} + diff --git a/cpukit/posix/src/prwlock.c b/cpukit/posix/src/prwlock.c new file mode 100644 index 0000000000..9c3fd707d8 --- /dev/null +++ b/cpukit/posix/src/prwlock.c @@ -0,0 +1,45 @@ +/* + * RWLock Manager -- Initialization + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/posix/rwlock.h> + +/** + * @brief _POSIX_RWLock_Manager_initialization + */ + +void _POSIX_RWLock_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_RWLock_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_SPINLOCKS, /* object class */ + Configuration_POSIX_API.maximum_rwlocks, + /* maximum objects of this class */ + sizeof( POSIX_RWLock_Control ), /* size of this object's control block */ + true, /* true if the name is a string */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/prwlockdestroy.c b/cpukit/posix/src/prwlockdestroy.c new file mode 100644 index 0000000000..8b32517c37 --- /dev/null +++ b/cpukit/posix/src/prwlockdestroy.c @@ -0,0 +1,80 @@ +/* + * POSIX RWLock Manager -- Destroy a RWLock + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_destroy + * + * This directive allows a thread to delete a rwlock specified by + * the rwlock id. The rwlock is freed back to the inactive + * rwlock chain. + * + * Input parameters: + * rwlock - rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_destroy( + pthread_rwlock_t *rwlock +) +{ + POSIX_RWLock_Control *the_rwlock = NULL; + Objects_Locations location; + + if ( !rwlock ) + return EINVAL; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + /* + * If there is at least one thread waiting, then do not delete it. + */ + if ( _Thread_queue_First( &the_rwlock->RWLock.Wait_queue ) != NULL ) { + _Thread_Enable_dispatch(); + return EBUSY; + } + + /* + * POSIX doesn't require behavior when it is locked. + */ + + _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); + + _POSIX_RWLock_Free( the_rwlock ); + + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlockinit.c b/cpukit/posix/src/prwlockinit.c new file mode 100644 index 0000000000..c79b260b50 --- /dev/null +++ b/cpukit/posix/src/prwlockinit.c @@ -0,0 +1,110 @@ +/* + * POSIX RWLock Manager -- Destroy a RWLock Instance + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_init + * + * This directive creates a rwlock. A rwlock id is returned. + * + * Input parameters: + * rwlock - pointer to rwlock id + * attr - rwlock attributes + * + * Output parameters: + * rwlock - rwlock id + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_init( + pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr +) +{ + POSIX_RWLock_Control *the_rwlock; + CORE_RWLock_Attributes the_attributes; + pthread_rwlockattr_t default_attr; + const pthread_rwlockattr_t *the_attr; + + /* + * Error check parameters + */ + if ( !rwlock ) + return EINVAL; + + /* + * If the user passed in NULL, use the default attributes + */ + if ( attr ) { + the_attr = attr; + } else { + (void) pthread_rwlockattr_init( &default_attr ); + the_attr = &default_attr; + } + + /* + * Now start error checking the attributes that we are going to use + */ + if ( !the_attr->is_initialized ) + return EINVAL; + + switch ( the_attr->process_shared ) { + case PTHREAD_PROCESS_PRIVATE: /* only supported values */ + break; + case PTHREAD_PROCESS_SHARED: + default: + return EINVAL; + } + + /* + * Convert from POSIX attributes to Core RWLock attributes + * + * NOTE: Currently there are no core rwlock attributes + */ + _CORE_RWLock_Initialize_attributes( &the_attributes ); + + /* + * Enter dispatching critical section to allocate and initialize RWLock + */ + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_rwlock = _POSIX_RWLock_Allocate(); + + if ( !the_rwlock ) { + _Thread_Enable_dispatch(); + return EAGAIN; + } + + _CORE_RWLock_Initialize( &the_rwlock->RWLock, &the_attributes ); + + _Objects_Open_u32( + &_POSIX_RWLock_Information, + &the_rwlock->Object, + 0 + ); + + *rwlock = the_rwlock->Object.id; + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/prwlockrdlock.c b/cpukit/posix/src/prwlockrdlock.c new file mode 100644 index 0000000000..fe9d6196d9 --- /dev/null +++ b/cpukit/posix/src/prwlockrdlock.c @@ -0,0 +1,73 @@ +/* + * POSIX RWLock Manager -- Obtain a Read Lock on a RWLock Instance + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_rdlock + * + * This directive attempts to obtain a read only lock on an rwlock instance. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_rdlock( + pthread_rwlock_t *rwlock +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + + if ( !rwlock ) + return EINVAL; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _CORE_RWLock_Obtain_for_reading( + &the_rwlock->RWLock, + *rwlock, + true, /* we are willing to wait forever */ + 0, + NULL + ); + + _Thread_Enable_dispatch(); + return _POSIX_RWLock_Translate_core_RWLock_return_code( + (CORE_RWLock_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlocktimedrdlock.c b/cpukit/posix/src/prwlocktimedrdlock.c new file mode 100644 index 0000000000..d6df7815a8 --- /dev/null +++ b/cpukit/posix/src/prwlocktimedrdlock.c @@ -0,0 +1,105 @@ +/* + * POSIX RWLock Manager -- Attempt to Obtain a Read Lock on a RWLock Instance + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> +#include <rtems/posix/time.h> + +/* + * pthread_rwlock_timedrdlock + * + * This directive attempts to obtain a read only lock on an rwlock instance. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_timedrdlock( + pthread_rwlock_t *rwlock, + const struct timespec *abstime +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + Watchdog_Interval ticks; + bool do_wait = true; + POSIX_Absolute_timeout_conversion_results_t status; + + if ( !rwlock ) + return EINVAL; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + * + * If the status is POSIX_ABSOLUTE_TIMEOUT_INVALID, + * POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, or POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + * then we should not wait. + */ + status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ); + if ( status != POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) + do_wait = false; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _CORE_RWLock_Obtain_for_reading( + &the_rwlock->RWLock, + *rwlock, + do_wait, + ticks, + NULL + ); + + _Thread_Enable_dispatch(); + if ( !do_wait ) { + if ( _Thread_Executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE ) { + if ( status == POSIX_ABSOLUTE_TIMEOUT_INVALID ) + return EINVAL; + if ( status == POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST || + status == POSIX_ABSOLUTE_TIMEOUT_IS_NOW ) + return ETIMEDOUT; + } + } + + return _POSIX_RWLock_Translate_core_RWLock_return_code( + (CORE_RWLock_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlocktimedwrlock.c b/cpukit/posix/src/prwlocktimedwrlock.c new file mode 100644 index 0000000000..d34ee69489 --- /dev/null +++ b/cpukit/posix/src/prwlocktimedwrlock.c @@ -0,0 +1,104 @@ +/* + * POSIX RWLock Manager -- Attempt to Obtain a Write Lock on a RWLock Instance + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> +#include <rtems/posix/time.h> + +/* + * pthread_rwlock_timedwrlock + * + * This directive attempts to obtain a write only lock on an rwlock instance. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_timedwrlock( + pthread_rwlock_t *rwlock, + const struct timespec *abstime +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + Watchdog_Interval ticks; + bool do_wait = true; + POSIX_Absolute_timeout_conversion_results_t status; + + if ( !rwlock ) + return EINVAL; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + * + * If the status is POSIX_ABSOLUTE_TIMEOUT_INVALID, + * POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, or POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + * then we should not wait. + */ + status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ); + if ( status != POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) + do_wait = false; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _CORE_RWLock_Obtain_for_writing( + &the_rwlock->RWLock, + *rwlock, + do_wait, + ticks, + NULL + ); + + _Thread_Enable_dispatch(); + if ( !do_wait && + (_Thread_Executing->Wait.return_code == CORE_RWLOCK_UNAVAILABLE) ) { + if ( status == POSIX_ABSOLUTE_TIMEOUT_INVALID ) + return EINVAL; + if ( status == POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST || + status == POSIX_ABSOLUTE_TIMEOUT_IS_NOW ) + return ETIMEDOUT; + } + + return _POSIX_RWLock_Translate_core_RWLock_return_code( + (CORE_RWLock_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlocktranslatereturncode.c b/cpukit/posix/src/prwlocktranslatereturncode.c new file mode 100644 index 0000000000..3378d577b2 --- /dev/null +++ b/cpukit/posix/src/prwlocktranslatereturncode.c @@ -0,0 +1,55 @@ +/* + * RWLock Manager -- Translate SuperCore Status + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * _POSIX_RWLock_Translate_core_rwlock_return_code + * + * Input parameters: + * the_rwlock_status - rwlock status code to translate + * + * Output parameters: + * status code - translated POSIX status code + * + */ + +static int _POSIX_RWLock_Return_codes[CORE_RWLOCK_STATUS_LAST + 1] = { + 0, /* CORE_RWLOCK_SUCCESSFUL */ + EINVAL, /* CORE_RWLOCK_DELETED */ + EBUSY, /* CORE_RWLOCK_UNAVAILABLE */ + ETIMEDOUT, /* CORE_RWLOCK_TIMEOUT */ +}; + + +int _POSIX_RWLock_Translate_core_RWLock_return_code( + CORE_RWLock_Status the_rwlock_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_rwlock_status > CORE_RWLOCK_STATUS_LAST ) + return EINVAL; + #endif + return _POSIX_RWLock_Return_codes[the_rwlock_status]; +} diff --git a/cpukit/posix/src/prwlocktryrdlock.c b/cpukit/posix/src/prwlocktryrdlock.c new file mode 100644 index 0000000000..f07edf5f4d --- /dev/null +++ b/cpukit/posix/src/prwlocktryrdlock.c @@ -0,0 +1,74 @@ +/* + * POSIX RWLock Manager -- Attempt to Obtain a Read Lock on a RWLock Instance + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_tryrdlock + * + * This directive attempts to obtain a read only lock on an rwlock instance. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_tryrdlock( + pthread_rwlock_t *rwlock +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + + if ( !rwlock ) + return EINVAL; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _CORE_RWLock_Obtain_for_reading( + &the_rwlock->RWLock, + *rwlock, + false, /* do not wait for the rwlock */ + 0, + NULL + ); + + + _Thread_Enable_dispatch(); + return _POSIX_RWLock_Translate_core_RWLock_return_code( + (CORE_RWLock_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlocktrywrlock.c b/cpukit/posix/src/prwlocktrywrlock.c new file mode 100644 index 0000000000..326e643910 --- /dev/null +++ b/cpukit/posix/src/prwlocktrywrlock.c @@ -0,0 +1,73 @@ +/* + * POSIX RWLock Manager -- Attempt to Obtain a Write Lock on a RWLock Instance + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_trywrlock + * + * This directive attempts to obtain a Write only lock on an rwlock instance. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_trywrlock( + pthread_rwlock_t *rwlock +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + + if ( !rwlock ) + return EINVAL; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _CORE_RWLock_Obtain_for_writing( + &the_rwlock->RWLock, + *rwlock, + false, /* we are not willing to wait */ + 0, + NULL + ); + + _Thread_Enable_dispatch(); + return _POSIX_RWLock_Translate_core_RWLock_return_code( + (CORE_RWLock_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlockunlock.c b/cpukit/posix/src/prwlockunlock.c new file mode 100644 index 0000000000..665ee1fb34 --- /dev/null +++ b/cpukit/posix/src/prwlockunlock.c @@ -0,0 +1,64 @@ +/* + * POSIX RWLock Manager -- Release a lock held on a RWLock Instance + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_unlock + * + * This directive attempts to release a lock on an RWLock. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_unlock( + pthread_rwlock_t *rwlock +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + CORE_RWLock_Status status; + + if ( !rwlock ) + return EINVAL; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_RWLock_Release( &the_rwlock->RWLock ); + _Thread_Enable_dispatch(); + return _POSIX_RWLock_Translate_core_RWLock_return_code( status ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/prwlockwrlock.c b/cpukit/posix/src/prwlockwrlock.c new file mode 100644 index 0000000000..61d5facbef --- /dev/null +++ b/cpukit/posix/src/prwlockwrlock.c @@ -0,0 +1,73 @@ +/* + * POSIX RWLock Manager -- Obtain a Write Lock on a RWLock Instance + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/rwlock.h> + +/* + * pthread_rwlock_wrlock + * + * This directive attempts to obtain a write only lock on an rwlock instance. + * + * Input parameters: + * rwlock - pointer to rwlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_rwlock_wrlock( + pthread_rwlock_t *rwlock +) +{ + POSIX_RWLock_Control *the_rwlock; + Objects_Locations location; + + if ( !rwlock ) + return EINVAL; + + the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + _CORE_RWLock_Obtain_for_writing( + &the_rwlock->RWLock, + *rwlock, + true, /* do not timeout -- wait forever */ + 0, + NULL + ); + + _Thread_Enable_dispatch(); + return _POSIX_RWLock_Translate_core_RWLock_return_code( + (CORE_RWLock_Status) _Thread_Executing->Wait.return_code + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c new file mode 100644 index 0000000000..3040718874 --- /dev/null +++ b/cpukit/posix/src/psignal.c @@ -0,0 +1,224 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_DEBUG) + #include <assert.h> +#endif +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <string.h> /* memcpy */ +#include <stdlib.h> /* exit */ + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tqdata.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/threadsup.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/time.h> +#include <stdio.h> + +/*** PROCESS WIDE STUFF ****/ + +sigset_t _POSIX_signals_Pending; + +void _POSIX_signals_Abnormal_termination_handler( + int signo __attribute__((unused)) ) +{ + exit( 1 ); +} + +#define SIG_ARRAY_MAX (SIGRTMAX + 1) +const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ] = { + /* NO SIGNAL 0 */ SIGACTION_IGNORE, + /* SIGHUP 1 */ SIGACTION_TERMINATE, + /* SIGINT 2 */ SIGACTION_TERMINATE, + /* SIGQUIT 3 */ SIGACTION_TERMINATE, + /* SIGILL 4 */ SIGACTION_TERMINATE, + /* SIGTRAP 5 */ SIGACTION_TERMINATE, + /* SIGIOT 6 */ SIGACTION_TERMINATE, + /* SIGABRT 6 SIGACTION_TERMINATE, -- alias for SIGIOT */ + /* SIGEMT 7 */ SIGACTION_TERMINATE, + /* SIGFPE 8 */ SIGACTION_TERMINATE, + /* SIGKILL 9 */ SIGACTION_TERMINATE, + /* SIGBUS 10 */ SIGACTION_TERMINATE, + /* SIGSEGV 11 */ SIGACTION_TERMINATE, + /* SIGSYS 12 */ SIGACTION_TERMINATE, + /* SIGPIPE 13 */ SIGACTION_TERMINATE, + /* SIGALRM 14 */ SIGACTION_TERMINATE, + /* SIGTERM 15 */ SIGACTION_TERMINATE, + /* SIGURG 16 */ SIGACTION_TERMINATE, + /* SIGSTOP 17 */ SIGACTION_TERMINATE, + /* SIGTSTP 18 */ SIGACTION_TERMINATE, + /* SIGCONT 19 */ SIGACTION_TERMINATE, + /* SIGCHLD 20 */ SIGACTION_TERMINATE, + /* SIGTTIN 21 */ SIGACTION_TERMINATE, + /* SIGTTOU 22 */ SIGACTION_TERMINATE, + /* SIGIO 23 */ SIGACTION_TERMINATE, + /* SIGWINCH 24 */ SIGACTION_TERMINATE, + /* SIGUSR1 25 */ SIGACTION_TERMINATE, + /* SIGUSR2 26 */ SIGACTION_TERMINATE, + /* SIGRT 27 */ SIGACTION_TERMINATE, + /* SIGRT 28 */ SIGACTION_TERMINATE, + /* SIGRT 29 */ SIGACTION_TERMINATE, + /* SIGRT 30 */ SIGACTION_TERMINATE, + /* SIGRTMAX 31 */ SIGACTION_TERMINATE +}; + +struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; + +Thread_queue_Control _POSIX_signals_Wait_queue; + +Chain_Control _POSIX_signals_Inactive_siginfo; +Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; + +Watchdog_Control _POSIX_signals_Alarm_timer; +Watchdog_Control _POSIX_signals_Ualarm_timer; + +/*PAGE + * + * XXX - move these + */ + +#define _States_Is_interruptible_signal( _states ) \ + ( ((_states) & \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) + +/* + * _POSIX_signals_Post_switch_extension + */ + +void _POSIX_signals_Post_switch_extension( + Thread_Control *the_thread +) +{ + POSIX_API_Control *api; + int signo; + ISR_Level level; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + /* + * api may be NULL in case of a thread close in progress + */ + if ( !api ) + return; + + /* + * If we invoke any user code, there is the possibility that + * a new signal has been posted that we should process so we + * restart the loop if a signal handler was invoked. + * + * The first thing done is to check there are any signals to be + * processed at all. No point in doing this loop otherwise. + */ + while (1) { + _ISR_Disable( level ); + if ( !(~api->signals_blocked & + (api->signals_pending | _POSIX_signals_Pending)) ) { + _ISR_Enable( level ); + break; + } + _ISR_Enable( level ); + + for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { + _POSIX_signals_Check_signal( api, signo, false ); + _POSIX_signals_Check_signal( api, signo, true ); + } + /* Unfortunately - nothing like __SIGFIRSTNOTRT in newlib signal .h */ + + for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) { + _POSIX_signals_Check_signal( api, signo, false ); + _POSIX_signals_Check_signal( api, signo, true ); + } + } +} + +/*PAGE + * + * _POSIX_signals_Manager_Initialization + */ + +void _POSIX_signals_Manager_Initialization(void) +{ + uint32_t signo; + uint32_t maximum_queued_signals; + + maximum_queued_signals = Configuration_POSIX_API.maximum_queued_signals; + + /* + * Ensure we have the same number of vectors and default vector entries + */ + + #if defined(RTEMS_DEBUG) + assert( + sizeof(_POSIX_signals_Vectors) == sizeof(_POSIX_signals_Default_vectors) + ); + #endif + + memcpy( + _POSIX_signals_Vectors, + _POSIX_signals_Default_vectors, + sizeof( _POSIX_signals_Vectors ) + ); + + /* + * Initialize the set of pending signals for the entire process + */ + sigemptyset( &_POSIX_signals_Pending ); + + /* + * Initialize the queue we use to block for signals + */ + _Thread_queue_Initialize( + &_POSIX_signals_Wait_queue, + THREAD_QUEUE_DISCIPLINE_FIFO, + STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, + EAGAIN + ); + + /* XXX status codes */ + + /* + * Allocate the siginfo pools. + */ + for ( signo=1 ; signo<= SIGRTMAX ; signo++ ) + _Chain_Initialize_empty( &_POSIX_signals_Siginfo[ signo ] ); + + if ( maximum_queued_signals ) { + _Chain_Initialize( + &_POSIX_signals_Inactive_siginfo, + _Workspace_Allocate_or_fatal_error( + maximum_queued_signals * sizeof( POSIX_signals_Siginfo_node ) + ), + maximum_queued_signals, + sizeof( POSIX_signals_Siginfo_node ) + ); + } else { + _Chain_Initialize_empty( &_POSIX_signals_Inactive_siginfo ); + } + + /* + * Initialize the Alarm Timer + */ + _Watchdog_Initialize( &_POSIX_signals_Alarm_timer, NULL, 0, NULL ); + _Watchdog_Initialize( &_POSIX_signals_Ualarm_timer, NULL, 0, NULL ); +} diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c new file mode 100644 index 0000000000..8bba7a4226 --- /dev/null +++ b/cpukit/posix/src/psignalchecksignal.c @@ -0,0 +1,113 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined(RTEMS_DEBUG) + #include <assert.h> +#endif +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <string.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tqdata.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/threadsup.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/time.h> +#include <stdio.h> + + +/*PAGE + * + * _POSIX_signals_Check_signal + */ + +bool _POSIX_signals_Check_signal( + POSIX_API_Control *api, + int signo, + bool is_global +) +{ + siginfo_t siginfo_struct; + sigset_t saved_signals_blocked; + Thread_Wait_information stored_thread_wait_information; + + if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct, + is_global, true ) ) + return false; + + /* + * Since we made a union of these, only one test is necessary but this is + * safer. + */ + #if defined(RTEMS_DEBUG) + assert( _POSIX_signals_Vectors[ signo ].sa_handler || + _POSIX_signals_Vectors[ signo ].sa_sigaction ); + #endif + + /* + * Just to prevent sending a signal which is currently being ignored. + */ + if ( _POSIX_signals_Vectors[ signo ].sa_handler == SIG_IGN ) + return false; + + /* + * Block the signals requested in sa_mask + */ + saved_signals_blocked = api->signals_blocked; + api->signals_blocked |= _POSIX_signals_Vectors[ signo ].sa_mask; + + /* + * We have to save the blocking information of the current wait queue + * because the signal handler may subsequently go on and put the thread + * on a wait queue, for its own purposes. + */ + memcpy( &stored_thread_wait_information, &_Thread_Executing->Wait, + sizeof( Thread_Wait_information )); + + /* + * Here, the signal handler function executes + */ + switch ( _POSIX_signals_Vectors[ signo ].sa_flags ) { + case SA_SIGINFO: + (*_POSIX_signals_Vectors[ signo ].sa_sigaction)( + signo, + &siginfo_struct, + NULL /* context is undefined per 1003.1b-1993, p. 66 */ + ); + break; + default: + (*_POSIX_signals_Vectors[ signo ].sa_handler)( signo ); + break; + } + + /* + * Restore the blocking information + */ + memcpy( &_Thread_Executing->Wait, &stored_thread_wait_information, + sizeof( Thread_Wait_information )); + + /* + * Restore the previous set of blocked signals + */ + api->signals_blocked = saved_signals_blocked; + + return true; +} diff --git a/cpukit/posix/src/psignalclearprocesssignals.c b/cpukit/posix/src/psignalclearprocesssignals.c new file mode 100644 index 0000000000..b11ae0ebc2 --- /dev/null +++ b/cpukit/posix/src/psignalclearprocesssignals.c @@ -0,0 +1,58 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tqdata.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/threadsup.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/time.h> +#include <stdio.h> + +/*PAGE + * + * _POSIX_signals_Clear_process_signals + */ + +void _POSIX_signals_Clear_process_signals( + int signo +) +{ + sigset_t mask; + bool clear_signal; + + clear_signal = true; + mask = signo_to_mask( signo ); + + ISR_Level level; + + _ISR_Disable( level ); + if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { + if ( !_Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) ) + clear_signal = false; + } + if ( clear_signal ) { + _POSIX_signals_Pending &= ~mask; + } + _ISR_Enable( level ); +} diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c new file mode 100644 index 0000000000..09942f3bb5 --- /dev/null +++ b/cpukit/posix/src/psignalclearsignals.c @@ -0,0 +1,99 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tqdata.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/threadsup.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/time.h> +#include <stdio.h> + +/*PAGE + * + * _POSIX_signals_Clear_signals + */ + +bool _POSIX_signals_Clear_signals( + POSIX_API_Control *api, + int signo, + siginfo_t *info, + bool is_global, + bool check_blocked +) +{ + sigset_t mask; + sigset_t signals_blocked; + ISR_Level level; + bool do_callout; + POSIX_signals_Siginfo_node *psiginfo; + + mask = signo_to_mask( signo ); + + do_callout = false; + + /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK + * insures that no signals are blocked and all are checked. + */ + + if ( check_blocked ) + signals_blocked = ~api->signals_blocked; + else + signals_blocked = SIGNAL_ALL_MASK; + + /* XXX is this right for siginfo type signals? */ + /* XXX are we sure they can be cleared the same way? */ + + _ISR_Disable( level ); + if ( is_global ) { + if ( mask & (_POSIX_signals_Pending & signals_blocked) ) { + if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) { + psiginfo = (POSIX_signals_Siginfo_node *) + _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] ); + _POSIX_signals_Clear_process_signals( signo ); + /* + * It may be impossible to get here with an empty chain + * BUT until that is proven we need to be defensive and + * protect against it. + */ + if ( psiginfo ) { + *info = psiginfo->Info; + _Chain_Append_unprotected( + &_POSIX_signals_Inactive_siginfo, + &psiginfo->Node + ); + } else + do_callout = false; + } + _POSIX_signals_Clear_process_signals( signo ); + do_callout = true; + } + } else { + if ( mask & (api->signals_pending & signals_blocked) ) { + api->signals_pending &= ~mask; + do_callout = true; + } + } + _ISR_Enable( level ); + return do_callout; +} diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c new file mode 100644 index 0000000000..cb4ad8b241 --- /dev/null +++ b/cpukit/posix/src/psignalsetprocesssignals.c @@ -0,0 +1,46 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tqdata.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/threadsup.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/time.h> +#include <stdio.h> + +/*PAGE + * + * _POSIX_signals_Set_process_signals + */ + +void _POSIX_signals_Set_process_signals( + sigset_t mask +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _POSIX_signals_Pending |= mask; + _ISR_Enable( level ); +} diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c new file mode 100644 index 0000000000..f6bf5fcc7d --- /dev/null +++ b/cpukit/posix/src/psignalunblockthread.c @@ -0,0 +1,120 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tqdata.h> +#include <rtems/score/wkspace.h> +#include <rtems/seterr.h> +#include <rtems/posix/threadsup.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/time.h> +#include <stdio.h> + + +/*PAGE + * + * _POSIX_signals_Unblock_thread + */ + +/* XXX this routine could probably be cleaned up */ +bool _POSIX_signals_Unblock_thread( + Thread_Control *the_thread, + int signo, + siginfo_t *info +) +{ + POSIX_API_Control *api; + sigset_t mask; + siginfo_t *the_info = NULL; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + mask = signo_to_mask( signo ); + + /* + * Is the thread is specifically waiting for a signal? + */ + + if ( _States_Is_interruptible_signal( the_thread->current_state ) ) { + + if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) { + the_thread->Wait.return_code = EINTR; + + the_info = (siginfo_t *) the_thread->Wait.return_argument; + + if ( !info ) { + the_info->si_signo = signo; + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + } else { + *the_info = *info; + } + + _Thread_queue_Extract_with_proxy( the_thread ); + return true; + } + + /* + * This should only be reached via pthread_kill(). + */ + + return false; + } + + /* + * Thread is not waiting due to a sigwait. + */ + if ( ~api->signals_blocked & mask ) { + + /* + * The thread is interested in this signal. We are going + * to post it. We have a few broad cases: + * + If it is blocked on an interruptible signal, THEN + * we unblock the thread. + * + If it is in the ready state AND + * we are sending from an ISR AND + * it is the interrupted thread AND + * it is not blocked, THEN + * we need to dispatch at the end of this ISR. + * + Any other combination, do nothing. + */ + + if ( _States_Is_interruptible_by_signal( the_thread->current_state ) ) { + the_thread->Wait.return_code = EINTR; + /* + * In pthread_cond_wait, a thread will be blocking on a thread + * queue, but is also interruptible by a POSIX signal. + */ + if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) ) + _Thread_queue_Extract_with_proxy( the_thread ); + else if ( _States_Is_delaying(the_thread->current_state) ) { + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + } else if ( the_thread->current_state == STATES_READY ) { + if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) ) + _Thread_Dispatch_necessary = true; + } + } + return false; +} diff --git a/cpukit/posix/src/pspin.c b/cpukit/posix/src/pspin.c new file mode 100644 index 0000000000..88dadf2cba --- /dev/null +++ b/cpukit/posix/src/pspin.c @@ -0,0 +1,57 @@ +/* + * Spinlock Manager + * + * DESCRIPTION: + * + * This package is the implementation of the Spinlock Manager. + * + * Directives provided are: + * + * + create a spinlock + * + get an ID of a spinlock + * + delete a spinlock + * + acquire a spinlock + * + release a spinlock + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/posix/spinlock.h> + +/** + * @brief _POSIX_Spinlock_Manager_initialization + */ + +void _POSIX_Spinlock_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Spinlock_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_SPINLOCKS, /* object class */ + Configuration_POSIX_API.maximum_spinlocks, + /* maximum objects of this class */ + sizeof( POSIX_Spinlock_Control ),/* size of this object's control block */ + true, /* true if the name is a string */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/pspindestroy.c b/cpukit/posix/src/pspindestroy.c new file mode 100644 index 0000000000..aa3c465ec7 --- /dev/null +++ b/cpukit/posix/src/pspindestroy.c @@ -0,0 +1,73 @@ +/* + * POSIX Spinlock Manager -- Destroy a Spinlock + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/spinlock.h> + +/* + * pthread_spin_destroy + * + * This directive allows a thread to delete a spinlock specified by + * the spinlock id. The spinlock is freed back to the inactive + * spinlock chain. + * + * Input parameters: + * spinlock - spinlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_spin_destroy( + pthread_spinlock_t *spinlock +) +{ + POSIX_Spinlock_Control *the_spinlock = NULL; + Objects_Locations location; + + if ( !spinlock ) + return EINVAL; + + the_spinlock = _POSIX_Spinlock_Get( spinlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + if ( _CORE_spinlock_Is_busy( &the_spinlock->Spinlock ) ) { + _Thread_Enable_dispatch(); + return EBUSY; + } + + _Objects_Close( &_POSIX_Spinlock_Information, &the_spinlock->Object ); + + _POSIX_Spinlock_Free( the_spinlock ); + + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/pspininit.c b/cpukit/posix/src/pspininit.c new file mode 100644 index 0000000000..bab6ac3140 --- /dev/null +++ b/cpukit/posix/src/pspininit.c @@ -0,0 +1,78 @@ +/* + * POSIX Spinlock Manager -- Initialize a Spinlock Instance + * + * COPYRIGHT (c) 1989-2006. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/spinlock.h> + +/* + * pthread_spinlock_init + * + * This directive creates a spinlock. A spinlock id is returned. + * + * Input parameters: + * spinlock - pointer to spinlock id + * pshared - is this spinlock shared between processes + * + * Output parameters: + * spinlock - spinlock id + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_spin_init( + pthread_spinlock_t *spinlock, + int pshared +) +{ + POSIX_Spinlock_Control *the_spinlock; + CORE_spinlock_Attributes attributes; + + + if ( !spinlock ) + return EINVAL; + + switch ( pshared ) { + case PTHREAD_PROCESS_PRIVATE: /* only supported values */ + break; + case PTHREAD_PROCESS_SHARED: + default: + return EINVAL; + } + + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_spinlock = _POSIX_Spinlock_Allocate(); + + if ( !the_spinlock ) { + _Thread_Enable_dispatch(); + return EAGAIN; + } + + _CORE_spinlock_Initialize_attributes( &attributes ); + + _CORE_spinlock_Initialize( &the_spinlock->Spinlock, &attributes ); + + _Objects_Open_u32( &_POSIX_Spinlock_Information, &the_spinlock->Object, 0 ); + + *spinlock = the_spinlock->Object.id; + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/pspinlock.c b/cpukit/posix/src/pspinlock.c new file mode 100644 index 0000000000..845117a3e3 --- /dev/null +++ b/cpukit/posix/src/pspinlock.c @@ -0,0 +1,64 @@ +/* + * POSIX Spinlock Manager -- Wait at a Spinlock + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/spinlock.h> + +/* + * pthread_spin_lock + * + * This directive allows a thread to wait at a spinlock. + * + * Input parameters: + * spinlock - spinlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_spin_lock( + pthread_spinlock_t *spinlock +) +{ + POSIX_Spinlock_Control *the_spinlock = NULL; + Objects_Locations location; + CORE_spinlock_Status status; + + if ( !spinlock ) + return EINVAL; + + the_spinlock = _POSIX_Spinlock_Get( spinlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_spinlock_Wait( &the_spinlock->Spinlock, true, 0 ); + _Thread_Enable_dispatch(); + return _POSIX_Spinlock_Translate_core_spinlock_return_code( status ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/pspinlocktranslatereturncode.c b/cpukit/posix/src/pspinlocktranslatereturncode.c new file mode 100644 index 0000000000..fbce440010 --- /dev/null +++ b/cpukit/posix/src/pspinlocktranslatereturncode.c @@ -0,0 +1,58 @@ +/* + * Spinlock Manager -- Translate SuperCore Status + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/corespinlock.h> + +/* + * _POSIX_Spinlock_Translate_core_spinlock_return_code + * + * Input parameters: + * the_spinlock_status - spinlock status code to translate + * + * Output parameters: + * status code - translated POSIX status code + * + */ + +static int _POSIX_Spinlock_Return_codes[CORE_SPINLOCK_STATUS_LAST + 1] = { + 0, /* CORE_SPINLOCK_SUCCESSFUL */ + EDEADLK, /* CORE_SPINLOCK_HOLDER_RELOCKING */ + EPERM, /* CORE_SPINLOCK_NOT_HOLDER */ + -1, /* CORE_SPINLOCK_TIMEOUT */ + EBUSY, /* CORE_SPINLOCK_IS_BUSY */ + EBUSY, /* CORE_SPINLOCK_UNAVAILABLE */ + 0 /* CORE_SPINLOCK_NOT_LOCKED */ +}; + + +int _POSIX_Spinlock_Translate_core_spinlock_return_code( + CORE_spinlock_Status the_spinlock_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_spinlock_status > CORE_SPINLOCK_STATUS_LAST ) + return EINVAL; + #endif + return _POSIX_Spinlock_Return_codes[the_spinlock_status]; +} diff --git a/cpukit/posix/src/pspintrylock.c b/cpukit/posix/src/pspintrylock.c new file mode 100644 index 0000000000..7e66d88e8b --- /dev/null +++ b/cpukit/posix/src/pspintrylock.c @@ -0,0 +1,64 @@ +/* + * POSIX Spinlock Manager -- Wait at a Spinlock + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/spinlock.h> + +/* + * pthread_spin_trylock + * + * This directive allows a thread to poll an attempt at locking a spinlock. + * + * Input parameters: + * spinlock - spinlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_spin_trylock( + pthread_spinlock_t *spinlock +) +{ + POSIX_Spinlock_Control *the_spinlock = NULL; + Objects_Locations location; + CORE_spinlock_Status status; + + if ( !spinlock ) + return EINVAL; + + the_spinlock = _POSIX_Spinlock_Get( spinlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_spinlock_Wait( &the_spinlock->Spinlock, false, 0 ); + _Thread_Enable_dispatch(); + return _POSIX_Spinlock_Translate_core_spinlock_return_code( status ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/pspinunlock.c b/cpukit/posix/src/pspinunlock.c new file mode 100644 index 0000000000..8bbf4f2f61 --- /dev/null +++ b/cpukit/posix/src/pspinunlock.c @@ -0,0 +1,64 @@ +/* + * POSIX Spinlock Manager -- Wait at a Spinlock + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/spinlock.h> + +/* + * pthread_spin_unlock + * + * This directive allows a thread to wait at a spinlock. + * + * Input parameters: + * spinlock - spinlock id + * + * Output parameters: + * 0 - if successful + * error code - if unsuccessful + */ + +int pthread_spin_unlock( + pthread_spinlock_t *spinlock +) +{ + POSIX_Spinlock_Control *the_spinlock = NULL; + Objects_Locations location; + CORE_spinlock_Status status; + + if ( !spinlock ) + return EINVAL; + + the_spinlock = _POSIX_Spinlock_Get( spinlock, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _CORE_spinlock_Release( &the_spinlock->Spinlock ); + _Thread_Enable_dispatch(); + return _POSIX_Spinlock_Translate_core_spinlock_return_code( status ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/psxpriorityisvalid.c b/cpukit/posix/src/psxpriorityisvalid.c new file mode 100644 index 0000000000..4b35a81e62 --- /dev/null +++ b/cpukit/posix/src/psxpriorityisvalid.c @@ -0,0 +1,27 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/posix/priority.h> + +bool _POSIX_Priority_Is_valid( + int priority +) +{ + return ((priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY) && + (priority <= POSIX_SCHEDULER_MAXIMUM_PRIORITY)); + +} + diff --git a/cpukit/posix/src/psxtransschedparam.c b/cpukit/posix/src/psxtransschedparam.c new file mode 100644 index 0000000000..7be4dcc641 --- /dev/null +++ b/cpukit/posix/src/psxtransschedparam.c @@ -0,0 +1,73 @@ +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int _POSIX_Thread_Translate_sched_param( + int policy, + struct sched_param *param, + Thread_CPU_budget_algorithms *budget_algorithm, + Thread_CPU_budget_algorithm_callout *budget_callout +) +{ + if ( !_POSIX_Priority_Is_valid( param->sched_priority ) ) + return EINVAL; + + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + *budget_callout = NULL; + + if ( policy == SCHED_OTHER ) { + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; + return 0; + } + + if ( policy == SCHED_FIFO ) { + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + return 0; + } + + if ( policy == SCHED_RR ) { + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE; + return 0; + } + + if ( policy == SCHED_SPORADIC ) { + if ( (param->sched_ss_repl_period.tv_sec == 0) && + (param->sched_ss_repl_period.tv_nsec == 0) ) + return EINVAL; + + if ( (param->sched_ss_init_budget.tv_sec == 0) && + (param->sched_ss_init_budget.tv_nsec == 0) ) + return EINVAL; + + if ( _Timespec_To_ticks( ¶m->sched_ss_repl_period ) < + _Timespec_To_ticks( ¶m->sched_ss_init_budget ) ) + return EINVAL; + + if ( !_POSIX_Priority_Is_valid( param->sched_ss_low_priority ) ) + return EINVAL; + + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT; + *budget_callout = _POSIX_Threads_Sporadic_budget_callout; + return 0; + } + + return EINVAL; +} diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c new file mode 100644 index 0000000000..3890144aa5 --- /dev/null +++ b/cpukit/posix/src/pthread.c @@ -0,0 +1,366 @@ +/* + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/apiext.h> +#include <rtems/score/stack.h> +#include <rtems/score/thread.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/config.h> +#include <rtems/posix/key.h> +#include <rtems/posix/time.h> +#include <rtems/score/timespec.h> + +/* + * The default pthreads attributes structure. + * + * NOTE: Be careful .. if the default attribute set changes, + * _POSIX_Threads_Initialize_user_threads will need to be examined. + */ +const pthread_attr_t _POSIX_Threads_Default_attributes = { + true, /* is_initialized */ + NULL, /* stackaddr */ + 0, /* stacksize -- will be adjusted to minimum */ + PTHREAD_SCOPE_PROCESS, /* contentionscope */ + PTHREAD_INHERIT_SCHED, /* inheritsched */ + SCHED_FIFO, /* schedpolicy */ + { /* schedparam */ + 2, /* sched_priority */ + #if defined(_POSIX_SPORADIC_SERVER) || \ + defined(_POSIX_THREAD_SPORADIC_SERVER) + 0, /* sched_ss_low_priority */ + { 0L, 0 }, /* sched_ss_repl_period */ + { 0L, 0 } /* sched_ss_init_budget */ + #endif + }, + #if HAVE_DECL_PTHREAD_ATTR_SETGUARDSIZE + 0, /* guardsize */ + #endif + #if defined(_POSIX_THREAD_CPUTIME) + 1, /* cputime_clock_allowed */ + #endif + PTHREAD_CREATE_JOINABLE, /* detachstate */ +}; + +/* + * _POSIX_Threads_Sporadic_budget_TSR + */ +void _POSIX_Threads_Sporadic_budget_TSR( + Objects_Id id __attribute__((unused)), + void *argument +) +{ + uint32_t ticks; + uint32_t new_priority; + Thread_Control *the_thread; + POSIX_API_Control *api; + + the_thread = argument; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + /* ticks is guaranteed to be at least one */ + ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget ); + + the_thread->cpu_time_budget = ticks; + + new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority ); + the_thread->real_priority = new_priority; + + /* + * If holding a resource, then do not change it. + */ + #if 0 + printk( "TSR %d %d %d\n", the_thread->resource_count, + the_thread->current_priority, new_priority ); + #endif + if ( the_thread->resource_count == 0 ) { + /* + * If this would make them less important, then do not change it. + */ + if ( the_thread->current_priority > new_priority ) { + _Thread_Change_priority( the_thread, new_priority, true ); + #if 0 + printk( "raise priority\n" ); + #endif + } + } + + /* ticks is guaranteed to be at least one */ + ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ); + + _Watchdog_Insert_ticks( &api->Sporadic_timer, ticks ); +} + +/* + * _POSIX_Threads_Sporadic_budget_callout + */ +void _POSIX_Threads_Sporadic_budget_callout( + Thread_Control *the_thread +) +{ + POSIX_API_Control *api; + uint32_t new_priority; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + /* + * This will prevent the thread from consuming its entire "budget" + * while at low priority. + */ + the_thread->cpu_time_budget = 0xFFFFFFFF; /* XXX should be based on MAX_U32 */ + + new_priority = _POSIX_Priority_To_core(api->schedparam.sched_ss_low_priority); + the_thread->real_priority = new_priority; + + /* + * If holding a resource, then do not change it. + */ + #if 0 + printk( "callout %d %d %d\n", the_thread->resource_count, + the_thread->current_priority, new_priority ); + #endif + if ( the_thread->resource_count == 0 ) { + /* + * Make sure we are actually lowering it. If they have lowered it + * to logically lower than sched_ss_low_priority, then we do not want to + * change it. + */ + if ( the_thread->current_priority < new_priority ) { + _Thread_Change_priority( the_thread, new_priority, true ); + #if 0 + printk( "lower priority\n" ); + #endif + } + } +} + +/* + * _POSIX_Threads_Create_extension + * + * This method is invoked for each thread created. + */ + +bool _POSIX_Threads_Create_extension( + Thread_Control *executing __attribute__((unused)), + Thread_Control *created +) +{ + POSIX_API_Control *api; + POSIX_API_Control *executing_api; + + api = _Workspace_Allocate( sizeof( POSIX_API_Control ) ); + + if ( !api ) + return false; + + created->API_Extensions[ THREAD_API_POSIX ] = api; + + /* XXX check all fields are touched */ + api->Attributes = _POSIX_Threads_Default_attributes; + api->detachstate = _POSIX_Threads_Default_attributes.detachstate; + api->schedpolicy = _POSIX_Threads_Default_attributes.schedpolicy; + api->schedparam = _POSIX_Threads_Default_attributes.schedparam; + api->schedparam.sched_priority = + _POSIX_Priority_From_core( created->current_priority ); + + /* + * POSIX 1003.1 1996, 18.2.2.2 + */ + api->cancelation_requested = 0; + api->cancelability_state = PTHREAD_CANCEL_ENABLE; + api->cancelability_type = PTHREAD_CANCEL_DEFERRED; + _Chain_Initialize_empty (&api->Cancellation_Handlers); + + /* + * If the thread is not a posix thread, then all posix signals are blocked + * by default. + * + * The check for class == 1 is debug. Should never really happen. + */ + + /* XXX use signal constants */ + api->signals_pending = 0; + if ( _Objects_Get_API( created->Object.id ) == OBJECTS_POSIX_API + #if defined(RTEMS_DEBUG) + && _Objects_Get_class( created->Object.id ) == 1 + #endif + ) { + executing_api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + api->signals_blocked = executing_api->signals_blocked; + } else { + api->signals_blocked = 0xffffffff; + } + + _Thread_queue_Initialize( + &api->Join_List, + THREAD_QUEUE_DISCIPLINE_FIFO, + STATES_WAITING_FOR_JOIN_AT_EXIT, + 0 + ); + + _Watchdog_Initialize( + &api->Sporadic_timer, + _POSIX_Threads_Sporadic_budget_TSR, + created->Object.id, + created + ); + + return true; +} + +/* + * _POSIX_Threads_Delete_extension + * + * This method is invoked for each thread deleted. + */ +void _POSIX_Threads_Delete_extension( + Thread_Control *executing __attribute__((unused)), + Thread_Control *deleted +) +{ + Thread_Control *the_thread; + POSIX_API_Control *api; + void **value_ptr; + + api = deleted->API_Extensions[ THREAD_API_POSIX ]; + + /* + * Run the POSIX cancellation handlers + */ + _POSIX_Threads_cancel_run( deleted ); + + /* + * Run all the key destructors + */ + _POSIX_Keys_Run_destructors( deleted ); + + /* + * Wakeup all the tasks which joined with this one + */ + value_ptr = (void **) deleted->Wait.return_argument; + + while ( (the_thread = _Thread_queue_Dequeue( &api->Join_List )) ) + *(void **)the_thread->Wait.return_argument = value_ptr; + + if ( api->schedpolicy == SCHED_SPORADIC ) + (void) _Watchdog_Remove( &api->Sporadic_timer ); + + deleted->API_Extensions[ THREAD_API_POSIX ] = NULL; + + _Workspace_Free( api ); +} + +/* + * _POSIX_Threads_Exitted_extension + * + * This method is invoked each time a thread exits. + */ +void _POSIX_Threads_Exitted_extension( + Thread_Control *executing +) +{ + /* + * If the executing thread was not created with the POSIX API, then this + * API do not get to define its exit behavior. + */ + if ( _Objects_Get_API( executing->Object.id ) == OBJECTS_POSIX_API ) + pthread_exit( executing->Wait.return_argument ); +} + +/* + * _POSIX_Threads_Initialize_user_threads + * + * This routine creates and starts all configured user + * initialzation threads. + */ +void _POSIX_Threads_Initialize_user_threads( void ) +{ + if ( _POSIX_Threads_Initialize_user_threads_p ) + (*_POSIX_Threads_Initialize_user_threads_p)(); +} + +/* + * API Extension control structures + */ +API_extensions_Control _POSIX_Threads_API_extensions = { + { NULL, NULL }, + #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) + NULL, /* predriver */ + #endif + _POSIX_Threads_Initialize_user_threads, /* postdriver */ + _POSIX_signals_Post_switch_extension, /* post switch */ +}; + +User_extensions_Control _POSIX_Threads_User_extensions = { + { NULL, NULL }, + { { NULL, NULL }, NULL }, + { _POSIX_Threads_Create_extension, /* create */ + NULL, /* start */ + NULL, /* restart */ + _POSIX_Threads_Delete_extension, /* delete */ + NULL, /* switch */ + NULL, /* begin */ + _POSIX_Threads_Exitted_extension, /* exitted */ + NULL /* fatal */ + } +}; + +/* + * _POSIX_Threads_Manager_initialization + * + * This routine initializes all threads manager related data structures. + */ +void _POSIX_Threads_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Threads_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_THREADS, /* object class */ + Configuration_POSIX_API.maximum_threads, + /* maximum objects of this class */ + sizeof( Thread_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); + + /* + * Add all the extensions for this API + */ + _User_extensions_Add_API_set( &_POSIX_Threads_User_extensions ); + + _API_extensions_Add( &_POSIX_Threads_API_extensions ); + + /* + * If we supported MP, then here we would ... + * Register the MP Process Packet routine. + */ +} diff --git a/cpukit/posix/src/pthreadatfork.c b/cpukit/posix/src/pthreadatfork.c new file mode 100644 index 0000000000..9a08abd254 --- /dev/null +++ b/cpukit/posix/src/pthreadatfork.c @@ -0,0 +1,37 @@ +/* + * pthread_atfork() - POSIX 1003.1b 3.1.3 + * + * 3.1.3 Register Fork Handlers, P1003.1c/Draft 10, P1003.1c/Draft 10, p. 27 + * + * RTEMS does not support processes, so we fall under this and do not + * provide this routine: + * + * "Either the implementation shall support the pthread_atfork() function + * as described above or the pthread_atfork() funciton shall not be + * provided." + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <rtems/seterr.h> + +int pthread_atfork( + void (*prepare)(void) __attribute__((unused)), + void (*parent)(void) __attribute__((unused)), + void (*child)(void) __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/pthreadattrdestroy.c b/cpukit/posix/src/pthreadattrdestroy.c new file mode 100644 index 0000000000..60787322e7 --- /dev/null +++ b/cpukit/posix/src/pthreadattrdestroy.c @@ -0,0 +1,32 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> + +int pthread_attr_destroy( + pthread_attr_t *attr +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + attr->is_initialized = false; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetdetachstate.c b/cpukit/posix/src/pthreadattrgetdetachstate.c new file mode 100644 index 0000000000..bd8b9a02ae --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetdetachstate.c @@ -0,0 +1,31 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getdetachstate( + const pthread_attr_t *attr, + int *detachstate +) +{ + if ( !attr || !attr->is_initialized || !detachstate ) + return EINVAL; + + *detachstate = attr->detachstate; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetguardsize.c b/cpukit/posix/src/pthreadattrgetguardsize.c new file mode 100644 index 0000000000..b3c64fbfad --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetguardsize.c @@ -0,0 +1,33 @@ +/* + * 16.1.1 Thread Creation Attributes + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_DECL_PTHREAD_ATTR_GETGUARDSIZE +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getguardsize( + const pthread_attr_t *attr, + size_t *guardsize +) +{ + if ( !attr || !attr->is_initialized || !guardsize ) + return EINVAL; + + *guardsize = attr->guardsize; + return 0; +} +#endif diff --git a/cpukit/posix/src/pthreadattrgetinheritsched.c b/cpukit/posix/src/pthreadattrgetinheritsched.c new file mode 100644 index 0000000000..e924f2d26c --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetinheritsched.c @@ -0,0 +1,31 @@ +/* + * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getinheritsched( + const pthread_attr_t *attr, + int *inheritsched +) +{ + if ( !attr || !attr->is_initialized || !inheritsched ) + return EINVAL; + + *inheritsched = attr->inheritsched; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetschedparam.c b/cpukit/posix/src/pthreadattrgetschedparam.c new file mode 100644 index 0000000000..2ec95d729e --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetschedparam.c @@ -0,0 +1,31 @@ +/* + * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getschedparam( + const pthread_attr_t *attr, + struct sched_param *param +) +{ + if ( !attr || !attr->is_initialized || !param ) + return EINVAL; + + *param = attr->schedparam; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetschedpolicy.c b/cpukit/posix/src/pthreadattrgetschedpolicy.c new file mode 100644 index 0000000000..571430e953 --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetschedpolicy.c @@ -0,0 +1,31 @@ +/* + * 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getschedpolicy( + const pthread_attr_t *attr, + int *policy +) +{ + if ( !attr || !attr->is_initialized || !policy ) + return EINVAL; + + *policy = attr->schedpolicy; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetscope.c b/cpukit/posix/src/pthreadattrgetscope.c new file mode 100644 index 0000000000..2d74dc30ba --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetscope.c @@ -0,0 +1,31 @@ +/* + * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getscope( + const pthread_attr_t *attr, + int *contentionscope +) +{ + if ( !attr || !attr->is_initialized || !contentionscope ) + return EINVAL; + + *contentionscope = attr->contentionscope; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetstack.c b/cpukit/posix/src/pthreadattrgetstack.c new file mode 100644 index 0000000000..8303099a96 --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetstack.c @@ -0,0 +1,35 @@ +/* + * 16.1.1 Thread Creation Attributes + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_DECL_PTHREAD_ATTR_GETSTACK +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getstack( + const pthread_attr_t *attr, + void **stackaddr, + size_t *stacksize +) +{ + if ( !attr || !attr->is_initialized || !stackaddr || !stacksize ) + return EINVAL; + + *stackaddr = attr->stackaddr; + *stacksize = attr->stacksize; + return 0; +} +#endif diff --git a/cpukit/posix/src/pthreadattrgetstackaddr.c b/cpukit/posix/src/pthreadattrgetstackaddr.c new file mode 100644 index 0000000000..3ca66112aa --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetstackaddr.c @@ -0,0 +1,31 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getstackaddr( + const pthread_attr_t *attr, + void **stackaddr +) +{ + if ( !attr || !attr->is_initialized || !stackaddr ) + return EINVAL; + + *stackaddr = attr->stackaddr; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrgetstacksize.c b/cpukit/posix/src/pthreadattrgetstacksize.c new file mode 100644 index 0000000000..f7f23c6dd6 --- /dev/null +++ b/cpukit/posix/src/pthreadattrgetstacksize.c @@ -0,0 +1,31 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getstacksize( + const pthread_attr_t *attr, + size_t *stacksize +) +{ + if ( !attr || !attr->is_initialized || !stacksize ) + return EINVAL; + + *stacksize = attr->stacksize; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrinit.c b/cpukit/posix/src/pthreadattrinit.c new file mode 100644 index 0000000000..1862623e3e --- /dev/null +++ b/cpukit/posix/src/pthreadattrinit.c @@ -0,0 +1,33 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_init( + pthread_attr_t *attr +) +{ + if ( !attr ) + return EINVAL; + + *attr = _POSIX_Threads_Default_attributes; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrsetdetachstate.c b/cpukit/posix/src/pthreadattrsetdetachstate.c new file mode 100644 index 0000000000..cb29f44d3a --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetdetachstate.c @@ -0,0 +1,38 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_setdetachstate( + pthread_attr_t *attr, + int detachstate +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( detachstate ) { + case PTHREAD_CREATE_DETACHED: + case PTHREAD_CREATE_JOINABLE: + attr->detachstate = detachstate; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/pthreadattrsetguardsize.c b/cpukit/posix/src/pthreadattrsetguardsize.c new file mode 100644 index 0000000000..f69ff7b173 --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetguardsize.c @@ -0,0 +1,36 @@ +/* + * 16.1.1 Thread Creation Attributes + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_DECL_PTHREAD_ATTR_SETGUARDSIZE +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_setguardsize( + pthread_attr_t *attr, + size_t guardsize +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + attr->guardsize = guardsize; + return 0; +} +#endif diff --git a/cpukit/posix/src/pthreadattrsetinheritsched.c b/cpukit/posix/src/pthreadattrsetinheritsched.c new file mode 100644 index 0000000000..0819eb48b7 --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetinheritsched.c @@ -0,0 +1,41 @@ +/* + * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_setinheritsched( + pthread_attr_t *attr, + int inheritsched +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( inheritsched ) { + case PTHREAD_INHERIT_SCHED: + case PTHREAD_EXPLICIT_SCHED: + attr->inheritsched = inheritsched; + return 0; + + default: + return ENOTSUP; + } +} diff --git a/cpukit/posix/src/pthreadattrsetschedparam.c b/cpukit/posix/src/pthreadattrsetschedparam.c new file mode 100644 index 0000000000..cb310a9893 --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetschedparam.c @@ -0,0 +1,31 @@ +/* + * 13.5.1 Thread Creation Scheduling Parameters, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_setschedparam( + pthread_attr_t *attr, + const struct sched_param *param +) +{ + if ( !attr || !attr->is_initialized || !param ) + return EINVAL; + + attr->schedparam = *param; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrsetschedpolicy.c b/cpukit/posix/src/pthreadattrsetschedpolicy.c new file mode 100644 index 0000000000..ab61e000ed --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetschedpolicy.c @@ -0,0 +1,43 @@ +/* + * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_setschedpolicy( + pthread_attr_t *attr, + int policy +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( policy ) { + case SCHED_OTHER: + case SCHED_FIFO: + case SCHED_RR: + case SCHED_SPORADIC: + attr->schedpolicy = policy; + return 0; + + default: + return ENOTSUP; + } +} diff --git a/cpukit/posix/src/pthreadattrsetscope.c b/cpukit/posix/src/pthreadattrsetscope.c new file mode 100644 index 0000000000..8c6d1c3f9c --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetscope.c @@ -0,0 +1,43 @@ +/* + * 13.5.1 Thread Creation Scheduling Attributes, P1003.1c/Draft 10, p. 120 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_setscope( + pthread_attr_t *attr, + int contentionscope +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( contentionscope ) { + case PTHREAD_SCOPE_PROCESS: + attr->contentionscope = contentionscope; + return 0; + + case PTHREAD_SCOPE_SYSTEM: + return ENOTSUP; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/pthreadattrsetstack.c b/cpukit/posix/src/pthreadattrsetstack.c new file mode 100644 index 0000000000..f97d3ac885 --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetstack.c @@ -0,0 +1,42 @@ +/* + * 16.1.1 Thread Creation Attributes + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#if HAVE_DECL_PTHREAD_ATTR_SETSTACK +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_setstack( + pthread_attr_t *attr, + void *stackaddr, + size_t stacksize +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + if (stacksize < PTHREAD_MINIMUM_STACK_SIZE) + attr->stacksize = PTHREAD_MINIMUM_STACK_SIZE; + else + attr->stacksize = stacksize; + + attr->stackaddr = stackaddr; + return 0; +} +#endif diff --git a/cpukit/posix/src/pthreadattrsetstackaddr.c b/cpukit/posix/src/pthreadattrsetstackaddr.c new file mode 100644 index 0000000000..b7ed212546 --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetstackaddr.c @@ -0,0 +1,31 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_setstackaddr( + pthread_attr_t *attr, + void *stackaddr +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + attr->stackaddr = stackaddr; + return 0; +} diff --git a/cpukit/posix/src/pthreadattrsetstacksize.c b/cpukit/posix/src/pthreadattrsetstacksize.c new file mode 100644 index 0000000000..9598a8a7d7 --- /dev/null +++ b/cpukit/posix/src/pthreadattrsetstacksize.c @@ -0,0 +1,37 @@ +/* + * 16.1.1 Thread Creation Attributes, P1003.1c/Draft 10, p, 140 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> + +int pthread_attr_setstacksize( + pthread_attr_t *attr, + size_t stacksize +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + if (stacksize < PTHREAD_MINIMUM_STACK_SIZE) + attr->stacksize = PTHREAD_MINIMUM_STACK_SIZE; + else + attr->stacksize = stacksize; + return 0; +} diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c new file mode 100644 index 0000000000..d7f08a5527 --- /dev/null +++ b/cpukit/posix/src/pthreadcreate.c @@ -0,0 +1,232 @@ +/* + * 16.1.2 Thread Creation, P1003.1c/Draft 10, p. 144 + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> +#include <rtems/score/apimutex.h> + +static inline size_t _POSIX_Threads_Ensure_minimum_stack ( + size_t size +) +{ + if ( size >= PTHREAD_MINIMUM_STACK_SIZE ) + return size; + return PTHREAD_MINIMUM_STACK_SIZE; +} + + +int pthread_create( + pthread_t *thread, + const pthread_attr_t *attr, + void *(*start_routine)( void * ), + void *arg +) +{ + const pthread_attr_t *the_attr; + Priority_Control core_priority; + Thread_CPU_budget_algorithms budget_algorithm; + Thread_CPU_budget_algorithm_callout budget_callout; + bool is_fp; + bool status; + Thread_Control *the_thread; + POSIX_API_Control *api; + int schedpolicy = SCHED_RR; + struct sched_param schedparam; + Objects_Name name; + int rc; + + if ( !start_routine ) + return EFAULT; + + the_attr = (attr) ? attr : &_POSIX_Threads_Default_attributes; + + if ( !the_attr->is_initialized ) + return EINVAL; + + /* + * Core Thread Initialize ensures we get the minimum amount of + * stack space if it is allowed to allocate it itself. + * + * NOTE: If the user provides the stack we will let it drop below + * twice the minimum. + */ + if ( the_attr->stackaddr && !_Stack_Is_enough(the_attr->stacksize) ) + return EINVAL; + + #if 0 + int cputime_clock_allowed; /* see time.h */ + rtems_set_errno_and_return_minus_one( ENOSYS ); + #endif + + /* + * P1003.1c/Draft 10, p. 121. + * + * If inheritsched is set to PTHREAD_INHERIT_SCHED, then this thread + * inherits scheduling attributes from the creating thread. If it is + * PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the + * attributes structure. + */ + switch ( the_attr->inheritsched ) { + case PTHREAD_INHERIT_SCHED: + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + schedpolicy = api->schedpolicy; + schedparam = api->schedparam; + break; + + case PTHREAD_EXPLICIT_SCHED: + schedpolicy = the_attr->schedpolicy; + schedparam = the_attr->schedparam; + break; + + default: + return EINVAL; + } + + /* + * Check the contentionscope since rtems only supports PROCESS wide + * contention (i.e. no system wide contention). + */ + if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS ) + return ENOTSUP; + + /* + * Interpret the scheduling parameters. + */ + if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) ) + return EINVAL; + + core_priority = _POSIX_Priority_To_core( schedparam.sched_priority ); + + /* + * Set the core scheduling policy information. + */ + rc = _POSIX_Thread_Translate_sched_param( + schedpolicy, + &schedparam, + &budget_algorithm, + &budget_callout + ); + if ( rc ) + return rc; + + /* + * Currently all POSIX threads are floating point if the hardware + * supports it. + */ + #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) + is_fp = true; + #else + is_fp = false; + #endif + + /* + * Lock the allocator mutex for protection + */ + _RTEMS_Lock_allocator(); + + /* + * Allocate the thread control block. + * + * NOTE: Global threads are not currently supported. + */ + the_thread = _POSIX_Threads_Allocate(); + if ( !the_thread ) { + _RTEMS_Unlock_allocator(); + return EAGAIN; + } + + /* + * Initialize the core thread for this task. + */ + name.name_p = NULL; /* posix threads don't have a name by default */ + status = _Thread_Initialize( + &_POSIX_Threads_Information, + the_thread, + the_attr->stackaddr, + _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize), + is_fp, + core_priority, + true, /* preemptible */ + budget_algorithm, + budget_callout, + 0, /* isr level */ + name /* posix threads don't have a name */ + ); + + if ( !status ) { + _POSIX_Threads_Free( the_thread ); + _RTEMS_Unlock_allocator(); + return EAGAIN; + } + + /* + * finish initializing the per API structure + */ + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + api->Attributes = *the_attr; + api->detachstate = the_attr->detachstate; + api->schedpolicy = schedpolicy; + api->schedparam = schedparam; + + /* + * POSIX threads are allocated and started in one operation. + */ + status = _Thread_Start( + the_thread, + THREAD_START_POINTER, + start_routine, + arg, + 0 /* unused */ + ); + + #if defined(RTEMS_DEBUG) + /* + * _Thread_Start only fails if the thread was in the incorrect state + * + * NOTE: This can only happen if someone slips in and touches the + * thread while we are creating it. + */ + if ( !status ) { + _POSIX_Threads_Free( the_thread ); + _RTEMS_Unlock_allocator(); + return EINVAL; + } + #endif + + if ( schedpolicy == SCHED_SPORADIC ) { + _Watchdog_Insert_ticks( + &api->Sporadic_timer, + _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period ) + ); + } + + /* + * Return the id and indicate we successfully created the thread + */ + *thread = the_thread->Object.id; + + _RTEMS_Unlock_allocator(); + return 0; +} diff --git a/cpukit/posix/src/pthreaddetach.c b/cpukit/posix/src/pthreaddetach.c new file mode 100644 index 0000000000..6078fcc97e --- /dev/null +++ b/cpukit/posix/src/pthreaddetach.c @@ -0,0 +1,51 @@ +/* + * 16.1.4 Detaching a Thread, P1003.1c/Draft 10, p. 149 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/posix/pthread.h> + +int pthread_detach( + pthread_t thread +) +{ + register Thread_Control *the_thread; + POSIX_API_Control *api; + Objects_Locations location; + + the_thread = _Thread_Get( thread, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + api->detachstate = PTHREAD_CREATE_DETACHED; + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return ESRCH; +} diff --git a/cpukit/posix/src/pthreadequal.c b/cpukit/posix/src/pthreadequal.c new file mode 100644 index 0000000000..9944026f3e --- /dev/null +++ b/cpukit/posix/src/pthreadequal.c @@ -0,0 +1,93 @@ +/* + * 16.1.7 Compare Thread IDs, p1003.1c/Draft 10, p. 153 + * + * NOTE: POSIX does not define the behavior when either thread id is invalid. + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/score/thread.h> + +int pthread_equal( + pthread_t t1, + pthread_t t2 +) +{ + /* + * If the system is configured for debug, then we will do everything we + * can to insure that both ids are valid. Otherwise, we will do the + * cheapest possible thing to determine if they are equal. + */ + +#ifndef RTEMS_DEBUG + return _Objects_Are_ids_equal( t1, t2 ); +#else + int status; + Objects_Locations location; + + /* + * By default this is not a match. + */ + + status = 0; + + /* + * Validate the first id and return 0 if it is not valid + */ + + (void) _Thread_Get( t1, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + /* + * Validate the second id and return 0 if it is not valid + */ + + (void) _Thread_Get( t2, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + status = _Objects_Are_ids_equal( t1, t2 ); + _Thread_Unnest_dispatch(); + _Thread_Enable_dispatch(); + break; + + case OBJECTS_ERROR: +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + /* t1 must have been valid so exit the critical section */ + _Thread_Enable_dispatch(); + /* return status == 0 */ + break; + } + break; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + /* return status == 0 */ + break; + } + + return status; +#endif +} diff --git a/cpukit/posix/src/pthreadexit.c b/cpukit/posix/src/pthreadexit.c new file mode 100644 index 0000000000..9efe9d9a47 --- /dev/null +++ b/cpukit/posix/src/pthreadexit.c @@ -0,0 +1,67 @@ +/* + * 16.1.5.1 Thread Termination, p1003.1c/Draft 10, p. 150 + * + * NOTE: Key destructors are executed in the POSIX api delete extension. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/apimutex.h> +#include <rtems/score/thread.h> +#include <rtems/posix/pthread.h> + +void _POSIX_Thread_Exit( + Thread_Control *the_thread, + void *value_ptr +) +{ + Objects_Information *the_information; + + the_information = _Objects_Get_information_id( the_thread->Object.id ); + + /* + * The_information has to be non-NULL. Otherwise, we couldn't be + * running in a thread of this API and class. + * + * NOTE: Lock and unlock in different order so we do not throw a + * fatal error when locking the allocator mutex. And after + * we unlock, we want to defer the context switch until we + * are ready to be switched out. Otherwise, an ISR could + * occur and preempt us out while we still hold the + * allocator mutex. + */ + + _RTEMS_Lock_allocator(); + _Thread_Disable_dispatch(); + + the_thread->Wait.return_argument = value_ptr; + + _Thread_Close( the_information, the_thread ); + + _POSIX_Threads_Free( the_thread ); + + _RTEMS_Unlock_allocator(); + _Thread_Enable_dispatch(); +} + +void pthread_exit( + void *value_ptr +) +{ + _POSIX_Thread_Exit( _Thread_Executing, value_ptr ); +} diff --git a/cpukit/posix/src/pthreadgetcpuclockid.c b/cpukit/posix/src/pthreadgetcpuclockid.c new file mode 100644 index 0000000000..2ba0dcc3e0 --- /dev/null +++ b/cpukit/posix/src/pthreadgetcpuclockid.c @@ -0,0 +1,30 @@ +/* + * 20.1.6 Accessing a Thread CPU-time Clock, P1003.4b/Draft 8, p. 58 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> + +int pthread_getcpuclockid( + pthread_t pid, + clockid_t *clock_id +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/pthreadgetcputime.c b/cpukit/posix/src/pthreadgetcputime.c new file mode 100644 index 0000000000..7c9bb46c7b --- /dev/null +++ b/cpukit/posix/src/pthreadgetcputime.c @@ -0,0 +1,31 @@ +/* + * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_getcputime( + pthread_attr_t *attr, + int *clock_allowed +) +{ + if ( !attr || !attr->is_initialized || !clock_allowed ) + return EINVAL; + + *clock_allowed = attr->cputime_clock_allowed; + return 0; +} diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c new file mode 100644 index 0000000000..b8e0a83153 --- /dev/null +++ b/cpukit/posix/src/pthreadgetschedparam.c @@ -0,0 +1,63 @@ +/* + * 13.5.2 Dynamic Thread Scheduling Parameters Access, + * P1003.1c/Draft 10, p. 124 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> + +int pthread_getschedparam( + pthread_t thread, + int *policy, + struct sched_param *param +) +{ + Objects_Locations location; + POSIX_API_Control *api; + register Thread_Control *the_thread; + + if ( !policy || !param ) + return EINVAL; + + the_thread = _Thread_Get( thread, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + if ( policy ) + *policy = api->schedpolicy; + if ( param ) { + *param = api->schedparam; + param->sched_priority = + _POSIX_Priority_From_core( the_thread->current_priority ); + } + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return ESRCH; + +} diff --git a/cpukit/posix/src/pthreadinitthreads.c b/cpukit/posix/src/pthreadinitthreads.c new file mode 100644 index 0000000000..b7c0fdec3b --- /dev/null +++ b/cpukit/posix/src/pthreadinitthreads.c @@ -0,0 +1,87 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> +#include <pthread.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/apiext.h> +#include <rtems/score/stack.h> +#include <rtems/score/thread.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/config.h> +#include <rtems/posix/key.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * _POSIX_Threads_Initialize_user_threads_body + * + * This routine creates and starts all configured user + * initialzation threads. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _POSIX_Threads_Initialize_user_threads_body(void) +{ + int status; + uint32_t index; + uint32_t maximum; + posix_initialization_threads_table *user_threads; + pthread_t thread_id; + pthread_attr_t attr; + + user_threads = Configuration_POSIX_API.User_initialization_threads_table; + maximum = Configuration_POSIX_API.number_of_initialization_threads; + + if ( !user_threads || maximum == 0 ) + return; + + /* + * Be careful .. if the default attribute set changes, this may need to. + * + * Setting the attributes explicitly is critical, since we don't want + * to inherit the idle tasks attributes. + */ + + for ( index=0 ; index < maximum ; index++ ) { + /* + * There is no way for these calls to fail in this situation. + */ + (void) pthread_attr_init( &attr ); + (void) pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); + (void) pthread_attr_setstacksize(&attr, user_threads[ index ].stack_size); + + status = pthread_create( + &thread_id, + &attr, + user_threads[ index ].thread_entry, + NULL + ); + if ( status ) + _Internal_error_Occurred( INTERNAL_ERROR_POSIX_API, true, status ); + } +} + diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c new file mode 100644 index 0000000000..8ee9888b94 --- /dev/null +++ b/cpukit/posix/src/pthreadjoin.c @@ -0,0 +1,75 @@ +/* + * 16.1.3 Wait for Thread Termination, P1003.1c/Draft 10, p. 147 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> +#include <rtems/posix/pthread.h> + +int pthread_join( + pthread_t thread, + void **value_ptr +) +{ + register Thread_Control *the_thread; + POSIX_API_Control *api; + Objects_Locations location; + void *return_pointer; + + the_thread = _Thread_Get( thread, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( api->detachstate == PTHREAD_CREATE_DETACHED ) { + _Thread_Enable_dispatch(); + return EINVAL; + } + + if ( _Thread_Is_executing( the_thread ) ) { + _Thread_Enable_dispatch(); + return EDEADLK; + } + + /* + * Put ourself on the threads join list + */ + + _Thread_Executing->Wait.return_argument = &return_pointer; + + _Thread_queue_Enter_critical_section( &api->Join_List ); + + _Thread_queue_Enqueue( &api->Join_List, WATCHDOG_NO_TIMEOUT ); + + _Thread_Enable_dispatch(); + + if ( value_ptr ) + *value_ptr = return_pointer; + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return ESRCH; +} diff --git a/cpukit/posix/src/pthreadkill.c b/cpukit/posix/src/pthreadkill.c new file mode 100644 index 0000000000..777ee6ad0c --- /dev/null +++ b/cpukit/posix/src/pthreadkill.c @@ -0,0 +1,80 @@ +/* + * 3.3.10 Send a Signal to a Thread, P1003.1c/D10, p. 43 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/score/isr.h> +#include <rtems/seterr.h> + +int pthread_kill( + pthread_t thread, + int sig +) +{ + POSIX_API_Control *api; + Thread_Control *the_thread; + Objects_Locations location; + + if ( !sig ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !is_valid_signo(sig) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + the_thread = _Thread_Get( thread, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + /* + * If sig == 0 then just validate arguments + */ + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( sig ) { + + if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) { + _Thread_Enable_dispatch(); + return 0; + } + + /* XXX critical section */ + + api->signals_pending |= signo_to_mask( sig ); + + (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL ); + + if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) ) + _Thread_Dispatch_necessary = true; + } + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( ESRCH ); +} diff --git a/cpukit/posix/src/pthreadonce.c b/cpukit/posix/src/pthreadonce.c new file mode 100644 index 0000000000..8e4a9dc6d8 --- /dev/null +++ b/cpukit/posix/src/pthreadonce.c @@ -0,0 +1,44 @@ +/* + * 16.1.8 Dynamic Package Initialization, P1003.1c/Draft 10, p. 154 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/system.h> +#include <rtems/score/thread.h> + +int pthread_once( + pthread_once_t *once_control, + void (*init_routine)(void) +) +{ + if ( !once_control || !init_routine ) + return EINVAL; + + if ( !once_control->init_executed ) { + rtems_mode saveMode; + rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode); + if ( !once_control->init_executed ) { + once_control->is_initialized = true; + once_control->init_executed = true; + (*init_routine)(); + } + rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode); + } + return 0; +} diff --git a/cpukit/posix/src/pthreadself.c b/cpukit/posix/src/pthreadself.c new file mode 100644 index 0000000000..c1baf85177 --- /dev/null +++ b/cpukit/posix/src/pthreadself.c @@ -0,0 +1,27 @@ +/* + * 16.1.6 Get Calling Thread's ID, p1003.1c/Draft 10, p. 152 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/thread.h> + +pthread_t pthread_self( void ) +{ + return _Thread_Executing->Object.id; +} diff --git a/cpukit/posix/src/pthreadsetcputime.c b/cpukit/posix/src/pthreadsetcputime.c new file mode 100644 index 0000000000..70b9594ab9 --- /dev/null +++ b/cpukit/posix/src/pthreadsetcputime.c @@ -0,0 +1,38 @@ +/* + * 20.1.7 CPU-time Clock Thread Creation Attribute, P1003.4b/Draft 8, p. 59 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +int pthread_attr_setcputime( + pthread_attr_t *attr, + int clock_allowed +) +{ + if ( !attr || !attr->is_initialized ) + return EINVAL; + + switch ( clock_allowed ) { + case CLOCK_ENABLED: + case CLOCK_DISABLED: + attr->cputime_clock_allowed = clock_allowed; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c new file mode 100644 index 0000000000..14edfa0218 --- /dev/null +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -0,0 +1,107 @@ +/* + * 13.5.2 Dynamic Thread Scheduling Parameters Access, + * P1003.1c/Draft 10, p. 124 + */ + +/* COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int pthread_setschedparam( + pthread_t thread, + int policy, + struct sched_param *param +) +{ + register Thread_Control *the_thread; + POSIX_API_Control *api; + Thread_CPU_budget_algorithms budget_algorithm; + Thread_CPU_budget_algorithm_callout budget_callout; + Objects_Locations location; + int rc; + + /* + * Check all the parameters + */ + if ( !param ) + return EINVAL; + + rc = _POSIX_Thread_Translate_sched_param( + policy, + param, + &budget_algorithm, + &budget_callout + ); + if ( rc ) + return rc; + + /* + * Actually change the scheduling policy and parameters + */ + the_thread = _Thread_Get( thread, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + if ( api->schedpolicy == SCHED_SPORADIC ) + (void) _Watchdog_Remove( &api->Sporadic_timer ); + + api->schedpolicy = policy; + api->schedparam = *param; + the_thread->budget_algorithm = budget_algorithm; + the_thread->budget_callout = budget_callout; + + switch ( api->schedpolicy ) { + case SCHED_OTHER: + case SCHED_FIFO: + case SCHED_RR: + the_thread->cpu_time_budget = _Thread_Ticks_per_timeslice; + + the_thread->real_priority = + _POSIX_Priority_To_core( api->schedparam.sched_priority ); + + _Thread_Change_priority( + the_thread, + the_thread->real_priority, + true + ); + break; + + case SCHED_SPORADIC: + api->ss_high_priority = api->schedparam.sched_priority; + _Watchdog_Remove( &api->Sporadic_timer ); + _POSIX_Threads_Sporadic_budget_TSR( 0, the_thread ); + break; + } + + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + return ESRCH; +} diff --git a/cpukit/posix/src/pthreadsigmask.c b/cpukit/posix/src/pthreadsigmask.c new file mode 100644 index 0000000000..c97e75a89e --- /dev/null +++ b/cpukit/posix/src/pthreadsigmask.c @@ -0,0 +1,72 @@ +/* + * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 + * + * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/seterr.h> + +int pthread_sigmask( + int how, + const sigset_t *set, + sigset_t *oset +) +{ + POSIX_API_Control *api; + + if ( !set && !oset ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + if ( oset ) + *oset = api->signals_blocked; + + if ( !set ) + return 0; + + switch ( how ) { + case SIG_BLOCK: + api->signals_blocked |= *set; + break; + case SIG_UNBLOCK: + api->signals_blocked &= ~*set; + break; + case SIG_SETMASK: + api->signals_blocked = *set; + break; + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* XXX are there critical section problems here? */ + + /* XXX evaluate the new set */ + + if ( ~api->signals_blocked & + (api->signals_pending | _POSIX_signals_Pending) ) { + _Thread_Dispatch(); + } + + return 0; +} diff --git a/cpukit/posix/src/ptimer.c b/cpukit/posix/src/ptimer.c new file mode 100644 index 0000000000..6ded55c0a6 --- /dev/null +++ b/cpukit/posix/src/ptimer.c @@ -0,0 +1,72 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> +#include <limits.h> /* _POSIX_PATH_MAX */ + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> + +#include <rtems/posix/time.h> + +/************************************/ +/* These includes are now necessary */ +/************************************/ + +#include <unistd.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/rtems/timer.h> +#include <rtems/rtems/clock.h> +#include <rtems/posix/psignal.h> +#include <rtems/score/wkspace.h> +#include <pthread.h> +#include <stdio.h> +#include <signal.h> + +#include <rtems/posix/timer.h> + +/* + * _POSIX_Timer_Manager_initialization + * + * Description: + * + * Initialize the internal structure in which the data of all + * the timers are stored + */ + +void _POSIX_Timer_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Timer_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_TIMERS, /* object class */ + Configuration_POSIX_API.maximum_timers, + /* maximum objects of this class */ + sizeof( POSIX_Timer_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/rwlockattrdestroy.c b/cpukit/posix/src/rwlockattrdestroy.c new file mode 100644 index 0000000000..aa4b6e3345 --- /dev/null +++ b/cpukit/posix/src/rwlockattrdestroy.c @@ -0,0 +1,41 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/score/states.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/time.h> +#include <rtems/posix/mutex.h> + +/*PAGE + * + * RWLock Initialization Attributes + */ + +int pthread_rwlockattr_destroy( + pthread_rwlockattr_t *attr +) +{ + if ( !attr || attr->is_initialized == false ) + return EINVAL; + + attr->is_initialized = false; + return 0; +} diff --git a/cpukit/posix/src/rwlockattrgetpshared.c b/cpukit/posix/src/rwlockattrgetpshared.c new file mode 100644 index 0000000000..b0536df1b0 --- /dev/null +++ b/cpukit/posix/src/rwlockattrgetpshared.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +/*PAGE + * + * RWLock Attributes Get Process Shared + */ + +int pthread_rwlockattr_getpshared( + const pthread_rwlockattr_t *attr, + int *pshared +) +{ + if ( !attr ) + return EINVAL; + + if ( !attr->is_initialized ) + return EINVAL; + + *pshared = attr->process_shared; + return 0; +} diff --git a/cpukit/posix/src/rwlockattrinit.c b/cpukit/posix/src/rwlockattrinit.c new file mode 100644 index 0000000000..77f5992038 --- /dev/null +++ b/cpukit/posix/src/rwlockattrinit.c @@ -0,0 +1,36 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> + +/*PAGE + * + * RWLock Attributes Initialization + */ + +int pthread_rwlockattr_init( + pthread_rwlockattr_t *attr +) +{ + if ( !attr ) + return EINVAL; + + attr->is_initialized = true; + attr->process_shared = PTHREAD_PROCESS_PRIVATE; + return 0; +} diff --git a/cpukit/posix/src/rwlockattrsetpshared.c b/cpukit/posix/src/rwlockattrsetpshared.c new file mode 100644 index 0000000000..92fc38fa9e --- /dev/null +++ b/cpukit/posix/src/rwlockattrsetpshared.c @@ -0,0 +1,44 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +/*PAGE + * + * RWLock Attributes Set Process Shared + */ + +int pthread_rwlockattr_setpshared( + pthread_rwlockattr_t *attr, + int pshared +) +{ + if ( !attr ) + return EINVAL; + + if ( !attr->is_initialized ) + return EINVAL; + + switch ( pshared ) { + case PTHREAD_PROCESS_SHARED: + case PTHREAD_PROCESS_PRIVATE: + attr->process_shared = pshared; + return 0; + + default: + return EINVAL; + } +} diff --git a/cpukit/posix/src/sched_getparam.c b/cpukit/posix/src/sched_getparam.c new file mode 100644 index 0000000000..c25286bdc3 --- /dev/null +++ b/cpukit/posix/src/sched_getparam.c @@ -0,0 +1,30 @@ +/* + * 13.3.2 Set Scheduling Parameters, P1003.1b-1993, p. 253 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> + +int sched_getparam( + pid_t pid __attribute__((unused)), + struct sched_param *param __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/sched_getprioritymax.c b/cpukit/posix/src/sched_getprioritymax.c new file mode 100644 index 0000000000..9f8965e4d5 --- /dev/null +++ b/cpukit/posix/src/sched_getprioritymax.c @@ -0,0 +1,41 @@ +/* + * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/posix/priority.h> + +int sched_get_priority_max( + int policy +) +{ + switch ( policy ) { + case SCHED_OTHER: + case SCHED_FIFO: + case SCHED_RR: + case SCHED_SPORADIC: + break; + + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + return POSIX_SCHEDULER_MAXIMUM_PRIORITY; +} diff --git a/cpukit/posix/src/sched_getprioritymin.c b/cpukit/posix/src/sched_getprioritymin.c new file mode 100644 index 0000000000..88e1170f12 --- /dev/null +++ b/cpukit/posix/src/sched_getprioritymin.c @@ -0,0 +1,41 @@ +/* + * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/posix/priority.h> + +int sched_get_priority_min( + int policy +) +{ + switch ( policy ) { + case SCHED_OTHER: + case SCHED_FIFO: + case SCHED_RR: + case SCHED_SPORADIC: + break; + + default: + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + return POSIX_SCHEDULER_MINIMUM_PRIORITY; +} diff --git a/cpukit/posix/src/sched_getscheduler.c b/cpukit/posix/src/sched_getscheduler.c new file mode 100644 index 0000000000..8afbcfd486 --- /dev/null +++ b/cpukit/posix/src/sched_getscheduler.c @@ -0,0 +1,33 @@ +/* + * 13.3.4 Get Scheduling Policy, P1003.1b-1993, p. 256 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/tod.h> +#include <rtems/score/thread.h> +#include <rtems/seterr.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int sched_getscheduler( + pid_t pid __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/sched_rr_get_interval.c b/cpukit/posix/src/sched_rr_get_interval.c new file mode 100644 index 0000000000..c9e3e280ca --- /dev/null +++ b/cpukit/posix/src/sched_rr_get_interval.c @@ -0,0 +1,45 @@ +/* + * 13.3.6 Get Scheduling Parameter Limits, P1003.1b-1993, p. 258 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> /* getpid */ +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/tod.h> +#include <rtems/score/thread.h> +#include <rtems/score/timespec.h> +#include <rtems/seterr.h> + +int sched_rr_get_interval( + pid_t pid, + struct timespec *interval +) +{ + /* + * Only supported for the "calling process" (i.e. this node). + */ + + if ( pid && pid != getpid() ) + rtems_set_errno_and_return_minus_one( ESRCH ); + + if ( !interval ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + _Timespec_From_ticks( _Thread_Ticks_per_timeslice, interval ); + return 0; +} diff --git a/cpukit/posix/src/sched_setparam.c b/cpukit/posix/src/sched_setparam.c new file mode 100644 index 0000000000..155ed2d11b --- /dev/null +++ b/cpukit/posix/src/sched_setparam.c @@ -0,0 +1,34 @@ +/* + * 13.3.1 Set Scheduling Parameters, P1003.1b-1993, p. 252 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/tod.h> +#include <rtems/score/thread.h> +#include <rtems/seterr.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int sched_setparam( + pid_t pid __attribute__((unused)), + const struct sched_param *param __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/sched_setscheduler.c b/cpukit/posix/src/sched_setscheduler.c new file mode 100644 index 0000000000..f0bb5496fa --- /dev/null +++ b/cpukit/posix/src/sched_setscheduler.c @@ -0,0 +1,36 @@ +/* + * 13.3.3 Set Scheduling Policy and Scheduling Parameters, + * P1003.1b-1993, p. 254 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/tod.h> +#include <rtems/score/thread.h> +#include <rtems/seterr.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int sched_setscheduler( + pid_t pid __attribute__((unused)), + int policy __attribute__((unused)), + const struct sched_param *param __attribute__((unused)) +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/sched_yield.c b/cpukit/posix/src/sched_yield.c new file mode 100644 index 0000000000..b6c5c4fce4 --- /dev/null +++ b/cpukit/posix/src/sched_yield.c @@ -0,0 +1,35 @@ +/* + * 13.3.5 Yield Processor, P1003.1b-1993, p. 257 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sched.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/tod.h> +#include <rtems/score/thread.h> +#include <rtems/seterr.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int sched_yield( void ) +{ + _Thread_Disable_dispatch(); + _Scheduler_Yield(); + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/semaphore.c b/cpukit/posix/src/semaphore.c new file mode 100644 index 0000000000..e84bea87a4 --- /dev/null +++ b/cpukit/posix/src/semaphore.c @@ -0,0 +1,60 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * _POSIX_Semaphore_Manager_initialization + * + * This routine initializes all semaphore manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _POSIX_Semaphore_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_POSIX_Semaphore_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_SEMAPHORES, /* object class */ + Configuration_POSIX_API.maximum_semaphores, + /* maximum objects of this class */ + sizeof( POSIX_Semaphore_Control ), + /* size of this object's control block */ + true, /* true if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c new file mode 100644 index 0000000000..42e530bf07 --- /dev/null +++ b/cpukit/posix/src/semaphorecreatesupp.c @@ -0,0 +1,113 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> +#include <string.h> /* strlen */ + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/* pure ANSI mode does not have this prototype */ +size_t strnlen(const char *, size_t); + +/* + * _POSIX_Semaphore_Create_support + * + * This routine does the actual creation and initialization of + * a poxix semaphore. It is a support routine for sem_init and + * sem_open. + */ +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; + char *name_p = (char *)name; + + /* Sharing semaphores among processes is not currently supported */ + if (pshared != 0) + rtems_set_errno_and_return_minus_one( ENOSYS ); + + if ( name ) { + if ( strnlen( name, NAME_MAX ) >= NAME_MAX ) + rtems_set_errno_and_return_minus_one( ENAMETOOLONG ); + } + + _Thread_Disable_dispatch(); + + the_semaphore = _POSIX_Semaphore_Allocate(); + + if ( !the_semaphore ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( ENOSPC ); + } + + 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_semaphore->open_count = 0; + the_semaphore->linked = false; + } + + the_sem_attr = &the_semaphore->Semaphore.Attributes; + + /* + * POSIX does not appear to specify what the discipline for + * blocking tasks on this semaphore should be. It could somehow + * be derived from the current scheduling policy. One + * thing is certain, no matter what we decide, it won't be + * the same as all other POSIX implementations. :) + */ + the_sem_attr->discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO; + + /* + * This effectively disables limit checking. + */ + the_sem_attr->maximum_count = 0xFFFFFFFF; + + _CORE_semaphore_Initialize( &the_semaphore->Semaphore, the_sem_attr, value ); + + /* + * Make the semaphore available for use. + */ + _Objects_Open_string( + &_POSIX_Semaphore_Information, + &the_semaphore->Object, + name_p + ); + + *the_sem = the_semaphore; + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c new file mode 100644 index 0000000000..b9b8408c76 --- /dev/null +++ b/cpukit/posix/src/semaphoredeletesupp.c @@ -0,0 +1,50 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * _POSIX_Semaphore_Delete + */ + +void _POSIX_Semaphore_Delete( + POSIX_Semaphore_Control *the_semaphore +) +{ + if ( !the_semaphore->linked && !the_semaphore->open_count ) { + _Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object ); + + _CORE_semaphore_Flush( + &the_semaphore->Semaphore, + NULL, + -1 + ); + + _POSIX_Semaphore_Free( the_semaphore ); + } +} diff --git a/cpukit/posix/src/semaphorenametoid.c b/cpukit/posix/src/semaphorenametoid.c new file mode 100644 index 0000000000..e550910653 --- /dev/null +++ b/cpukit/posix/src/semaphorenametoid.c @@ -0,0 +1,63 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * _POSIX_Semaphore_Name_to_id + * + * Look up the specified name and attempt to locate the id + * for the associated semaphore. + */ + +int _POSIX_Semaphore_Name_to_id( + const char *name, + sem_t *id +) +{ + Objects_Name_or_id_lookup_errors status; + Objects_Id the_id; + + if ( !name ) + return EINVAL; + + if ( !name[0] ) + return EINVAL; + + status = _Objects_Name_to_id_string( + &_POSIX_Semaphore_Information, + name, + &the_id + ); + *id = the_id; + + if ( status == OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL ) + return 0; + + return ENOENT; +} diff --git a/cpukit/posix/src/semaphoretranslatereturncode.c b/cpukit/posix/src/semaphoretranslatereturncode.c new file mode 100644 index 0000000000..c87f5c93c8 --- /dev/null +++ b/cpukit/posix/src/semaphoretranslatereturncode.c @@ -0,0 +1,59 @@ +/* + * POSIX Semaphore Error Translation + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/coresem.h> + +/* + * _POSIX_Semaphore_Translate_core_semaphore_return_code + * + * Input parameters: + * the_semaphore_status - semaphore status code to translate + * + * Output parameters: + * status code - translated POSIX status code + * + */ + +static int _POSIX_Semaphore_Return_codes[CORE_SEMAPHORE_STATUS_LAST + 1] = { + 0, /* CORE_SEMAPHORE_STATUS_SUCCESSFUL */ + EAGAIN, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ + EAGAIN, /* CORE_SEMAPHORE_WAS_DELETED */ + ETIMEDOUT, /* CORE_SEMAPHORE_TIMEOUT */ + /* The next error can not occur since we set the maximum + * count to the largest value the count can hold. + */ + ENOSYS, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ +}; + + +int _POSIX_Semaphore_Translate_core_semaphore_return_code( + CORE_semaphore_Status the_semaphore_status +) +{ + /* + * Internal consistency check for bad status from SuperCore + */ + #if defined(RTEMS_DEBUG) + if ( the_semaphore_status > CORE_SEMAPHORE_STATUS_LAST ) + return EINVAL; + #endif + return _POSIX_Semaphore_Return_codes[the_semaphore_status]; +} diff --git a/cpukit/posix/src/semaphorewaitsupp.c b/cpukit/posix/src/semaphorewaitsupp.c new file mode 100644 index 0000000000..76e7edc4bc --- /dev/null +++ b/cpukit/posix/src/semaphorewaitsupp.c @@ -0,0 +1,73 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * _POSIX_Semaphore_Wait_support + */ + +int _POSIX_Semaphore_Wait_support( + sem_t *sem, + bool blocking, + Watchdog_Interval timeout +) +{ + POSIX_Semaphore_Control *the_semaphore; + Objects_Locations location; + + the_semaphore = _POSIX_Semaphore_Get( sem, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _CORE_semaphore_Seize( + &the_semaphore->Semaphore, + the_semaphore->Object.id, + blocking, + timeout + ); + _Thread_Enable_dispatch(); + + if ( !_Thread_Executing->Wait.return_code ) + return 0; + + rtems_set_errno_and_return_minus_one( + _POSIX_Semaphore_Translate_core_semaphore_return_code( + _Thread_Executing->Wait.return_code + ) + ); + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/semclose.c b/cpukit/posix/src/semclose.c new file mode 100644 index 0000000000..c265c867d5 --- /dev/null +++ b/cpukit/posix/src/semclose.c @@ -0,0 +1,64 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + + +/*PAGE + * + * sem_close + * + * Routine to close a semaphore that has been opened or initialized. + * + * 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_LOCAL: + the_semaphore->open_count -= 1; + _POSIX_Semaphore_Delete( the_semaphore ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/semdestroy.c b/cpukit/posix/src/semdestroy.c new file mode 100644 index 0000000000..8a3b20c23f --- /dev/null +++ b/cpukit/posix/src/semdestroy.c @@ -0,0 +1,67 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*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_LOCAL: + /* + * Undefined operation on a named semaphore. + */ + + if ( the_semaphore->named == true ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + _POSIX_Semaphore_Delete( the_semaphore ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/semgetvalue.c b/cpukit/posix/src/semgetvalue.c new file mode 100644 index 0000000000..81042bf316 --- /dev/null +++ b/cpukit/posix/src/semgetvalue.c @@ -0,0 +1,59 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*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_LOCAL: + *sval = _CORE_semaphore_Get_count( &the_semaphore->Semaphore ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/seminit.c b/cpukit/posix/src/seminit.c new file mode 100644 index 0000000000..132be509e7 --- /dev/null +++ b/cpukit/posix/src/seminit.c @@ -0,0 +1,58 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*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; + + if ( !sem ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + status = _POSIX_Semaphore_Create_support( + NULL, + pshared, + value, + &the_semaphore + ); + + if ( status != -1 ) + *sem = the_semaphore->Object.id; + + return status; +} diff --git a/cpukit/posix/src/semopen.c b/cpukit/posix/src/semopen.c new file mode 100644 index 0000000000..b51d2043be --- /dev/null +++ b/cpukit/posix/src/semopen.c @@ -0,0 +1,136 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * sem_open + * + * Opens a named semaphore. Used in conjunction with the sem_close + * and sem_unlink commands. + * + * 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 = 0; + int status; + sem_t the_semaphore_id; + sem_t *id; + POSIX_Semaphore_Control *the_semaphore; + Objects_Locations location; + + _Thread_Disable_dispatch(); + + if ( oflag & O_CREAT ) { + va_start(arg, oflag); + mode = (mode_t) va_arg( arg, unsigned int ); + value = 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 ) { + + /* + * Unless provided a valid name that did not already exist + * and we are willing to create then it is an error. + */ + + if ( !( status == ENOENT && (oflag & O_CREAT) ) ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one_cast( status, sem_t * ); + } + } else { + + /* + * Check for existence with creation. + */ + + if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one_cast( EEXIST, sem_t * ); + } + + the_semaphore = _POSIX_Semaphore_Get( &the_semaphore_id, &location ); + the_semaphore->open_count += 1; + _Thread_Enable_dispatch(); + _Thread_Enable_dispatch(); + goto return_id; + } + + /* + * 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, + false, /* not shared across processes */ + value, + &the_semaphore + ); + + /* + * errno was set by Create_support, so don't set it again. + */ + + _Thread_Enable_dispatch(); + + if ( status == -1 ) + return SEM_FAILED; + +return_id: + #if defined(RTEMS_USE_16_BIT_OBJECT) + the_semaphore->Semaphore_id = the_semaphore->Object.id; + id = &the_semaphore->Semaphore_id; + #else + id = (sem_t *)&the_semaphore->Object.id; + #endif + return id; +} diff --git a/cpukit/posix/src/sempost.c b/cpukit/posix/src/sempost.c new file mode 100644 index 0000000000..785ad3d966 --- /dev/null +++ b/cpukit/posix/src/sempost.c @@ -0,0 +1,66 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * 11.2.7 Unlock a Semaphore, P1003.1b-1993, p.227 + */ + +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_LOCAL: + _CORE_semaphore_Surrender( + &the_semaphore->Semaphore, + the_semaphore->Object.id, +#if defined(RTEMS_MULTIPROCESSING) + NULL /* XXX need to define a routine to handle this case */ +#else + NULL +#endif + ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/semtimedwait.c b/cpukit/posix/src/semtimedwait.c new file mode 100644 index 0000000000..60faafc242 --- /dev/null +++ b/cpukit/posix/src/semtimedwait.c @@ -0,0 +1,81 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*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 *abstime +) +{ + Watchdog_Interval ticks; + bool do_wait = true; + POSIX_Absolute_timeout_conversion_results_t status; + int lock_status; + + /* + * POSIX requires that blocking calls with timeouts that take + * an absolute timeout must ignore issues with the absolute + * time provided if the operation would otherwise succeed. + * So we check the abstime provided, and hold on to whether it + * is valid or not. If it isn't correct and in the future, + * then we do a polling operation and convert the UNSATISFIED + * status into the appropriate error. + * + * If the status is POSIX_ABSOLUTE_TIMEOUT_INVALID, + * POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST, or POSIX_ABSOLUTE_TIMEOUT_IS_NOW, + * then we should not wait. + */ + status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ); + if ( status != POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE ) + do_wait = false; + + lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks ); + + /* + * This service only gives us the option to block. We used a polling + * attempt to obtain if the abstime was not in the future. If we did + * not obtain the semaphore, then not look at the status immediately, + * make sure the right reason is returned. + */ + if ( !do_wait && (lock_status == EBUSY) ) { + if ( lock_status == POSIX_ABSOLUTE_TIMEOUT_INVALID ) + rtems_set_errno_and_return_minus_one( EINVAL ); + if ( lock_status == POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST || + lock_status == POSIX_ABSOLUTE_TIMEOUT_IS_NOW ) + rtems_set_errno_and_return_minus_one( ETIMEDOUT ); + } + + return lock_status; +} diff --git a/cpukit/posix/src/semtrywait.c b/cpukit/posix/src/semtrywait.c new file mode 100644 index 0000000000..fdf50be29d --- /dev/null +++ b/cpukit/posix/src/semtrywait.c @@ -0,0 +1,42 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*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); +} diff --git a/cpukit/posix/src/semunlink.c b/cpukit/posix/src/semunlink.c new file mode 100644 index 0000000000..864749c6ac --- /dev/null +++ b/cpukit/posix/src/semunlink.c @@ -0,0 +1,67 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*PAGE + * + * sem_unlink + * + * Unlinks a named semaphore, sem_close must also be called to remove + * the semaphore. + * + * 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; + sem_t the_semaphore_id; + + _Thread_Disable_dispatch(); + + status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id ); + if ( status != 0 ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( status ); + } + + the_semaphore = (POSIX_Semaphore_Control *) _Objects_Get_local_object( + &_POSIX_Semaphore_Information, + _Objects_Get_index( the_semaphore_id ) + ); + + the_semaphore->linked = false; + _POSIX_Semaphore_Namespace_remove( the_semaphore ); + _POSIX_Semaphore_Delete( the_semaphore ); + + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/semwait.c b/cpukit/posix/src/semwait.c new file mode 100644 index 0000000000..462c31ccda --- /dev/null +++ b/cpukit/posix/src/semwait.c @@ -0,0 +1,42 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <semaphore.h> +#include <limits.h> + +#include <rtems/system.h> +#include <rtems/score/object.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/time.h> +#include <rtems/seterr.h> + +/*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 ); +} diff --git a/cpukit/posix/src/setcancelstate.c b/cpukit/posix/src/setcancelstate.c new file mode 100644 index 0000000000..7b7543b639 --- /dev/null +++ b/cpukit/posix/src/setcancelstate.c @@ -0,0 +1,66 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +/* + * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 + */ + +int pthread_setcancelstate( + int state, + int *oldstate +) +{ + POSIX_API_Control *thread_support; + + /* + * Don't even think about deleting a resource from an ISR. + * Besides this request is supposed to be for _Thread_Executing + * and the ISR context is not a thread. + */ + + if ( _ISR_Is_in_progress() ) + return EPROTO; + + if ( !oldstate ) + return EINVAL; + + if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE ) + return EINVAL; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + _Thread_Disable_dispatch(); + *oldstate = thread_support->cancelability_state; + thread_support->cancelability_state = state; + + _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch(_Thread_Executing); + + /* + * _Thread_Enable_dispatch is invoked by above call. + */ + + return 0; +} diff --git a/cpukit/posix/src/setcanceltype.c b/cpukit/posix/src/setcanceltype.c new file mode 100644 index 0000000000..85f645bad4 --- /dev/null +++ b/cpukit/posix/src/setcanceltype.c @@ -0,0 +1,65 @@ +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +/* + * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 + */ + +int pthread_setcanceltype( + int type, + int *oldtype +) +{ + POSIX_API_Control *thread_support; + + /* + * Don't even think about deleting a resource from an ISR. + * Besides this request is supposed to be for _Thread_Executing + * and the ISR context is not a thread. + */ + + if ( _ISR_Is_in_progress() ) + return EPROTO; + + if ( !oldtype ) + return EINVAL; + + if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS ) + return EINVAL; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + _Thread_Disable_dispatch(); + *oldtype = thread_support->cancelability_type; + thread_support->cancelability_type = type; + + _POSIX_Thread_Evaluate_cancellation_and_enable_dispatch(_Thread_Executing); + + /* + * _Thread_Enable_dispatch is invoked by above call. + */ + return 0; +} diff --git a/cpukit/posix/src/setitimer.c b/cpukit/posix/src/setitimer.c new file mode 100644 index 0000000000..24a4723100 --- /dev/null +++ b/cpukit/posix/src/setitimer.c @@ -0,0 +1,43 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <sys/time.h> +#include <errno.h> +#include <rtems/seterr.h> + +int setitimer( + int which, + const struct itimerval *value, + struct itimerval *ovalue +) +{ + if ( !value ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + if ( !ovalue ) + rtems_set_errno_and_return_minus_one( EFAULT ); + + switch ( which ) { + case ITIMER_REAL: + case ITIMER_VIRTUAL: + case ITIMER_PROF: + rtems_set_errno_and_return_minus_one( ENOSYS ); + default: + break; + } + rtems_set_errno_and_return_minus_one( EINVAL ); +} + diff --git a/cpukit/posix/src/sigaction.c b/cpukit/posix/src/sigaction.c new file mode 100644 index 0000000000..b92154663c --- /dev/null +++ b/cpukit/posix/src/sigaction.c @@ -0,0 +1,93 @@ +/* + * 3.3.4 Examine and Change Signal Action, P1003.1b-1993, p. 70 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/seterr.h> +#include <rtems/score/isr.h> + +/* + * PARAMETERS_PASSING_S is defined in ptimer.c + */ + +extern void PARAMETERS_PASSING_S (int num_signal, const struct sigaction inf); + +int sigaction( + int sig, + const struct sigaction *act, + struct sigaction *oact +) +{ + ISR_Level level; + + if ( oact ) + *oact = _POSIX_signals_Vectors[ sig ]; + + if ( !sig ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !is_valid_signo(sig) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * Some signals cannot be ignored (P1003.1b-1993, pp. 70-72 and references. + * + * NOTE: Solaris documentation claims to "silently enforce" this which + * contradicts the POSIX specification. + */ + + if ( sig == SIGKILL ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * Evaluate the new action structure and set the global signal vector + * appropriately. + */ + + if ( act ) { + + /* + * Unless the user is installing the default signal actions, then + * we can just copy the provided sigaction structure into the vectors. + */ + + _ISR_Disable( level ); + if ( act->sa_handler == SIG_DFL ) { + _POSIX_signals_Vectors[ sig ] = _POSIX_signals_Default_vectors[ sig ]; + } else { + _POSIX_signals_Clear_process_signals( sig ); + _POSIX_signals_Vectors[ sig ] = *act; + } + _ISR_Enable( level ); + } + + /* + * No need to evaluate or dispatch because: + * + * + If we were ignoring the signal before, none could be pending + * now (signals not posted when SIG_IGN). + * + If we are now ignoring a signal that was previously pending, + * we clear the pending signal indicator. + */ + + return 0; +} diff --git a/cpukit/posix/src/sigaddset.c b/cpukit/posix/src/sigaddset.c new file mode 100644 index 0000000000..5c65ab60eb --- /dev/null +++ b/cpukit/posix/src/sigaddset.c @@ -0,0 +1,40 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/sigset.h> +#include <rtems/seterr.h> + +int sigaddset( + sigset_t *set, + int signo +) +{ + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !signo ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !is_valid_signo(signo) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + *set |= signo_to_mask(signo); + return 0; +} diff --git a/cpukit/posix/src/sigdelset.c b/cpukit/posix/src/sigdelset.c new file mode 100644 index 0000000000..856eb384df --- /dev/null +++ b/cpukit/posix/src/sigdelset.c @@ -0,0 +1,44 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/sigset.h> +#include <rtems/seterr.h> + +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + */ + +int sigdelset( + sigset_t *set, + int signo +) +{ + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !signo ) + return 0; + + if ( !is_valid_signo(signo) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + *set &= ~signo_to_mask(signo); + return 0; +} diff --git a/cpukit/posix/src/sigemptyset.c b/cpukit/posix/src/sigemptyset.c new file mode 100644 index 0000000000..9a6d3580ca --- /dev/null +++ b/cpukit/posix/src/sigemptyset.c @@ -0,0 +1,33 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/sigset.h> +#include <rtems/seterr.h> + +int sigemptyset( + sigset_t *set +) +{ + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + *set = 0; + return 0; +} diff --git a/cpukit/posix/src/sigfillset.c b/cpukit/posix/src/sigfillset.c new file mode 100644 index 0000000000..a67b9b9a3e --- /dev/null +++ b/cpukit/posix/src/sigfillset.c @@ -0,0 +1,33 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/sigset.h> +#include <rtems/seterr.h> + +int sigfillset( + sigset_t *set +) +{ + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + *set = SIGNAL_ALL_MASK; + return 0; +} diff --git a/cpukit/posix/src/sigismember.c b/cpukit/posix/src/sigismember.c new file mode 100644 index 0000000000..958c5336af --- /dev/null +++ b/cpukit/posix/src/sigismember.c @@ -0,0 +1,42 @@ +/* + * 3.3.3 Manipulate Signal Sets, P1003.1b-1993, p. 69 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/sigset.h> +#include <rtems/seterr.h> + +int sigismember( + const sigset_t *set, + int signo +) +{ + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !signo ) + return 0; + + if ( !is_valid_signo(signo) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( *set & signo_to_mask(signo) ) + return 1; + + return 0; +} diff --git a/cpukit/posix/src/signal_2.c b/cpukit/posix/src/signal_2.c new file mode 100644 index 0000000000..326861752f --- /dev/null +++ b/cpukit/posix/src/signal_2.c @@ -0,0 +1,54 @@ +/* + * signal(2) - Install signal handler + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> +#include <errno.h> + +#ifndef HAVE_SIGHANDLER_T + typedef void (*sighandler_t)(int); +#endif + +sighandler_t signal( + int signum, + sighandler_t handler +) +{ + struct sigaction s; + struct sigaction old; + + s.sa_handler = handler ; + sigemptyset(&s.sa_mask); + + /* + * Depending on which system we want to behave like, one of + * the following versions should be chosen. + */ + +/* #define signal_like_linux */ + +#if defined(signal_like_linux) + s.sa_flags = SA_RESTART | SA_INTERRUPT | SA_NOMASK; + s.sa_restorer= NULL ; +#elif defined(signal_like_SVR4) + s.sa_flags = SA_RESTART; +#else + s.sa_flags = 0; +#endif + + sigaction( signum, &s, &old ); + return (sighandler_t) old.sa_handler; +} diff --git a/cpukit/posix/src/sigpending.c b/cpukit/posix/src/sigpending.c new file mode 100644 index 0000000000..9f22760a58 --- /dev/null +++ b/cpukit/posix/src/sigpending.c @@ -0,0 +1,40 @@ +/* + * 3.3.6 Examine Pending Signals, P1003.1b-1993, p. 75 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/seterr.h> + +int sigpending( + sigset_t *set +) +{ + POSIX_API_Control *api; + + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + *set = api->signals_pending | _POSIX_signals_Pending; + + return 0; +} diff --git a/cpukit/posix/src/sigprocmask.c b/cpukit/posix/src/sigprocmask.c new file mode 100644 index 0000000000..d20a10d1ba --- /dev/null +++ b/cpukit/posix/src/sigprocmask.c @@ -0,0 +1,38 @@ +/* + * 3.3.5 Examine and Change Blocked Signals, P1003.1b-1993, p. 73 + * + * NOTE: P1003.1c/D10, p. 37 adds pthread_sigmask(). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> + +int sigprocmask( + int how, + const sigset_t *set, + sigset_t *oset +) +{ + /* + * P1003.1c/Draft 10, p. 38 maps sigprocmask to pthread_sigmask. + */ + +#if defined(RTEMS_POSIX_API) + return pthread_sigmask( how, set, oset ); +#else + return -1; +#endif +} diff --git a/cpukit/posix/src/sigqueue.c b/cpukit/posix/src/sigqueue.c new file mode 100644 index 0000000000..727f2c6b42 --- /dev/null +++ b/cpukit/posix/src/sigqueue.c @@ -0,0 +1,32 @@ +/* + * 3.3.9 Queue a Signal to a Process, P1003.1b-1993, p. 78 + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +int sigqueue( + pid_t pid, + int signo, + const union sigval value +) +{ + return killinfo( pid, signo, &value ); +} diff --git a/cpukit/posix/src/sigsuspend.c b/cpukit/posix/src/sigsuspend.c new file mode 100644 index 0000000000..77b6d90a29 --- /dev/null +++ b/cpukit/posix/src/sigsuspend.c @@ -0,0 +1,59 @@ +/* + * 3.3.7 Wait for a Signal, P1003.1b-1993, p. 75 + * + * COPYRIGHT (c) 1989-2004. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <assert.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/seterr.h> + +int sigsuspend( + const sigset_t *sigmask +) +{ + sigset_t saved_signals_blocked; + sigset_t current_unblocked_signals; + int status; + POSIX_API_Control *api; + + api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + /* + * We use SIG_BLOCK and not SIG_SETMASK because there may be + * signals which might be pending, which might get caught here. + * We want the signals to be caught inside sigtimedwait. + */ + status = sigprocmask( SIG_BLOCK, sigmask, &saved_signals_blocked ); + + current_unblocked_signals = ~(*sigmask); + status = sigtimedwait( ¤t_unblocked_signals, NULL, NULL ); + + (void) sigprocmask( SIG_SETMASK, &saved_signals_blocked, NULL ); + + /* + * sigtimedwait() returns the signal number while sigsuspend() + * is supposed to return -1 and EINTR when a signal is caught. + */ + #if defined(RTEMS_DEBUG) + assert( status != -1 ); + #endif + + rtems_set_errno_and_return_minus_one( EINTR ); +} diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c new file mode 100644 index 0000000000..41ebf88677 --- /dev/null +++ b/cpukit/posix/src/sigtimedwait.c @@ -0,0 +1,177 @@ +/* + * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/seterr.h> +#include <rtems/posix/time.h> +#include <rtems/score/isr.h> + +int _POSIX_signals_Get_lowest( + sigset_t set +) +{ + int signo; + + for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { + if ( set & signo_to_mask( signo ) ) { + goto found_it; + } + } + + /* + * We assume SIGHUP == 1 and is the first non-real-time signal. + */ + + #if (SIGHUP != 1) + #error "Assumption that SIGHUP==1 violated!!" + #endif + for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) { + if ( set & signo_to_mask( signo ) ) { + goto found_it; + } + } + + /* + * This is structured this way to eliminate the need to have + * a return 0. This routine will NOT be called unless a signal + * is pending in the set passed in. + */ +found_it: + return signo; +} + +int sigtimedwait( + const sigset_t *set, + siginfo_t *info, + const struct timespec *timeout +) +{ + Thread_Control *the_thread; + POSIX_API_Control *api; + Watchdog_Interval interval; + siginfo_t signal_information; + siginfo_t *the_info; + int signo; + ISR_Level level; + + /* + * Error check parameters before disabling interrupts. + */ + if ( !set ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* NOTE: This is very specifically a RELATIVE not ABSOLUTE time + * in the Open Group specification. + */ + + interval = 0; + if ( timeout ) { + + if ( !_Timespec_Is_valid( timeout ) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + interval = _Timespec_To_ticks( timeout ); + + if ( !interval ) + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* + * Initialize local variables. + */ + + the_info = ( info ) ? info : &signal_information; + + the_thread = _Thread_Executing; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + + /* + * What if they are already pending? + */ + + /* API signals pending? */ + + _ISR_Disable( level ); + if ( *set & api->signals_pending ) { + /* XXX real info later */ + the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending ); + _POSIX_signals_Clear_signals( + api, + the_info->si_signo, + the_info, + false, + false + ); + _ISR_Enable( level ); + + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + return the_info->si_signo; + } + + /* Process pending signals? */ + + if ( *set & _POSIX_signals_Pending ) { + signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending ); + _POSIX_signals_Clear_signals( api, signo, the_info, true, false ); + _ISR_Enable( level ); + + the_info->si_signo = signo; + the_info->si_code = SI_USER; + the_info->si_value.sival_int = 0; + return signo; + } + + the_info->si_signo = -1; + + _Thread_Disable_dispatch(); + the_thread->Wait.queue = &_POSIX_signals_Wait_queue; + the_thread->Wait.return_code = EINTR; + the_thread->Wait.option = *set; + the_thread->Wait.return_argument = the_info; + _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue ); + _ISR_Enable( level ); + _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval ); + _Thread_Enable_dispatch(); + + /* + * When the thread is set free by a signal, it is need to eliminate + * the signal. + */ + + _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false ); + + /* Set errno only if return code is not EINTR or + * if EINTR was caused by a signal being caught, which + * was not in our set. + */ + + if ( (_Thread_Executing->Wait.return_code != EINTR) + || !(*set & signo_to_mask( the_info->si_signo )) ) { + errno = _Thread_Executing->Wait.return_code; + return -1; + } + + return the_info->si_signo; +} diff --git a/cpukit/posix/src/sigwait.c b/cpukit/posix/src/sigwait.c new file mode 100644 index 0000000000..1c34b5ee5b --- /dev/null +++ b/cpukit/posix/src/sigwait.c @@ -0,0 +1,44 @@ +/* + * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 + * + * NOTE: P1003.1c/D10, p. 39 adds sigwait(). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +int sigwait( + const sigset_t *set, + int *sig +) +{ + int status; + + status = sigtimedwait( set, NULL, NULL ); + + if ( status != -1 ) { + if ( sig ) + *sig = status; + return 0; + } + + return errno; +} diff --git a/cpukit/posix/src/sigwaitinfo.c b/cpukit/posix/src/sigwaitinfo.c new file mode 100644 index 0000000000..2c61e2a8fc --- /dev/null +++ b/cpukit/posix/src/sigwaitinfo.c @@ -0,0 +1,33 @@ +/* + * 3.3.8 Synchronously Accept a Signal, P1003.1b-1993, p. 76 + * + * NOTE: P1003.1c/D10, p. 39 adds sigwait(). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <signal.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> + +int sigwaitinfo( + const sigset_t *set, + siginfo_t *info +) +{ + return sigtimedwait( set, info, NULL ); +} diff --git a/cpukit/posix/src/sysconf.c b/cpukit/posix/src/sysconf.c new file mode 100644 index 0000000000..97a774da25 --- /dev/null +++ b/cpukit/posix/src/sysconf.c @@ -0,0 +1,55 @@ +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <unistd.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/tod.h> +#include <rtems/libio_.h> + +#include <sys/param.h> + +/*PAGE + * + * 4.8.1 Get Configurable System Variables, P1003.1b-1993, p. 95 + */ + +long sysconf( + int name +) +{ + if ( name == _SC_CLK_TCK ) + return (TOD_MICROSECONDS_PER_SECOND / + rtems_configuration_get_microseconds_per_tick()); + + if ( name == _SC_OPEN_MAX ) + return rtems_libio_number_iops; + + if ( name == _SC_GETPW_R_SIZE_MAX ) + return 1024; + + if ( name == _SC_PAGESIZE ) + return PAGE_SIZE; + +#if defined(__sparc__) + if ( name == 515 ) /* Solaris _SC_STACK_PROT */ + return 0; +#endif + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/testcancel.c b/cpukit/posix/src/testcancel.c new file mode 100644 index 0000000000..bea71203d1 --- /dev/null +++ b/cpukit/posix/src/testcancel.c @@ -0,0 +1,57 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> +#include <rtems/posix/cancel.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/threadsup.h> + +/*PAGE + * + * 18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183 + */ + +void pthread_testcancel( void ) +{ + POSIX_API_Control *thread_support; + bool cancel = false; + + /* + * Don't even think about deleting a resource from an ISR. + * Besides this request is supposed to be for _Thread_Executing + * and the ISR context is not a thread. + */ + + if ( _ISR_Is_in_progress() ) + return; + + thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; + + _Thread_Disable_dispatch(); + if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE && + thread_support->cancelation_requested ) + cancel = true; + _Thread_Enable_dispatch(); + + if ( cancel ) + _POSIX_Thread_Exit( _Thread_Executing, PTHREAD_CANCELED ); +} diff --git a/cpukit/posix/src/timercreate.c b/cpukit/posix/src/timercreate.c new file mode 100644 index 0000000000..1d843580ba --- /dev/null +++ b/cpukit/posix/src/timercreate.c @@ -0,0 +1,97 @@ +/* + * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/thread.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/time.h> +#include <rtems/posix/timer.h> + +int timer_create( + clockid_t clock_id, + struct sigevent *evp, + timer_t *timerid +) +{ + POSIX_Timer_Control *ptimer; + + if ( clock_id != CLOCK_REALTIME ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !timerid ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * The data of the structure evp are checked in order to verify if they + * are coherent. + */ + + if (evp != NULL) { + /* The structure has data */ + if ( ( evp->sigev_notify != SIGEV_NONE ) && + ( evp->sigev_notify != SIGEV_SIGNAL ) ) { + /* The value of the field sigev_notify is not valid */ + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + if ( !evp->sigev_signo ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + if ( !is_valid_signo(evp->sigev_signo) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + /* + * Allocate a timer + */ + ptimer = _POSIX_Timer_Allocate(); + if ( !ptimer ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EAGAIN ); + } + + /* The data of the created timer are stored to use them later */ + + ptimer->state = POSIX_TIMER_STATE_CREATE_NEW; + ptimer->thread_id = _Thread_Executing->Object.id; + + if ( evp != NULL ) { + ptimer->inf.sigev_notify = evp->sigev_notify; + ptimer->inf.sigev_signo = evp->sigev_signo; + ptimer->inf.sigev_value = evp->sigev_value; + } + + ptimer->overrun = 0; + ptimer->timer_data.it_value.tv_sec = 0; + ptimer->timer_data.it_value.tv_nsec = 0; + ptimer->timer_data.it_interval.tv_sec = 0; + ptimer->timer_data.it_interval.tv_nsec = 0; + + _Watchdog_Initialize( &ptimer->Timer, NULL, 0, NULL ); + _Objects_Open_u32(&_POSIX_Timer_Information, &ptimer->Object, 0); + + *timerid = ptimer->Object.id; + _Thread_Enable_dispatch(); + return 0; +} diff --git a/cpukit/posix/src/timerdelete.c b/cpukit/posix/src/timerdelete.c new file mode 100644 index 0000000000..cc70871e3c --- /dev/null +++ b/cpukit/posix/src/timerdelete.c @@ -0,0 +1,63 @@ +/* + * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> +#include <pthread.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/thread.h> +#include <rtems/posix/time.h> +#include <rtems/posix/timer.h> + + +int timer_delete( + timer_t timerid +) +{ + /* + * IDEA: This function must probably stop the timer first and then delete it + * + * It will have to do a call to rtems_timer_cancel and then another + * call to rtems_timer_delete. + * The call to rtems_timer_delete will be probably unnecessary, + * because rtems_timer_delete stops the timer before deleting it. + */ + POSIX_Timer_Control *ptimer; + Objects_Locations location; + + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); + ptimer->state = POSIX_TIMER_STATE_FREE; + (void) _Watchdog_Remove( &ptimer->Timer ); + _POSIX_Timer_Free( ptimer ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/timergetoverrun.c b/cpukit/posix/src/timergetoverrun.c new file mode 100644 index 0000000000..1ad7bc4d04 --- /dev/null +++ b/cpukit/posix/src/timergetoverrun.c @@ -0,0 +1,58 @@ +/* + * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/thread.h> +#include <rtems/posix/timer.h> + +/* + * timer_getoverrun + * + * The expiration of a timer must increase by one a counter. + * After the signal handler associated to the timer finishes + * its execution, _POSIX_Timer_TSR will have to set this counter to 0. + */ +int timer_getoverrun( + timer_t timerid +) +{ + int overrun; + POSIX_Timer_Control *ptimer; + Objects_Locations location; + + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + overrun = ptimer->overrun; + ptimer->overrun = 0; + _Thread_Enable_dispatch(); + return overrun; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/timergettime.c b/cpukit/posix/src/timergettime.c new file mode 100644 index 0000000000..bb39121b81 --- /dev/null +++ b/cpukit/posix/src/timergettime.c @@ -0,0 +1,77 @@ +/* + * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/timespec.h> +#include <rtems/posix/timer.h> + +/* + * - When a timer is initialized, the value of the time in + * that moment is stored. + * - When this function is called, it returns the difference + * between the current time and the initialization time. + */ + +int timer_gettime( + timer_t timerid, + struct itimerspec *value +) +{ + POSIX_Timer_Control *ptimer; + Objects_Locations location; + struct timespec current_time; + Watchdog_Interval left; + + if ( !value ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* Reads the current time */ + _TOD_Get( ¤t_time ); + + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + + /* Calculates the time left before the timer finishes */ + + left = + (ptimer->Timer.start_time + ptimer->Timer.initial) - /* expire */ + _Watchdog_Ticks_since_boot; /* now */ + + _Timespec_From_ticks( left, &value->it_value ); + + value->it_interval = ptimer->timer_data.it_interval; + + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/timerinserthelper.c b/cpukit/posix/src/timerinserthelper.c new file mode 100644 index 0000000000..a2ced7a79b --- /dev/null +++ b/cpukit/posix/src/timerinserthelper.c @@ -0,0 +1,57 @@ +/* + * Helper routine for POSIX timers + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/isr.h> +#include <rtems/score/watchdog.h> +#include <rtems/posix/timer.h> +#include <rtems/posix/ptimer.h> + +bool _POSIX_Timer_Insert_helper( + Watchdog_Control *timer, + Watchdog_Interval ticks, + Objects_Id id, + Watchdog_Service_routine_entry TSR, + void *arg +) +{ + ISR_Level level; + + (void) _Watchdog_Remove( timer ); + _ISR_Disable( level ); + + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + if ( timer->state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + return false; + } + + /* + * OK. Now we now the timer was not rescheduled by an interrupt + * so we can atomically initialize it as in use. + */ + _Watchdog_Initialize( timer, TSR, id, arg ); + _Watchdog_Insert_ticks( timer, ticks ); + _ISR_Enable( level ); + return true; +} diff --git a/cpukit/posix/src/timersettime.c b/cpukit/posix/src/timersettime.c new file mode 100644 index 0000000000..d618bd391e --- /dev/null +++ b/cpukit/posix/src/timersettime.c @@ -0,0 +1,136 @@ +/* + * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/posix/time.h> +#include <rtems/posix/ptimer.h> +#include <rtems/posix/timer.h> + +int timer_settime( + timer_t timerid, + int flags, + const struct itimerspec *value, + struct itimerspec *ovalue +) +{ + POSIX_Timer_Control *ptimer; + Objects_Locations location; + bool activated; + uint32_t initial_period; + struct itimerspec normalize; + + if ( !value ) + rtems_set_errno_and_return_minus_one( EINVAL ); + + /* + * First, it verifies if the structure "value" is correct + * if the number of nanoseconds is not correct return EINVAL + */ + if ( !_Timespec_Is_valid( &(value->it_value) ) ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + if ( !_Timespec_Is_valid( &(value->it_interval) ) ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + if ( flags != TIMER_ABSTIME && flags != POSIX_TIMER_RELATIVE ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + normalize = *value; + + /* Convert absolute to relative time */ + if (flags == TIMER_ABSTIME) { + struct timespec now; + _TOD_Get( &now ); + /* Check for seconds in the past */ + if ( _Timespec_Greater_than( &now, &normalize.it_value ) ) + rtems_set_errno_and_return_minus_one( EINVAL ); + _Timespec_Subtract( &now, &normalize.it_value, &normalize.it_value ); + } + + /* If the function reaches this point, then it will be necessary to do + * something with the structure of times of the timer: to stop, start + * or start it again + */ + + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + + case OBJECTS_LOCAL: + /* First, it verifies if the timer must be stopped */ + if ( normalize.it_value.tv_sec == 0 && normalize.it_value.tv_nsec == 0 ) { + /* Stop the timer */ + (void) _Watchdog_Remove( &ptimer->Timer ); + /* The old data of the timer are returned */ + if ( ovalue ) + *ovalue = ptimer->timer_data; + /* The new data are set */ + ptimer->timer_data = normalize; + /* Indicates that the timer is created and stopped */ + ptimer->state = POSIX_TIMER_STATE_CREATE_STOP; + /* Returns with success */ + _Thread_Enable_dispatch(); + return 0; + } + + /* Convert from seconds and nanoseconds to ticks */ + ptimer->ticks = _Timespec_To_ticks( &value->it_interval ); + initial_period = _Timespec_To_ticks( &normalize.it_value ); + + + activated = _POSIX_Timer_Insert_helper( + &ptimer->Timer, + initial_period, + ptimer->Object.id, + _POSIX_Timer_TSR, + ptimer + ); + if ( !activated ) { + _Thread_Enable_dispatch(); + return 0; + } + + /* + * The timer has been started and is running. So we return the + * old ones in "ovalue" + */ + if ( ovalue ) + *ovalue = ptimer->timer_data; + ptimer->timer_data = normalize; + + /* Indicate that the time is running */ + ptimer->state = POSIX_TIMER_STATE_CREATE_RUN; + _TOD_Get( &ptimer->time ); + _Thread_Enable_dispatch(); + return 0; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: +#endif + case OBJECTS_ERROR: + break; + } + + rtems_set_errno_and_return_minus_one( EINVAL ); +} diff --git a/cpukit/posix/src/timertsr.c b/cpukit/posix/src/timertsr.c new file mode 100644 index 0000000000..b2a86ce4fb --- /dev/null +++ b/cpukit/posix/src/timertsr.c @@ -0,0 +1,81 @@ +/* + * _POSIX_Timer_TSR + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <time.h> +#include <pthread.h> +#include <signal.h> + +#include <rtems/system.h> +#include <rtems/seterr.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/posix/time.h> +#include <rtems/posix/ptimer.h> +#include <rtems/posix/timer.h> + +/* + * This is the operation that is run when a timer expires + */ +void _POSIX_Timer_TSR( + Objects_Id timer __attribute__((unused)), + void *data) +{ + POSIX_Timer_Control *ptimer; + bool activated; + + ptimer = (POSIX_Timer_Control *)data; + + /* Increment the number of expirations. */ + ptimer->overrun = ptimer->overrun + 1; + + /* The timer must be reprogrammed */ + if ( ( ptimer->timer_data.it_interval.tv_sec != 0 ) || + ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) { + activated = _POSIX_Timer_Insert_helper( + &ptimer->Timer, + ptimer->ticks, + ptimer->Object.id, + _POSIX_Timer_TSR, + ptimer + ); + if ( !activated ) + return; + + /* Store the time when the timer was started again */ + _TOD_Get( &ptimer->time ); + + /* The state really did not change but just to be safe */ + ptimer->state = POSIX_TIMER_STATE_CREATE_RUN; + } else { + /* Indicates that the timer is stopped */ + ptimer->state = POSIX_TIMER_STATE_CREATE_STOP; + } + + /* + * The sending of the signal to the process running the handling function + * specified for that signal is simulated + */ + + if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) { + /* XXX error handling */ + } + + /* After the signal handler returns, the count of expirations of the + * timer must be set to 0. + */ + ptimer->overrun = 0; +} diff --git a/cpukit/posix/src/ualarm.c b/cpukit/posix/src/ualarm.c new file mode 100644 index 0000000000..f43aabe52c --- /dev/null +++ b/cpukit/posix/src/ualarm.c @@ -0,0 +1,105 @@ +/* + * 3.4.1 Schedule Alarm, P1003.1b-1993, p. 79 + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +/* #include <errno.h> */ + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * _POSIX_signals_Ualarm_TSR + */ + +void _POSIX_signals_Ualarm_TSR( + Objects_Id id __attribute__((unused)), + void *argument __attribute__((unused)) +) +{ + /* + * Send a SIGALRM but if there is a problem, ignore it. + * It's OK, there isn't a way this should fail. + */ + (void) kill( getpid(), SIGALRM ); + + /* + * If the reset interval is non-zero, reschedule ourselves. + */ + _Watchdog_Reset( &_POSIX_signals_Ualarm_timer ); +} + +useconds_t ualarm( + useconds_t useconds, + useconds_t interval +) +{ + useconds_t remaining = 0; + Watchdog_Control *the_timer; + Watchdog_Interval ticks; + struct timespec tp; + + the_timer = &_POSIX_signals_Ualarm_timer; + + /* + * Initialize the timer used to implement alarm(). + */ + + if ( !the_timer->routine ) { + _Watchdog_Initialize( the_timer, _POSIX_signals_Ualarm_TSR, 0, NULL ); + } else { + Watchdog_States state; + + state = _Watchdog_Remove( the_timer ); + if ( (state == WATCHDOG_ACTIVE) || (state == WATCHDOG_REMOVE_IT) ) { + /* + * The stop_time and start_time fields are snapshots of ticks since + * boot. Since alarm() is dealing in seconds, we must account for + * this. + */ + + ticks = the_timer->initial; + ticks -= (the_timer->stop_time - the_timer->start_time); + /* remaining is now in ticks */ + + _Timespec_From_ticks( ticks, &tp ); + remaining = tp.tv_sec * TOD_MICROSECONDS_PER_SECOND; + remaining += tp.tv_nsec / 1000; + } + } + + /* + * If useconds is non-zero, then the caller wants to schedule + * the alarm repeatedly at that interval. If the interval is + * less than a single clock tick, then fudge it to a clock tick. + */ + if ( useconds ) { + Watchdog_Interval ticks; + + tp.tv_sec = useconds / TOD_MICROSECONDS_PER_SECOND; + tp.tv_nsec = (useconds % TOD_MICROSECONDS_PER_SECOND) * 1000; + ticks = _Timespec_To_ticks( &tp ); + if ( ticks == 0 ) + ticks = 1; + + _Watchdog_Insert_ticks( the_timer, _Timespec_To_ticks( &tp ) ); + } + + return remaining; +} diff --git a/cpukit/posix/src/vfork.c b/cpukit/posix/src/vfork.c new file mode 100644 index 0000000000..4db522f015 --- /dev/null +++ b/cpukit/posix/src/vfork.c @@ -0,0 +1,23 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <unistd.h> + +pid_t vfork(void) +{ + return -1; +} + diff --git a/cpukit/posix/src/wait.c b/cpukit/posix/src/wait.c new file mode 100644 index 0000000000..b277930b47 --- /dev/null +++ b/cpukit/posix/src/wait.c @@ -0,0 +1,28 @@ +/* + * waitpid() - POSIX 1003.1b 3.2.1 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <rtems/seterr.h> + +int wait( + int *stat_loc +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} diff --git a/cpukit/posix/src/waitpid.c b/cpukit/posix/src/waitpid.c new file mode 100644 index 0000000000..b3c3918f4e --- /dev/null +++ b/cpukit/posix/src/waitpid.c @@ -0,0 +1,30 @@ +/* + * waitpid() - POSIX 1003.1 3.2.1 + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <rtems/seterr.h> + +int waitpid( + pid_t pid, + int *stat_loc, + int options +) +{ + rtems_set_errno_and_return_minus_one( ENOSYS ); +} |