summaryrefslogtreecommitdiffstats
path: root/cpukit/posix
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-10-19 13:47:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-10-24 10:19:05 +0200
commitc31058947491ca319c901040219be39e4f8155b6 (patch)
tree435bf0887bd77e3d344b31275853a6e52fca8dd8 /cpukit/posix
parentscore: Rename function threadq support function (diff)
downloadrtems-c31058947491ca319c901040219be39e4f8155b6.tar.bz2
score: Move thread queue timeout handling
Update #3117. Update #3182.
Diffstat (limited to 'cpukit/posix')
-rw-r--r--cpukit/posix/include/rtems/posix/mqueueimpl.h25
-rw-r--r--cpukit/posix/include/rtems/posix/muteximpl.h32
-rw-r--r--cpukit/posix/src/condwaitsupp.c126
-rw-r--r--cpukit/posix/src/mqueuereceive.c15
-rw-r--r--cpukit/posix/src/mqueuerecvsupp.c29
-rw-r--r--cpukit/posix/src/mqueuesend.c4
-rw-r--r--cpukit/posix/src/mqueuesendsupp.c26
-rw-r--r--cpukit/posix/src/mqueuetimedreceive.c36
-rw-r--r--cpukit/posix/src/mqueuetimedsend.c36
-rw-r--r--cpukit/posix/src/mutexlock.c13
-rw-r--r--cpukit/posix/src/mutexlocksupp.c20
-rw-r--r--cpukit/posix/src/mutextimedlock.c50
-rw-r--r--cpukit/posix/src/mutextrylock.c24
-rw-r--r--cpukit/posix/src/nanosleep.c255
-rw-r--r--cpukit/posix/src/pbarrierwait.c1
-rw-r--r--cpukit/posix/src/prwlockrdlock.c2
-rw-r--r--cpukit/posix/src/prwlocktimedrdlock.c47
-rw-r--r--cpukit/posix/src/prwlocktimedwrlock.c47
-rw-r--r--cpukit/posix/src/prwlockwrlock.c2
-rw-r--r--cpukit/posix/src/pthreadjoin.c1
-rw-r--r--cpukit/posix/src/semtimedwait.c23
-rw-r--r--cpukit/posix/src/sigtimedwait.c25
22 files changed, 280 insertions, 559 deletions
diff --git a/cpukit/posix/include/rtems/posix/mqueueimpl.h b/cpukit/posix/include/rtems/posix/mqueueimpl.h
index 5888800ca1..6813a3ef88 100644
--- a/cpukit/posix/include/rtems/posix/mqueueimpl.h
+++ b/cpukit/posix/include/rtems/posix/mqueueimpl.h
@@ -22,6 +22,7 @@
#include <rtems/posix/mqueue.h>
#include <rtems/posix/posixapi.h>
#include <rtems/score/coremsgimpl.h>
+#include <rtems/score/threadqimpl.h>
#include <rtems/seterr.h>
@@ -63,12 +64,12 @@ void _POSIX_Message_queue_Delete(
* @note This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open time.
*/
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
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
);
/**
@@ -77,12 +78,12 @@ ssize_t _POSIX_Message_queue_Receive_support(
* 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,
- unsigned int msg_prio,
- bool wait,
- Watchdog_Interval timeout
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
);
RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *
diff --git a/cpukit/posix/include/rtems/posix/muteximpl.h b/cpukit/posix/include/rtems/posix/muteximpl.h
index f146e0d9db..435b43634d 100644
--- a/cpukit/posix/include/rtems/posix/muteximpl.h
+++ b/cpukit/posix/include/rtems/posix/muteximpl.h
@@ -132,7 +132,7 @@ Status_Control _POSIX_Mutex_Seize_slow(
POSIX_Mutex_Control *the_mutex,
const Thread_queue_Operations *operations,
Thread_Control *executing,
- bool wait,
+ const struct timespec *abstime,
Thread_queue_Context *queue_context
);
@@ -171,7 +171,7 @@ RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Seize(
unsigned long flags,
const Thread_queue_Operations *operations,
Thread_Control *executing,
- bool wait,
+ const struct timespec *abstime,
Thread_queue_Context *queue_context
)
{
@@ -198,7 +198,7 @@ RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Seize(
the_mutex,
operations,
executing,
- wait,
+ abstime,
queue_context
);
}
@@ -329,11 +329,11 @@ RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_set_owner(
}
RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_seize(
- POSIX_Mutex_Control *the_mutex,
- unsigned long flags,
- Thread_Control *executing,
- bool wait,
- Thread_queue_Context *queue_context
+ POSIX_Mutex_Control *the_mutex,
+ unsigned long flags,
+ Thread_Control *executing,
+ const struct timespec *abstime,
+ Thread_queue_Context *queue_context
)
{
Thread_Control *owner;
@@ -371,7 +371,7 @@ RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_seize(
the_mutex,
POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS,
executing,
- wait,
+ abstime,
queue_context
);
}
@@ -444,16 +444,12 @@ RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_surrender(
return STATUS_SUCCESSFUL;
}
-/**
- * @brief POSIX Mutex Lock Support Method
- *
- * A support routine which implements guts of the blocking, non-blocking, and
- * timed wait version of mutex lock.
- */
+#define POSIX_MUTEX_ABSTIME_TRY_LOCK ((uintptr_t) 1)
+
int _POSIX_Mutex_Lock_support(
- pthread_mutex_t *mutex,
- bool blocking,
- Watchdog_Interval timeout
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
);
static inline POSIX_Mutex_Control *_POSIX_Mutex_Get(
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c
index ceaa6eb1af..32c1eab629 100644
--- a/cpukit/posix/src/condwaitsupp.c
+++ b/cpukit/posix/src/condwaitsupp.c
@@ -25,7 +25,7 @@
#include <rtems/score/status.h>
#include <rtems/score/threaddispatch.h>
-static void _POSIX_Condition_variables_Enqueue_callout(
+static void _POSIX_Condition_variables_Mutex_unlock(
Thread_queue_Queue *queue,
Thread_Control *the_thread,
Thread_queue_Context *queue_context
@@ -44,11 +44,52 @@ static void _POSIX_Condition_variables_Enqueue_callout(
* case, so we follow their lead.
*/
_Assert( mutex_error == EINVAL || mutex_error == EPERM );
- _Thread_queue_Extract( the_thread );
- the_thread->Wait.return_code= STATUS_NOT_OWNER;
+ _Thread_Continue( the_thread, STATUS_NOT_OWNER );
}
}
+static void _POSIX_Condition_variables_Enqueue_no_timeout(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+)
+{
+ _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
+}
+
+static void _POSIX_Condition_variables_Enqueue_with_timeout_monotonic(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Add_timeout_monotonic_timespec(
+ queue,
+ the_thread,
+ cpu_self,
+ queue_context
+ );
+ _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
+}
+
+static void _POSIX_Condition_variables_Enqueue_with_timeout_realtime(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Add_timeout_realtime_timespec(
+ queue,
+ the_thread,
+ cpu_self,
+ queue_context
+ );
+ _POSIX_Condition_variables_Mutex_unlock( queue, the_thread, queue_context );
+}
+
int _POSIX_Condition_variables_Wait_support(
pthread_cond_t *cond,
pthread_mutex_t *mutex,
@@ -59,44 +100,32 @@ int _POSIX_Condition_variables_Wait_support(
unsigned long flags;
Thread_queue_Context queue_context;
int error;
- int mutex_error;
Thread_Control *executing;
- Watchdog_Interval timeout;
- bool already_timedout;
- TOD_Absolute_timeout_conversion_results status;
the_cond = _POSIX_Condition_variables_Get( cond );
POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags );
_Thread_queue_Context_initialize( &queue_context );
- already_timedout = false;
if ( abstime != NULL ) {
- /*
- * 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.
- */
- status = _TOD_Absolute_timeout_to_ticks(
- abstime,
- _POSIX_Condition_variables_Get_clock( flags ),
- &timeout
- );
- if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
- return EINVAL;
+ _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
- if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
- status == TOD_ABSOLUTE_TIMEOUT_IS_NOW ) {
- already_timedout = true;
+ if ( _POSIX_Condition_variables_Get_clock( flags ) == CLOCK_MONOTONIC ) {
+ _Thread_queue_Context_set_enqueue_callout(
+ &queue_context,
+ _POSIX_Condition_variables_Enqueue_with_timeout_monotonic
+ );
} else {
- _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
+ _Thread_queue_Context_set_enqueue_callout(
+ &queue_context,
+ _POSIX_Condition_variables_Enqueue_with_timeout_realtime
+ );
}
} else {
- _Thread_queue_Context_set_no_timeout( &queue_context );
+ _Thread_queue_Context_set_enqueue_callout(
+ &queue_context,
+ _POSIX_Condition_variables_Enqueue_no_timeout
+ );
}
executing = _POSIX_Condition_variables_Acquire( the_cond, &queue_context );
@@ -111,32 +140,17 @@ int _POSIX_Condition_variables_Wait_support(
the_cond->mutex = mutex;
- if ( !already_timedout ) {
- _Thread_queue_Context_set_thread_state(
- &queue_context,
- STATES_WAITING_FOR_CONDITION_VARIABLE
- );
- _Thread_queue_Context_set_enqueue_callout(
- &queue_context,
- _POSIX_Condition_variables_Enqueue_callout
- );
- _Thread_queue_Enqueue(
- &the_cond->Queue.Queue,
- POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
- executing,
- &queue_context
- );
- error = _POSIX_Get_error_after_wait( executing );
- } else {
- _POSIX_Condition_variables_Release( the_cond, &queue_context );
-
- mutex_error = pthread_mutex_unlock( the_cond->mutex );
- if ( mutex_error != 0 ) {
- error = EPERM;
- } else {
- error = ETIMEDOUT;
- }
- }
+ _Thread_queue_Context_set_thread_state(
+ &queue_context,
+ STATES_WAITING_FOR_CONDITION_VARIABLE
+ );
+ _Thread_queue_Enqueue(
+ &the_cond->Queue.Queue,
+ POSIX_CONDITION_VARIABLES_TQ_OPERATIONS,
+ executing,
+ &queue_context
+ );
+ error = _POSIX_Get_error_after_wait( executing );
/*
* If the thread is interrupted, while in the thread queue, by
@@ -155,6 +169,8 @@ int _POSIX_Condition_variables_Wait_support(
*/
if ( error != EPERM ) {
+ int mutex_error;
+
mutex_error = pthread_mutex_lock( mutex );
if ( mutex_error != 0 ) {
_Assert( mutex_error == EINVAL );
diff --git a/cpukit/posix/src/mqueuereceive.c b/cpukit/posix/src/mqueuereceive.c
index 465cd79cec..c160634dc5 100644
--- a/cpukit/posix/src/mqueuereceive.c
+++ b/cpukit/posix/src/mqueuereceive.c
@@ -18,17 +18,6 @@
#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/mqueueimpl.h>
ssize_t mq_receive(
@@ -43,7 +32,7 @@ ssize_t mq_receive(
msg_ptr,
msg_len,
msg_prio,
- true,
- WATCHDOG_NO_TIMEOUT
+ NULL,
+ _Thread_queue_Enqueue_do_nothing_extra
);
}
diff --git a/cpukit/posix/src/mqueuerecvsupp.c b/cpukit/posix/src/mqueuerecvsupp.c
index 416e7989fd..c6d1805214 100644
--- a/cpukit/posix/src/mqueuerecvsupp.c
+++ b/cpukit/posix/src/mqueuerecvsupp.c
@@ -36,18 +36,17 @@ THREAD_QUEUE_OBJECT_ASSERT(
*/
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
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
)
{
POSIX_Message_queue_Control *the_mq;
Thread_queue_Context queue_context;
size_t length_out;
- bool do_wait;
Thread_Control *executing;
Status_Control status;
@@ -67,22 +66,15 @@ ssize_t _POSIX_Message_queue_Receive_support(
rtems_set_errno_and_return_minus_one( EMSGSIZE );
}
+ _Thread_queue_Context_set_enqueue_callout( &queue_context, enqueue_callout );
+ _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
+
/*
* 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->oflag & O_NONBLOCK ) == 0;
- } else {
- do_wait = wait;
- }
-
_CORE_message_queue_Acquire_critical(
&the_mq->Message_queue,
&queue_context
@@ -97,13 +89,12 @@ ssize_t _POSIX_Message_queue_Receive_support(
* Now perform the actual message receive
*/
executing = _Thread_Executing;
- _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
status = _CORE_message_queue_Seize(
&the_mq->Message_queue,
executing,
msg_ptr,
&length_out,
- do_wait,
+ ( the_mq->oflag & O_NONBLOCK ) == 0,
&queue_context
);
diff --git a/cpukit/posix/src/mqueuesend.c b/cpukit/posix/src/mqueuesend.c
index 6cf67cd3bb..4843ae073d 100644
--- a/cpukit/posix/src/mqueuesend.c
+++ b/cpukit/posix/src/mqueuesend.c
@@ -61,7 +61,7 @@ int mq_send(
msg_ptr,
msg_len,
msg_prio,
- true,
- WATCHDOG_NO_TIMEOUT
+ NULL,
+ _Thread_queue_Enqueue_do_nothing_extra
);
}
diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c
index c975a95505..a238991af5 100644
--- a/cpukit/posix/src/mqueuesendsupp.c
+++ b/cpukit/posix/src/mqueuesendsupp.c
@@ -35,18 +35,17 @@
#include <fcntl.h>
int _POSIX_Message_queue_Send_support(
- mqd_t mqdes,
- const char *msg_ptr,
- size_t msg_len,
- unsigned int msg_prio,
- bool wait,
- Watchdog_Interval timeout
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
)
{
POSIX_Message_queue_Control *the_mq;
Thread_queue_Context queue_context;
Status_Control status;
- bool do_wait;
Thread_Control *executing;
/*
@@ -69,14 +68,8 @@ int _POSIX_Message_queue_Send_support(
rtems_set_errno_and_return_minus_one( EBADF );
}
- /*
- * A timed receive with a bad time will do a poll regardless.
- */
- if ( wait ) {
- do_wait = ( the_mq->oflag & O_NONBLOCK ) == 0;
- } else {
- do_wait = wait;
- }
+ _Thread_queue_Context_set_enqueue_callout( &queue_context, enqueue_callout );
+ _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
_CORE_message_queue_Acquire_critical(
&the_mq->Message_queue,
@@ -92,14 +85,13 @@ int _POSIX_Message_queue_Send_support(
* Now perform the actual message receive
*/
executing = _Thread_Executing;
- _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
status = _CORE_message_queue_Submit(
&the_mq->Message_queue,
executing,
msg_ptr,
msg_len,
_POSIX_Message_queue_Priority_to_core( msg_prio ),
- do_wait,
+ ( the_mq->oflag & O_NONBLOCK ) == 0,
&queue_context
);
return _POSIX_Zero_or_minus_one_plus_errno( status );
diff --git a/cpukit/posix/src/mqueuetimedreceive.c b/cpukit/posix/src/mqueuetimedreceive.c
index f9b2730baa..fe9fc75053 100644
--- a/cpukit/posix/src/mqueuetimedreceive.c
+++ b/cpukit/posix/src/mqueuetimedreceive.c
@@ -32,17 +32,6 @@
#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/todimpl.h>
-#include <rtems/seterr.h>
#include <rtems/posix/mqueueimpl.h>
/*
@@ -59,33 +48,12 @@ ssize_t mq_timedreceive(
const struct timespec *__restrict abstime
)
{
- Watchdog_Interval ticks;
- bool do_wait = true;
- TOD_Absolute_timeout_conversion_results 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 TOD_ABSOLUTE_TIMEOUT_INVALID,
- * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
- * then we should not wait.
- */
- status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
- if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
- do_wait = false;
-
return _POSIX_Message_queue_Receive_support(
mqdes,
msg_ptr,
msg_len,
msg_prio,
- do_wait,
- ticks
+ abstime,
+ _Thread_queue_Add_timeout_realtime_timespec
);
}
diff --git a/cpukit/posix/src/mqueuetimedsend.c b/cpukit/posix/src/mqueuetimedsend.c
index 3920a3fcc1..5596517c78 100644
--- a/cpukit/posix/src/mqueuetimedsend.c
+++ b/cpukit/posix/src/mqueuetimedsend.c
@@ -18,17 +18,6 @@
#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/todimpl.h>
-#include <rtems/seterr.h>
#include <rtems/posix/mqueueimpl.h>
int mq_timedsend(
@@ -39,33 +28,12 @@ int mq_timedsend(
const struct timespec *abstime
)
{
- Watchdog_Interval ticks;
- bool do_wait = true;
- TOD_Absolute_timeout_conversion_results 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 TOD_ABSOLUTE_TIMEOUT_INVALID,
- * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
- * then we should not wait.
- */
- status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
- if ( status != TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE )
- do_wait = false;
-
return _POSIX_Message_queue_Send_support(
mqdes,
msg_ptr,
msg_len,
msg_prio,
- do_wait,
- ticks
+ abstime,
+ _Thread_queue_Add_timeout_realtime_timespec
);
}
diff --git a/cpukit/posix/src/mutexlock.c b/cpukit/posix/src/mutexlock.c
index d4cf4b74bd..35722fe96f 100644
--- a/cpukit/posix/src/mutexlock.c
+++ b/cpukit/posix/src/mutexlock.c
@@ -18,14 +18,7 @@
#include "config.h"
#endif
-#include <errno.h>
-#include <pthread.h>
-
-#include <rtems/system.h>
-#include <rtems/score/coremuteximpl.h>
-#include <rtems/score/watchdog.h>
#include <rtems/posix/muteximpl.h>
-#include <rtems/posix/priorityimpl.h>
/*
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
@@ -37,5 +30,9 @@ int pthread_mutex_lock(
pthread_mutex_t *mutex
)
{
- return _POSIX_Mutex_Lock_support( mutex, true, WATCHDOG_NO_TIMEOUT );
+ return _POSIX_Mutex_Lock_support(
+ mutex,
+ NULL,
+ _Thread_queue_Enqueue_do_nothing_extra
+ );
}
diff --git a/cpukit/posix/src/mutexlocksupp.c b/cpukit/posix/src/mutexlocksupp.c
index 4b0f366629..4530a6bea2 100644
--- a/cpukit/posix/src/mutexlocksupp.c
+++ b/cpukit/posix/src/mutexlocksupp.c
@@ -25,16 +25,15 @@ Status_Control _POSIX_Mutex_Seize_slow(
POSIX_Mutex_Control *the_mutex,
const Thread_queue_Operations *operations,
Thread_Control *executing,
- bool wait,
+ const struct timespec *abstime,
Thread_queue_Context *queue_context
)
{
- if ( wait ) {
+ if ( (uintptr_t) abstime != POSIX_MUTEX_ABSTIME_TRY_LOCK ) {
_Thread_queue_Context_set_thread_state(
queue_context,
STATES_WAITING_FOR_MUTEX
);
- _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context );
_Thread_queue_Context_set_deadlock_callout(
queue_context,
_Thread_queue_Deadlock_status
@@ -53,9 +52,9 @@ Status_Control _POSIX_Mutex_Seize_slow(
}
int _POSIX_Mutex_Lock_support(
- pthread_mutex_t *mutex,
- bool wait,
- Watchdog_Interval timeout
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
)
{
POSIX_Mutex_Control *the_mutex;
@@ -68,7 +67,8 @@ int _POSIX_Mutex_Lock_support(
POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags );
executing = _POSIX_Mutex_Acquire( the_mutex, &queue_context );
- _Thread_queue_Context_set_relative_timeout( &queue_context, timeout );
+ _Thread_queue_Context_set_enqueue_callout( &queue_context, enqueue_callout);
+ _Thread_queue_Context_set_timeout_argument( &queue_context, abstime );
switch ( _POSIX_Mutex_Get_protocol( flags ) ) {
case POSIX_MUTEX_PRIORITY_CEILING:
@@ -76,7 +76,7 @@ int _POSIX_Mutex_Lock_support(
the_mutex,
flags,
executing,
- wait,
+ abstime,
&queue_context
);
break;
@@ -86,7 +86,7 @@ int _POSIX_Mutex_Lock_support(
flags,
POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
executing,
- wait,
+ abstime,
&queue_context
);
break;
@@ -99,7 +99,7 @@ int _POSIX_Mutex_Lock_support(
flags,
POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS,
executing,
- wait,
+ abstime,
&queue_context
);
break;
diff --git a/cpukit/posix/src/mutextimedlock.c b/cpukit/posix/src/mutextimedlock.c
index cfc1827ae8..075417a3dd 100644
--- a/cpukit/posix/src/mutextimedlock.c
+++ b/cpukit/posix/src/mutextimedlock.c
@@ -18,14 +18,7 @@
#include "config.h"
#endif
-#include <errno.h>
-#include <pthread.h>
-
-#include <rtems/system.h>
-#include <rtems/score/coremuteximpl.h>
-#include <rtems/score/todimpl.h>
#include <rtems/posix/muteximpl.h>
-#include <rtems/posix/priorityimpl.h>
/**
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
@@ -37,42 +30,9 @@ int pthread_mutex_timedlock(
const struct timespec *abstime
)
{
- Watchdog_Interval ticks;
- bool do_wait = true;
- TOD_Absolute_timeout_conversion_results 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 TOD_ABSOLUTE_TIMEOUT_INVALID,
- * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
- * then we should not wait.
- */
- status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
- if ( status != TOD_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 == TOD_ABSOLUTE_TIMEOUT_INVALID )
- return EINVAL;
- if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST ||
- status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
- return ETIMEDOUT;
- }
-
- return lock_status;
+ return _POSIX_Mutex_Lock_support(
+ mutex,
+ abstime,
+ _Thread_queue_Add_timeout_realtime_timespec
+ );
}
diff --git a/cpukit/posix/src/mutextrylock.c b/cpukit/posix/src/mutextrylock.c
index d029ae5de6..895f38fa44 100644
--- a/cpukit/posix/src/mutextrylock.c
+++ b/cpukit/posix/src/mutextrylock.c
@@ -18,14 +18,7 @@
#include "config.h"
#endif
-#include <errno.h>
-#include <pthread.h>
-
-#include <rtems/system.h>
-#include <rtems/score/coremuteximpl.h>
-#include <rtems/score/watchdog.h>
#include <rtems/posix/muteximpl.h>
-#include <rtems/posix/priorityimpl.h>
/**
* 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93
@@ -36,8 +29,17 @@ int pthread_mutex_trylock(
pthread_mutex_t *mutex
)
{
- int r = _POSIX_Mutex_Lock_support( mutex, false, WATCHDOG_NO_TIMEOUT );
- if ( r == EDEADLK )
- r = EBUSY;
- return r;
+ int eno;
+
+ eno = _POSIX_Mutex_Lock_support(
+ mutex,
+ (const struct timespec *) POSIX_MUTEX_ABSTIME_TRY_LOCK,
+ NULL
+ );
+
+ if ( eno == EDEADLK ) {
+ eno = EBUSY;
+ }
+
+ return eno;
}
diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c
index e8a7fe14c1..f65c91bc17 100644
--- a/cpukit/posix/src/nanosleep.c
+++ b/cpukit/posix/src/nanosleep.c
@@ -21,100 +21,18 @@
#endif
#include <time.h>
-#include <errno.h>
-#include <rtems/seterr.h>
#include <rtems/score/threadimpl.h>
#include <rtems/score/threadqimpl.h>
#include <rtems/score/timespec.h>
+#include <rtems/score/todimpl.h>
#include <rtems/score/watchdogimpl.h>
+#include <rtems/posix/posixapi.h>
+#include <rtems/seterr.h>
static Thread_queue_Control _Nanosleep_Pseudo_queue =
THREAD_QUEUE_INITIALIZER( "Nanosleep" );
-static inline int nanosleep_helper(
- clockid_t clock_id,
- uint64_t ticks,
- struct timespec *timeout,
- struct timespec *rmtp,
- Watchdog_Discipline discipline
-)
-{
- Thread_queue_Context queue_context;
- struct timespec stop;
- int err;
-
- err = 0;
-
- _Thread_queue_Context_initialize( &queue_context );
- _Thread_queue_Context_set_thread_state(
- &queue_context,
- STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
- );
- _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
-
- if ( discipline == WATCHDOG_ABSOLUTE ) {
- _Thread_queue_Context_set_absolute_timeout( &queue_context, ticks );
- } else {
- _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
- }
-
- /*
- * Block for the desired amount of time
- */
- _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
- _Thread_queue_Enqueue(
- &_Nanosleep_Pseudo_queue.Queue,
- &_Thread_queue_Operations_FIFO,
- _Thread_Executing,
- &queue_context
- );
-
- clock_gettime( clock_id, &stop );
- /*
- * If the user wants the time remaining, do the conversion.
- */
- if ( _Timespec_Less_than( &stop, timeout ) ) {
- /*
- * If there is time remaining, then we were interrupted by a signal.
- */
- err = EINTR;
- if ( rmtp != NULL ) {
- _Timespec_Subtract( &stop, timeout, rmtp );
- }
- } else if ( rmtp != NULL ) {
- /* no time remaining */
- _Timespec_Set_to_zero( rmtp );
- }
-
- return err;
-}
-
-/*
- * 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.
- */
-static inline int nanosleep_yield( struct timespec *rmtp )
-{
- /*
- * It is critical to obtain the executing thread after thread dispatching is
- * disabled on SMP configurations.
- */
- Thread_Control *executing;
- Per_CPU_Control *cpu_self;
-
- executing = _Thread_Get_executing();
- cpu_self = _Thread_Dispatch_disable();
- _Thread_Yield( executing );
- _Thread_Dispatch_direct( cpu_self );
- if ( rmtp ) {
- rmtp->tv_sec = 0;
- rmtp->tv_nsec = 0;
- }
- return 0;
-}
-
/*
* 14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
*/
@@ -123,43 +41,15 @@ int nanosleep(
struct timespec *rmtp
)
{
- int err;
- struct timespec now;
- uint64_t ticks;
- Watchdog_Interval relative_interval;
-
- /*
- * 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 );
- }
+ int eno;
- relative_interval = _Timespec_To_ticks( rqtp );
- if ( relative_interval == 0 )
- return nanosleep_yield( rmtp );
-
- /* CLOCK_REALTIME can be adjusted during the timeout,
- * so convert to an absolute timeout value and put the
- * thread on the WATCHDOG_ABSOLUTE threadq. */
- err = clock_gettime( CLOCK_REALTIME, &now );
- if ( err != 0 )
- return -1;
- _Timespec_Add_to( &now, rqtp );
- ticks = _Watchdog_Realtime_from_timespec( &now );
- err = nanosleep_helper( CLOCK_REALTIME,
- ticks,
- &now,
- rmtp,
- WATCHDOG_ABSOLUTE
- );
- if ( err != 0 ) {
- rtems_set_errno_and_return_minus_one( err );
+ eno = clock_nanosleep( CLOCK_REALTIME, 0, rqtp, rmtp );
+
+ if ( eno != 0 ) {
+ rtems_set_errno_and_return_minus_one( eno );
}
- return 0;
+
+ return eno;
}
/*
@@ -172,59 +62,82 @@ int clock_nanosleep(
struct timespec *rmtp
)
{
- int err = 0;
- struct timespec timeout;
- uint64_t ticks;
- Watchdog_Interval relative_interval;
- TOD_Absolute_timeout_conversion_results status;
-
- if ( !_Timespec_Is_valid( rqtp ) )
- return EINVAL;
-
- /* get relative ticks of the requested timeout */
- if ( flags & TIMER_ABSTIME ) {
- /* See if absolute time already passed */
- status = _TOD_Absolute_timeout_to_ticks(rqtp, clock_id, &relative_interval);
- if ( status == TOD_ABSOLUTE_TIMEOUT_INVALID )
- return EINVAL;
- if ( status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST )
- return 0;
- if ( status == TOD_ABSOLUTE_TIMEOUT_IS_NOW )
- return nanosleep_yield( NULL );
- rmtp = NULL; /* Do not touch rmtp when using absolute time */
- timeout.tv_sec = 0;
- timeout.tv_nsec = 0;
+ Thread_queue_Context queue_context;
+ struct timespec spare_end;
+ const struct timespec *end;
+ Thread_Control *executing;
+ int eno;
+
+ if ( clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC ) {
+ return ENOTSUP;
+ }
+
+ _Thread_queue_Context_initialize( &queue_context );
+ _Thread_queue_Context_set_thread_state(
+ &queue_context,
+ STATES_WAITING_FOR_TIME | STATES_INTERRUPTIBLE_BY_SIGNAL
+ );
+
+ if ( ( flags & TIMER_ABSTIME ) != 0 ) {
+ end = rqtp;
+
+ if ( clock_id == CLOCK_REALTIME ) {
+ _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+ &queue_context,
+ end
+ );
+ } else {
+ _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
+ &queue_context,
+ end
+ );
+ }
} else {
- /* prepare to convert relative ticks to absolute timeout */
- err = clock_gettime( clock_id, &timeout );
- if ( err != 0 )
+ if ( !_Watchdog_Is_valid_interval_timespec( rqtp ) ) {
return EINVAL;
- relative_interval = _Timespec_To_ticks( rqtp );
- }
- if ( relative_interval == 0 )
- return nanosleep_yield( rmtp );
-
- _Timespec_Add_to( &timeout, rqtp );
- if ( clock_id == CLOCK_REALTIME ) {
- ticks = _Watchdog_Realtime_from_timespec( &timeout );
- err = nanosleep_helper(
- clock_id,
- ticks,
- &timeout,
- rmtp,
- WATCHDOG_ABSOLUTE
- );
- } else if ( clock_id == CLOCK_MONOTONIC ) {
- /* use the WATCHDOG_RELATIVE to ignore changes in wall time */
- err = nanosleep_helper(
- clock_id,
- relative_interval,
- &timeout,
- rmtp,
- WATCHDOG_RELATIVE
+ }
+
+ _TOD_Get_zero_based_uptime_as_timespec( &spare_end );
+
+ /* In case this overflows, then the enqueue callout will reject it */
+ _Timespec_Add_to( &spare_end, rqtp );
+
+ end = &spare_end;
+ _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
+ &queue_context,
+ end
);
- } else {
- err = ENOTSUP;
}
- return err;
+
+ _Thread_queue_Acquire( &_Nanosleep_Pseudo_queue, &queue_context );
+ executing = _Thread_Executing;
+ _Thread_queue_Enqueue(
+ &_Nanosleep_Pseudo_queue.Queue,
+ &_Thread_queue_Operations_FIFO,
+ executing,
+ &queue_context
+ );
+ eno = _POSIX_Get_error_after_wait( executing );
+
+ if ( eno == ETIMEDOUT ) {
+ eno = 0;
+ }
+
+ if ( rmtp != NULL && ( flags & TIMER_ABSTIME ) == 0 ) {
+ if ( eno == EINTR ) {
+ struct timespec actual_end;
+
+ _TOD_Get_zero_based_uptime_as_timespec( &actual_end );
+
+ if ( _Timespec_Less_than( &actual_end, end ) ) {
+ _Timespec_Subtract( &actual_end, end, rmtp );
+ } else {
+ _Timespec_Set_to_zero( rmtp );
+ }
+ } else {
+ _Timespec_Set_to_zero( rmtp );
+ }
+ }
+
+ return eno;
}
diff --git a/cpukit/posix/src/pbarrierwait.c b/cpukit/posix/src/pbarrierwait.c
index b9785216b4..75d9437774 100644
--- a/cpukit/posix/src/pbarrierwait.c
+++ b/cpukit/posix/src/pbarrierwait.c
@@ -54,7 +54,6 @@ int pthread_barrier_wait( pthread_barrier_t *_barrier )
STATES_WAITING_FOR_BARRIER
);
_Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
- _Thread_queue_Context_set_no_timeout( &queue_context );
_Thread_queue_Enqueue(
&barrier->Queue.Queue,
POSIX_BARRIER_TQ_OPERATIONS,
diff --git a/cpukit/posix/src/prwlockrdlock.c b/cpukit/posix/src/prwlockrdlock.c
index 4019c1fcb2..38c2981076 100644
--- a/cpukit/posix/src/prwlockrdlock.c
+++ b/cpukit/posix/src/prwlockrdlock.c
@@ -33,7 +33,7 @@ int pthread_rwlock_rdlock(
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
_Thread_queue_Context_initialize( &queue_context );
- _Thread_queue_Context_set_no_timeout( &queue_context );
+ _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
status = _CORE_RWLock_Seize_for_reading(
&the_rwlock->RWLock,
true, /* we are willing to wait forever */
diff --git a/cpukit/posix/src/prwlocktimedrdlock.c b/cpukit/posix/src/prwlocktimedrdlock.c
index a9ac13348d..47c76d9136 100644
--- a/cpukit/posix/src/prwlocktimedrdlock.c
+++ b/cpukit/posix/src/prwlocktimedrdlock.c
@@ -20,59 +20,28 @@
#include <rtems/posix/rwlockimpl.h>
#include <rtems/posix/posixapi.h>
-#include <rtems/score/todimpl.h>
int pthread_rwlock_timedrdlock(
pthread_rwlock_t *rwlock,
const struct timespec *abstime
)
{
- POSIX_RWLock_Control *the_rwlock;
- Thread_queue_Context queue_context;
- Watchdog_Interval ticks;
- bool do_wait;
- TOD_Absolute_timeout_conversion_results timeout_status;
- Status_Control 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 STATUS_UNAVAILABLE
- * status into the appropriate error.
- *
- * If the timeout status is TOD_ABSOLUTE_TIMEOUT_INVALID,
- * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
- * then we should not wait.
- */
- timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
- do_wait = ( timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
+ POSIX_RWLock_Control *the_rwlock;
+ Thread_queue_Context queue_context;
+ Status_Control status;
the_rwlock = _POSIX_RWLock_Get( rwlock );
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
_Thread_queue_Context_initialize( &queue_context );
- _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
+ _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+ &queue_context,
+ abstime
+ );
status = _CORE_RWLock_Seize_for_reading(
&the_rwlock->RWLock,
- do_wait,
+ true,
&queue_context
);
-
- if ( !do_wait && status == STATUS_UNAVAILABLE ) {
- if ( timeout_status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
- return EINVAL;
- }
-
- if (
- timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
- || timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
- ) {
- return ETIMEDOUT;
- }
- }
-
return _POSIX_Get_error( status );
}
diff --git a/cpukit/posix/src/prwlocktimedwrlock.c b/cpukit/posix/src/prwlocktimedwrlock.c
index 1f1e654d53..a48f0e665c 100644
--- a/cpukit/posix/src/prwlocktimedwrlock.c
+++ b/cpukit/posix/src/prwlocktimedwrlock.c
@@ -22,59 +22,28 @@
#include <rtems/posix/rwlockimpl.h>
#include <rtems/posix/posixapi.h>
-#include <rtems/score/todimpl.h>
int pthread_rwlock_timedwrlock(
pthread_rwlock_t *rwlock,
const struct timespec *abstime
)
{
- POSIX_RWLock_Control *the_rwlock;
- Thread_queue_Context queue_context;
- Watchdog_Interval ticks;
- bool do_wait;
- TOD_Absolute_timeout_conversion_results timeout_status;
- Status_Control 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 STATUS_UNAVAILABLE
- * status into the appropriate error.
- *
- * If the timeout status is TOD_ABSOLUTE_TIMEOUT_INVALID,
- * TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, or TOD_ABSOLUTE_TIMEOUT_IS_NOW,
- * then we should not wait.
- */
- timeout_status = _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks );
- do_wait = ( timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE );
+ POSIX_RWLock_Control *the_rwlock;
+ Thread_queue_Context queue_context;
+ Status_Control status;
the_rwlock = _POSIX_RWLock_Get( rwlock );
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
_Thread_queue_Context_initialize( &queue_context );
- _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
+ _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+ &queue_context,
+ abstime
+ );
status = _CORE_RWLock_Seize_for_writing(
&the_rwlock->RWLock,
- do_wait,
+ true,
&queue_context
);
-
- if ( !do_wait && status == STATUS_UNAVAILABLE ) {
- if ( timeout_status == TOD_ABSOLUTE_TIMEOUT_INVALID ) {
- return EINVAL;
- }
-
- if (
- timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST
- || timeout_status == TOD_ABSOLUTE_TIMEOUT_IS_NOW
- ) {
- return ETIMEDOUT;
- }
- }
-
return _POSIX_Get_error( status );
}
diff --git a/cpukit/posix/src/prwlockwrlock.c b/cpukit/posix/src/prwlockwrlock.c
index df4d2685aa..eae10ba375 100644
--- a/cpukit/posix/src/prwlockwrlock.c
+++ b/cpukit/posix/src/prwlockwrlock.c
@@ -35,7 +35,7 @@ int pthread_rwlock_wrlock(
POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
_Thread_queue_Context_initialize( &queue_context );
- _Thread_queue_Context_set_no_timeout( &queue_context );
+ _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
status = _CORE_RWLock_Seize_for_writing(
&the_rwlock->RWLock,
true, /* do not timeout -- wait forever */
diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c
index b6981fd9b3..ce4bf0d049 100644
--- a/cpukit/posix/src/pthreadjoin.c
+++ b/cpukit/posix/src/pthreadjoin.c
@@ -40,7 +40,6 @@ static int _POSIX_Threads_Join( pthread_t thread, void **value_ptr )
_Thread_queue_Context_initialize( &queue_context );
_Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
- _Thread_queue_Context_set_no_timeout( &queue_context );
the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context );
if ( the_thread == NULL ) {
diff --git a/cpukit/posix/src/semtimedwait.c b/cpukit/posix/src/semtimedwait.c
index 90e6866341..9e7bb466dd 100644
--- a/cpukit/posix/src/semtimedwait.c
+++ b/cpukit/posix/src/semtimedwait.c
@@ -51,29 +51,16 @@ int sem_timedwait(
_Sem_Queue_release( sem, level, &queue_context );
return 0;
} else {
- Watchdog_Interval ticks;
- Status_Control status;
-
- switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) {
- case TOD_ABSOLUTE_TIMEOUT_INVALID:
- _Sem_Queue_release( sem, level, &queue_context );
- rtems_set_errno_and_return_minus_one( EINVAL );
- break;
- case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST:
- case TOD_ABSOLUTE_TIMEOUT_IS_NOW:
- _Sem_Queue_release( sem, level, &queue_context );
- rtems_set_errno_and_return_minus_one( ETIMEDOUT );
- break;
- default:
- break;
- }
+ Status_Control status;
_Thread_queue_Context_set_thread_state(
&queue_context,
STATES_WAITING_FOR_SEMAPHORE
);
- _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
- _Thread_queue_Context_set_relative_timeout( &queue_context, ticks );
+ _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+ &queue_context,
+ abstime
+ );
_Thread_queue_Context_set_ISR_level( &queue_context, level );
_Thread_queue_Enqueue(
&sem->Queue.Queue,
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
index 70170bf2f7..a0e18adef0 100644
--- a/cpukit/posix/src/sigtimedwait.c
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -24,6 +24,8 @@
#include <rtems/posix/psignalimpl.h>
#include <rtems/posix/posixapi.h>
#include <rtems/score/threadqimpl.h>
+#include <rtems/score/todimpl.h>
+#include <rtems/score/watchdogimpl.h>
#include <rtems/score/isr.h>
static int _POSIX_signals_Get_lowest(
@@ -89,20 +91,24 @@ int sigtimedwait(
* in the Open Group specification.
*/
- if ( timeout ) {
- Watchdog_Interval interval;
+ if ( timeout != NULL ) {
+ struct timespec end;
- if ( !_Timespec_Is_valid( timeout ) )
- rtems_set_errno_and_return_minus_one( EINVAL );
+ if ( !_Watchdog_Is_valid_interval_timespec( timeout ) ) {
+ return EINVAL;
+ }
- interval = _Timespec_To_ticks( timeout );
+ _TOD_Get_zero_based_uptime_as_timespec( &end );
- if ( !interval )
- rtems_set_errno_and_return_minus_one( EINVAL );
+ /* In case this overflows, then the enqueue callout will reject it */
+ _Timespec_Add_to( &end, timeout );
- _Thread_queue_Context_set_relative_timeout( &queue_context, interval );
+ _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
+ &queue_context,
+ &end
+ );
} else {
- _Thread_queue_Context_set_no_timeout( &queue_context );
+ _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
}
/*
@@ -160,7 +166,6 @@ int sigtimedwait(
&queue_context,
STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL
);
- _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
_Thread_queue_Enqueue(
&_POSIX_signals_Wait_queue.Queue,
POSIX_SIGNALS_TQ_OPERATIONS,