mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 23:23:13 +00:00
2008-07-24 Joel Sherrill <joel.sherrill@OARcorp.com>
PR 1291/cpukit * posix/src/posixtimespecabsolutetimeout.c: New file. * itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, posix/Makefile.am, posix/include/mqueue.h, posix/include/rtems/posix/mqueue.h, posix/include/rtems/posix/semaphore.h, posix/include/rtems/posix/time.h, posix/src/condtimedwait.c, posix/src/mqueuereceive.c, posix/src/mqueuerecvsupp.c, posix/src/mqueuesend.c, posix/src/mqueuesendsupp.c, posix/src/mqueuetimedreceive.c, posix/src/mqueuetimedsend.c, posix/src/mutexfromcorestatus.c, posix/src/mutextimedlock.c, posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, posix/src/semtrywait.c, posix/src/semwait.c, rtems/src/semobtain.c, rtems/src/semtranslatereturncode.c, score/include/rtems/score/coresem.h, score/src/coremsgseize.c, score/src/coresemseize.c: This patch addresses issues on implementation of the timeout on the following POSIX services. Some of these services incorrectly took a timeout as a relative time. Others would compute a 0 delta to timeout if the absolute time and the current time were equal and thus incorrectly block the caller forever. The root of the confusion is that POSIX specifies that if the timeout is incorrect (e.g. in the past, is now, or is numerically invalid), that it does not matter if the call would succeed without blocking. This is in contrast to RTEMS programming style where all errors are checked before any critical sections are entered. This fix implemented a more uniform way of handling POSIX absolute time timeouts. + pthread_cond_timedwait - could block forever + mq_timedreceive - used relative not absolute time + mq_timedsend - used relative not absolute time + pthread_mutex_timedlock - used relative not absolute time + pthread_rwlock_timedrdlock- used relative not absolute time + pthread_rwlock_timedwrlock- used relative not absolute time + sem_timedwait - could block forever
This commit is contained in:
@@ -1,3 +1,40 @@
|
|||||||
|
2008-07-24 Joel Sherrill <joel.sherrill@OARcorp.com>
|
||||||
|
|
||||||
|
PR 1291/cpukit
|
||||||
|
* posix/src/posixtimespecabsolutetimeout.c: New file.
|
||||||
|
* itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c,
|
||||||
|
posix/Makefile.am, posix/include/mqueue.h,
|
||||||
|
posix/include/rtems/posix/mqueue.h,
|
||||||
|
posix/include/rtems/posix/semaphore.h,
|
||||||
|
posix/include/rtems/posix/time.h, posix/src/condtimedwait.c,
|
||||||
|
posix/src/mqueuereceive.c, posix/src/mqueuerecvsupp.c,
|
||||||
|
posix/src/mqueuesend.c, posix/src/mqueuesendsupp.c,
|
||||||
|
posix/src/mqueuetimedreceive.c, posix/src/mqueuetimedsend.c,
|
||||||
|
posix/src/mutexfromcorestatus.c, posix/src/mutextimedlock.c,
|
||||||
|
posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c,
|
||||||
|
posix/src/semtrywait.c, posix/src/semwait.c, rtems/src/semobtain.c,
|
||||||
|
rtems/src/semtranslatereturncode.c,
|
||||||
|
score/include/rtems/score/coresem.h, score/src/coremsgseize.c,
|
||||||
|
score/src/coresemseize.c:
|
||||||
|
This patch addresses issues on implementation of the timeout on the
|
||||||
|
following POSIX services. Some of these services incorrectly took a
|
||||||
|
timeout as a relative time. Others would compute a 0 delta to timeout
|
||||||
|
if the absolute time and the current time were equal and thus
|
||||||
|
incorrectly block the caller forever. The root of the confusion is
|
||||||
|
that POSIX specifies that if the timeout is incorrect (e.g. in the
|
||||||
|
past, is now, or is numerically invalid), that it does not matter if
|
||||||
|
the call would succeed without blocking. This is in contrast to RTEMS
|
||||||
|
programming style where all errors are checked before any critical
|
||||||
|
sections are entered. This fix implemented a more uniform way of
|
||||||
|
handling POSIX absolute time timeouts.
|
||||||
|
+ pthread_cond_timedwait - could block forever
|
||||||
|
+ mq_timedreceive - used relative not absolute time
|
||||||
|
+ mq_timedsend - used relative not absolute time
|
||||||
|
+ pthread_mutex_timedlock - used relative not absolute time
|
||||||
|
+ pthread_rwlock_timedrdlock- used relative not absolute time
|
||||||
|
+ pthread_rwlock_timedwrlock- used relative not absolute time
|
||||||
|
+ sem_timedwait - could block forever
|
||||||
|
|
||||||
2008-04-25 Joel Sherrill <joel.sherrill@OARcorp.com>
|
2008-04-25 Joel Sherrill <joel.sherrill@OARcorp.com>
|
||||||
|
|
||||||
* score/include/rtems/system.h: Fix typo in comment.
|
* score/include/rtems/system.h: Fix typo in comment.
|
||||||
|
|||||||
@@ -172,8 +172,6 @@ RTEMS_INLINE_ROUTINE ER _ITRON_Semaphore_Translate_core_semaphore_return_code (
|
|||||||
return E_TMOUT;
|
return E_TMOUT;
|
||||||
case CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED:
|
case CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED:
|
||||||
return E_QOVR;
|
return E_QOVR;
|
||||||
case CORE_SEMAPHORE_BAD_TIMEOUT_VALUE:
|
|
||||||
return E_PAR;
|
|
||||||
case THREAD_STATUS_PROXY_BLOCKING:
|
case THREAD_STATUS_PROXY_BLOCKING:
|
||||||
return THREAD_STATUS_PROXY_BLOCKING;
|
return THREAD_STATUS_PROXY_BLOCKING;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ ER twai_sem(
|
|||||||
ITRON_Semaphore_Control *the_semaphore;
|
ITRON_Semaphore_Control *the_semaphore;
|
||||||
Objects_Locations location;
|
Objects_Locations location;
|
||||||
Watchdog_Interval interval;
|
Watchdog_Interval interval;
|
||||||
Core_semaphore_Blocking_option blocking;
|
boolean blocking;
|
||||||
|
|
||||||
interval = 0;
|
interval = 0;
|
||||||
if ( tmout == TMO_POL ) {
|
if ( tmout == TMO_POL ) {
|
||||||
blocking = CORE_SEMAPHORE_NO_WAIT;
|
blocking = FALSE;
|
||||||
} else {
|
} else {
|
||||||
blocking = CORE_SEMAPHORE_BLOCK_FOREVER;
|
blocking = TRUE;
|
||||||
|
|
||||||
if ( tmout != TMO_FEVR )
|
if ( tmout != TMO_FEVR )
|
||||||
interval = TOD_MILLISECONDS_TO_TICKS(tmout);
|
interval = TOD_MILLISECONDS_TO_TICKS(tmout);
|
||||||
|
|||||||
@@ -132,10 +132,11 @@ libposix_a_SOURCES += src/semaphore.c src/semaphorecreatesupp.c \
|
|||||||
|
|
||||||
## TIME_C_FILES
|
## TIME_C_FILES
|
||||||
libposix_a_SOURCES += src/adjtime.c src/time.c src/posixtimespecsubtract.c \
|
libposix_a_SOURCES += src/adjtime.c src/time.c src/posixtimespecsubtract.c \
|
||||||
src/posixtimespectointerval.c src/posixintervaltotimespec.c \
|
src/posixtimespecabsolutetimeout.c src/posixtimespectointerval.c \
|
||||||
src/clockgetcpuclockid.c src/clockgetenableattr.c src/clockgetres.c \
|
src/posixintervaltotimespec.c src/clockgetcpuclockid.c \
|
||||||
src/clockgettime.c src/clocksetenableattr.c src/clocksettime.c \
|
src/clockgetenableattr.c src/clockgetres.c src/clockgettime.c \
|
||||||
src/nanosleep.c src/sleep.c src/usleep.c
|
src/clocksetenableattr.c src/clocksettime.c src/nanosleep.c src/sleep.c \
|
||||||
|
src/usleep.c
|
||||||
|
|
||||||
# the timer manager needs to be split further but only after its
|
# the timer manager needs to be split further but only after its
|
||||||
# dependence on the Classic API Timer Manager is removed.
|
# dependence on the Classic API Timer Manager is removed.
|
||||||
|
|||||||
@@ -26,47 +26,53 @@ extern "C" {
|
|||||||
* 15.1.1 Data Structures, P1003.1b-1993, p. 271
|
* 15.1.1 Data Structures, P1003.1b-1993, p. 271
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message queue id type
|
||||||
|
*/
|
||||||
typedef Objects_Id mqd_t;
|
typedef Objects_Id mqd_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the message queue attributes structure.
|
||||||
|
*/
|
||||||
struct mq_attr {
|
struct mq_attr {
|
||||||
long mq_flags; /* Message queue flags */
|
/** This is the message queue flags */
|
||||||
long mq_maxmsg; /* Maximum number of messages */
|
long mq_flags;
|
||||||
long mq_msgsize; /* Maximum message size */
|
/** This is the maximum number of messages */
|
||||||
long mq_curmsgs; /* Number of messages currently queued */
|
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
|
* 15.2.2 Open a Message Queue, P1003.1b-1993, p. 272
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mqd_t mq_open(
|
mqd_t mq_open(
|
||||||
const char *name,
|
const char *name,
|
||||||
int oflag,
|
int oflag,
|
||||||
...
|
...
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
|
* 15.2.2 Close a Message Queue, P1003.1b-1993, p. 275
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mq_close(
|
int mq_close(
|
||||||
mqd_t mqdes
|
mqd_t mqdes
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
|
* 15.2.2 Remove a Message Queue, P1003.1b-1993, p. 276
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mq_unlink(
|
int mq_unlink(
|
||||||
const char *name
|
const char *name
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
* 15.2.4 Send a Message to a Message Queue, P1003.1b-1993, p. 277
|
||||||
*
|
*
|
||||||
* NOTE: P1003.4b/D8, p. 45 adds mq_timedsend().
|
* @note P1003.4b/D8, p. 45 adds mq_timedsend().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mq_send(
|
int mq_send(
|
||||||
mqd_t mqdes,
|
mqd_t mqdes,
|
||||||
const char *msg_ptr,
|
const char *msg_ptr,
|
||||||
@@ -83,7 +89,7 @@ int mq_timedsend(
|
|||||||
const char *msg_ptr,
|
const char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
unsigned int msg_prio,
|
unsigned int msg_prio,
|
||||||
const struct timespec *timeout
|
const struct timespec *abstime
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif /* _POSIX_TIMEOUTS */
|
#endif /* _POSIX_TIMEOUTS */
|
||||||
@@ -108,7 +114,7 @@ ssize_t mq_timedreceive(
|
|||||||
char *msg_ptr,
|
char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
unsigned int *msg_prio,
|
unsigned int *msg_prio,
|
||||||
const struct timespec *timeout
|
const struct timespec *abstime
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif /* _POSIX_TIMEOUTS */
|
#endif /* _POSIX_TIMEOUTS */
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ ssize_t _POSIX_Message_queue_Receive_support(
|
|||||||
char *msg_ptr,
|
char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
unsigned int *msg_prio,
|
unsigned int *msg_prio,
|
||||||
|
boolean wait,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -128,6 +129,7 @@ int _POSIX_Message_queue_Send_support(
|
|||||||
const char *msg_ptr,
|
const char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
uint32_t msg_prio,
|
uint32_t msg_prio,
|
||||||
|
boolean wait,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ void _POSIX_Semaphore_Delete(
|
|||||||
|
|
||||||
int _POSIX_Semaphore_Wait_support(
|
int _POSIX_Semaphore_Wait_support(
|
||||||
sem_t *sem,
|
sem_t *sem,
|
||||||
Core_semaphore_Blocking_option blocking,
|
boolean blocking,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,23 @@
|
|||||||
|
|
||||||
#include <rtems/score/tod.h>
|
#include <rtems/score/tod.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Seconds from January 1, 1970 to January 1, 1988. Used to account for
|
* Seconds from January 1, 1970 to January 1, 1988. Used to account for
|
||||||
* differences between POSIX API and RTEMS core.
|
* differences between POSIX API and RTEMS core.
|
||||||
@@ -51,4 +68,24 @@ void _POSIX_Interval_to_timespec(
|
|||||||
struct timespec *time
|
struct timespec *time
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* abstime - is the timeout
|
||||||
|
* ticks_out - will contain the number of ticks
|
||||||
|
*
|
||||||
|
* 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
|
#endif
|
||||||
|
|||||||
@@ -28,34 +28,34 @@ int pthread_cond_timedwait(
|
|||||||
const struct timespec *abstime
|
const struct timespec *abstime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Watchdog_Interval timeout;
|
Watchdog_Interval ticks;
|
||||||
struct timespec current_time;
|
boolean already_timedout;
|
||||||
struct timespec difference;
|
|
||||||
boolean already_timedout = FALSE;
|
|
||||||
|
|
||||||
if ( !abstime )
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The abstime is a walltime. We turn it into an interval.
|
* 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.
|
||||||
*/
|
*/
|
||||||
|
switch ( _POSIX_Absolute_timeout_to_ticks(abstime, &ticks) ) {
|
||||||
(void) clock_gettime( CLOCK_REALTIME, ¤t_time );
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
|
return EINVAL;
|
||||||
/* XXX probably some error checking should go here */
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
_POSIX_Timespec_subtract( ¤t_time, abstime, &difference );
|
|
||||||
|
|
||||||
if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&
|
|
||||||
( difference.tv_nsec < 0 ) ) )
|
|
||||||
already_timedout = TRUE;
|
already_timedout = TRUE;
|
||||||
|
break;
|
||||||
timeout = _POSIX_Timespec_to_interval( &difference );
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
|
already_timedout = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return _POSIX_Condition_variables_Wait_support(
|
return _POSIX_Condition_variables_Wait_support(
|
||||||
cond,
|
cond,
|
||||||
mutex,
|
mutex,
|
||||||
timeout,
|
ticks,
|
||||||
already_timedout
|
already_timedout
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ ssize_t mq_receive(
|
|||||||
msg_ptr,
|
msg_ptr,
|
||||||
msg_len,
|
msg_len,
|
||||||
msg_prio,
|
msg_prio,
|
||||||
|
TRUE,
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
THREAD_QUEUE_WAIT_FOREVER
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,7 @@
|
|||||||
#include <rtems/posix/mqueue.h>
|
#include <rtems/posix/mqueue.h>
|
||||||
#include <rtems/posix/time.h>
|
#include <rtems/posix/time.h>
|
||||||
|
|
||||||
/*PAGE
|
/*
|
||||||
*
|
|
||||||
* _POSIX_Message_queue_Receive_support
|
* _POSIX_Message_queue_Receive_support
|
||||||
*
|
*
|
||||||
* NOTE: XXX Document how size, priority, length, and the buffer go
|
* NOTE: XXX Document how size, priority, length, and the buffer go
|
||||||
@@ -45,6 +44,7 @@ ssize_t _POSIX_Message_queue_Receive_support(
|
|||||||
char *msg_ptr,
|
char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
unsigned int *msg_prio,
|
unsigned int *msg_prio,
|
||||||
|
boolean wait,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -52,6 +52,7 @@ ssize_t _POSIX_Message_queue_Receive_support(
|
|||||||
POSIX_Message_queue_Control_fd *the_mq_fd;
|
POSIX_Message_queue_Control_fd *the_mq_fd;
|
||||||
Objects_Locations location;
|
Objects_Locations location;
|
||||||
size_t length_out;
|
size_t length_out;
|
||||||
|
boolean do_wait;
|
||||||
|
|
||||||
the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
|
the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location );
|
||||||
switch ( location ) {
|
switch ( location ) {
|
||||||
@@ -81,12 +82,23 @@ ssize_t _POSIX_Message_queue_Receive_support(
|
|||||||
|
|
||||||
length_out = -1;
|
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(
|
_CORE_message_queue_Seize(
|
||||||
&the_mq->Message_queue,
|
&the_mq->Message_queue,
|
||||||
mqdes,
|
mqdes,
|
||||||
msg_ptr,
|
msg_ptr,
|
||||||
&length_out,
|
&length_out,
|
||||||
(the_mq_fd->oflag & O_NONBLOCK) ? FALSE : TRUE,
|
do_wait,
|
||||||
timeout
|
timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ int mq_send(
|
|||||||
msg_ptr,
|
msg_ptr,
|
||||||
msg_len,
|
msg_len,
|
||||||
msg_prio,
|
msg_prio,
|
||||||
|
TRUE,
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
THREAD_QUEUE_WAIT_FOREVER
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ int _POSIX_Message_queue_Send_support(
|
|||||||
const char *msg_ptr,
|
const char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
uint32_t msg_prio,
|
uint32_t msg_prio,
|
||||||
|
boolean wait,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -50,6 +51,7 @@ int _POSIX_Message_queue_Send_support(
|
|||||||
POSIX_Message_queue_Control_fd *the_mq_fd;
|
POSIX_Message_queue_Control_fd *the_mq_fd;
|
||||||
Objects_Locations location;
|
Objects_Locations location;
|
||||||
CORE_message_queue_Status msg_status;
|
CORE_message_queue_Status msg_status;
|
||||||
|
boolean do_wait;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate the priority.
|
* Validate the priority.
|
||||||
@@ -77,6 +79,17 @@ int _POSIX_Message_queue_Send_support(
|
|||||||
|
|
||||||
the_mq = the_mq_fd->Queue;
|
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(
|
msg_status = _CORE_message_queue_Submit(
|
||||||
&the_mq->Message_queue,
|
&the_mq->Message_queue,
|
||||||
(void *) msg_ptr,
|
(void *) msg_ptr,
|
||||||
@@ -88,7 +101,7 @@ int _POSIX_Message_queue_Send_support(
|
|||||||
NULL,
|
NULL,
|
||||||
#endif
|
#endif
|
||||||
_POSIX_Message_queue_Priority_to_core( msg_prio ),
|
_POSIX_Message_queue_Priority_to_core( msg_prio ),
|
||||||
(the_mq_fd->oflag & O_NONBLOCK) ? FALSE : TRUE,
|
do_wait,
|
||||||
timeout /* no timeout */
|
timeout /* no timeout */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,38 @@ ssize_t mq_timedreceive(
|
|||||||
char *msg_ptr,
|
char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
unsigned int *msg_prio,
|
unsigned int *msg_prio,
|
||||||
const struct timespec *timeout
|
const struct timespec *abstime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Watchdog_Interval ticks;
|
||||||
|
boolean do_wait;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
switch ( _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ) ) {
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
|
do_wait = FALSE;
|
||||||
|
break;
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
|
do_wait = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return _POSIX_Message_queue_Receive_support(
|
return _POSIX_Message_queue_Receive_support(
|
||||||
mqdes,
|
mqdes,
|
||||||
msg_ptr,
|
msg_ptr,
|
||||||
msg_len,
|
msg_len,
|
||||||
msg_prio,
|
msg_prio,
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
do_wait,
|
||||||
|
ticks
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,14 +44,38 @@ int mq_timedsend(
|
|||||||
const char *msg_ptr,
|
const char *msg_ptr,
|
||||||
size_t msg_len,
|
size_t msg_len,
|
||||||
unsigned int msg_prio,
|
unsigned int msg_prio,
|
||||||
const struct timespec *timeout
|
const struct timespec *abstime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Watchdog_Interval ticks;
|
||||||
|
boolean do_wait;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
switch ( _POSIX_Absolute_timeout_to_ticks( abstime, &ticks ) ) {
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
|
do_wait = FALSE;
|
||||||
|
break;
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
|
do_wait = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return _POSIX_Message_queue_Send_support(
|
return _POSIX_Message_queue_Send_support(
|
||||||
mqdes,
|
mqdes,
|
||||||
msg_ptr,
|
msg_ptr,
|
||||||
msg_len,
|
msg_len,
|
||||||
msg_prio,
|
msg_prio,
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
do_wait,
|
||||||
|
ticks
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ int _POSIX_Mutex_From_core_mutex_status(
|
|||||||
case CORE_MUTEX_WAS_DELETED:
|
case CORE_MUTEX_WAS_DELETED:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
case CORE_MUTEX_TIMEOUT:
|
case CORE_MUTEX_TIMEOUT:
|
||||||
return EAGAIN;
|
return ETIMEDOUT;
|
||||||
case CORE_MUTEX_STATUS_CEILING_VIOLATED:
|
case CORE_MUTEX_STATUS_CEILING_VIOLATED:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -28,12 +28,58 @@
|
|||||||
|
|
||||||
int pthread_mutex_timedlock(
|
int pthread_mutex_timedlock(
|
||||||
pthread_mutex_t *mutex,
|
pthread_mutex_t *mutex,
|
||||||
const struct timespec *timeout
|
const struct timespec *abstime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _POSIX_Mutex_Lock_support(
|
Watchdog_Interval ticks;
|
||||||
|
boolean do_wait;
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks );
|
||||||
|
switch ( status ) {
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
|
do_wait = FALSE;
|
||||||
|
break;
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
|
do_wait = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_status = _POSIX_Mutex_Lock_support(
|
||||||
mutex,
|
mutex,
|
||||||
TRUE,
|
do_wait,
|
||||||
_POSIX_Timespec_to_interval( timeout )
|
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) ) {
|
||||||
|
switch (lock_status) {
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
|
return EINVAL;
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
|
return ETIMEDOUT;
|
||||||
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lock_status;
|
||||||
}
|
}
|
||||||
|
|||||||
126
cpukit/posix/src/posixtimespecabsolutetimeout.c
Normal file
126
cpukit/posix/src/posixtimespecabsolutetimeout.c
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Convert abstime timeout to ticks
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
static boolean _Timespec_Is_valid(
|
||||||
|
const struct timespec *time
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( !time )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( time->tv_sec < 0 )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( time->tv_nsec < 0 )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( time->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean _Timespec_Less_than(
|
||||||
|
const struct timespec *lhs,
|
||||||
|
const struct timespec *rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if ( lhs->tv_sec < rhs->tv_sec )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if ( lhs->tv_sec > rhs->tv_sec )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* ASSERT: lhs->tv_sec == rhs->tv_sec */
|
||||||
|
if ( lhs->tv_nsec < rhs->tv_nsec )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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?
|
||||||
|
*/
|
||||||
|
clock_gettime( CLOCK_REALTIME, ¤t_time );
|
||||||
|
|
||||||
|
if ( _Timespec_Less_than( abstime, ¤t_time ) )
|
||||||
|
return POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How long until the requested absolute time?
|
||||||
|
*/
|
||||||
|
_POSIX_Timespec_subtract( ¤t_time, abstime, &difference );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internally the SuperCore uses ticks, so convert to them.
|
||||||
|
*/
|
||||||
|
*ticks_out = _POSIX_Timespec_to_interval( &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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
int _POSIX_Semaphore_Wait_support(
|
int _POSIX_Semaphore_Wait_support(
|
||||||
sem_t *sem,
|
sem_t *sem,
|
||||||
Core_semaphore_Blocking_option blocking,
|
boolean blocking,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -65,9 +65,6 @@ int _POSIX_Semaphore_Wait_support(
|
|||||||
* count to the largest value the count can hold.
|
* count to the largest value the count can hold.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case CORE_SEMAPHORE_BAD_TIMEOUT_VALUE:
|
|
||||||
rtems_set_errno_and_return_minus_one( EINVAL );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -32,40 +32,51 @@ int sem_timedwait(
|
|||||||
const struct timespec *abstime
|
const struct timespec *abstime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/*
|
Watchdog_Interval ticks;
|
||||||
* The abstime is a walltime. We turn it into an interval.
|
boolean do_wait = TRUE;
|
||||||
*/
|
POSIX_Absolute_timeout_conversion_results_t status;
|
||||||
Watchdog_Interval ticks = 0;
|
int lock_status;
|
||||||
struct timespec current_time;
|
|
||||||
struct timespec difference;
|
|
||||||
Core_semaphore_Blocking_option blocking = CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error check the absolute time to timeout
|
* 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 0
|
status = _POSIX_Absolute_timeout_to_ticks( abstime, &ticks );
|
||||||
if ( /* abstime->tv_sec < 0 || */ abstime->tv_nsec ) /* tv_sec is unsigned */
|
switch ( status ) {
|
||||||
blocking = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE;
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
else
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
#endif
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
if ( abstime->tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) {
|
do_wait = FALSE;
|
||||||
blocking = CORE_SEMAPHORE_BAD_TIMEOUT;
|
break;
|
||||||
} else {
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
clock_gettime( CLOCK_REALTIME, ¤t_time );
|
do_wait = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_status = _POSIX_Semaphore_Wait_support( sem, do_wait, ticks );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the abstime is in the future
|
* 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 ( abstime->tv_sec < current_time.tv_sec )
|
if ( !do_wait && (lock_status == EBUSY) ) {
|
||||||
blocking = CORE_SEMAPHORE_BAD_TIMEOUT;
|
switch (lock_status) {
|
||||||
else if ( (abstime->tv_sec == current_time.tv_sec) &&
|
case POSIX_ABSOLUTE_TIMEOUT_INVALID:
|
||||||
(abstime->tv_nsec <= current_time.tv_nsec) )
|
return EINVAL;
|
||||||
blocking = CORE_SEMAPHORE_BAD_TIMEOUT;
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
|
||||||
else {
|
case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
|
||||||
_POSIX_Timespec_subtract( ¤t_time, abstime, &difference );
|
return ETIMEDOUT;
|
||||||
ticks = _POSIX_Timespec_to_interval( &difference );
|
case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
|
||||||
blocking = CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _POSIX_Semaphore_Wait_support( sem, blocking, ticks );
|
return lock_status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ int sem_trywait(
|
|||||||
sem_t *sem
|
sem_t *sem
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _POSIX_Semaphore_Wait_support( sem, FALSE, THREAD_QUEUE_WAIT_FOREVER );
|
return _POSIX_Semaphore_Wait_support(sem, FALSE, THREAD_QUEUE_WAIT_FOREVER);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,5 @@ int sem_wait(
|
|||||||
sem_t *sem
|
sem_t *sem
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _POSIX_Semaphore_Wait_support(
|
return _POSIX_Semaphore_Wait_support( sem, TRUE, THREAD_QUEUE_WAIT_FOREVER );
|
||||||
sem,
|
|
||||||
CORE_SEMAPHORE_BLOCK_FOREVER,
|
|
||||||
THREAD_QUEUE_WAIT_FOREVER
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,8 +107,7 @@ rtems_status_code rtems_semaphore_obtain(
|
|||||||
_CORE_semaphore_Seize_isr_disable(
|
_CORE_semaphore_Seize_isr_disable(
|
||||||
&the_semaphore->Core_control.semaphore,
|
&the_semaphore->Core_control.semaphore,
|
||||||
id,
|
id,
|
||||||
((_Options_Is_no_wait( option_set )) ?
|
((_Options_Is_no_wait( option_set )) ? FALSE : TRUE),
|
||||||
CORE_SEMAPHORE_NO_WAIT : CORE_SEMAPHORE_BLOCK_FOREVER),
|
|
||||||
timeout,
|
timeout,
|
||||||
&level
|
&level
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ rtems_status_code _Semaphore_Translate_core_semaphore_return_code_[] = {
|
|||||||
RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */
|
RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */
|
||||||
RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */
|
RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */
|
||||||
RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */
|
RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */
|
||||||
RTEMS_INTERNAL_ERROR /* CORE_SEMAPHORE_BAD_TIMEOUT_VALUE */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
|
rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
|
||||||
@@ -114,7 +113,7 @@ rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
|
|||||||
if ( status == THREAD_STATUS_PROXY_BLOCKING )
|
if ( status == THREAD_STATUS_PROXY_BLOCKING )
|
||||||
return RTEMS_PROXY_BLOCKING;
|
return RTEMS_PROXY_BLOCKING;
|
||||||
#endif
|
#endif
|
||||||
if ( status > CORE_MUTEX_STATUS_CEILING_VIOLATED )
|
if ( status > CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED )
|
||||||
return RTEMS_INTERNAL_ERROR;
|
return RTEMS_INTERNAL_ERROR;
|
||||||
return _Semaphore_Translate_core_semaphore_return_code_[status];
|
return _Semaphore_Translate_core_semaphore_return_code_[status];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,14 +82,7 @@ typedef enum {
|
|||||||
/** This status indicates that an attempt was made to unlock the semaphore
|
/** This status indicates that an attempt was made to unlock the semaphore
|
||||||
* and this would have made its count greater than that allowed.
|
* and this would have made its count greater than that allowed.
|
||||||
*/
|
*/
|
||||||
CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED,
|
CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED
|
||||||
/** This status indicates that the semaphore was not immediately
|
|
||||||
* available and the caller passed a bad timeout value to the API
|
|
||||||
* routine. In this case, the API required that the validity check
|
|
||||||
* for the timeout occur after the check that the semaphore was immediately
|
|
||||||
* available.
|
|
||||||
*/
|
|
||||||
CORE_SEMAPHORE_BAD_TIMEOUT_VALUE
|
|
||||||
} CORE_semaphore_Status;
|
} CORE_semaphore_Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,25 +115,6 @@ typedef struct {
|
|||||||
uint32_t count;
|
uint32_t count;
|
||||||
} CORE_semaphore_Control;
|
} CORE_semaphore_Control;
|
||||||
|
|
||||||
/**
|
|
||||||
* The following enumerated type is the set of blocking options
|
|
||||||
* available to seize operation.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
/** This value indicates that the caller does not wish to block. */
|
|
||||||
CORE_SEMAPHORE_NO_WAIT,
|
|
||||||
/** This value indicates that the caller is willing to block forever. */
|
|
||||||
CORE_SEMAPHORE_BLOCK_FOREVER,
|
|
||||||
/** This value indicates that the caller is blocking with a timeout. */
|
|
||||||
CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT,
|
|
||||||
/** This value indicates that the caller wanted to block but passed in
|
|
||||||
* a bad timeout value to the API. Unfortunately, this is a weird case
|
|
||||||
* where the timeout bad error is required to be generated only if
|
|
||||||
* the semaphore is not available.
|
|
||||||
*/
|
|
||||||
CORE_SEMAPHORE_BAD_TIMEOUT
|
|
||||||
} Core_semaphore_Blocking_option;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine initializes the semaphore based on the parameters passed.
|
* This routine initializes the semaphore based on the parameters passed.
|
||||||
*
|
*
|
||||||
@@ -163,14 +137,14 @@ void _CORE_semaphore_Initialize(
|
|||||||
* @param[in] the_semaphore is the semaphore to seize
|
* @param[in] the_semaphore is the semaphore to seize
|
||||||
* @param[in] id is the Id of the API level Semaphore object associated
|
* @param[in] id is the Id of the API level Semaphore object associated
|
||||||
* with this instance of a SuperCore Semaphore
|
* with this instance of a SuperCore Semaphore
|
||||||
* @param[in] wait is the blocking mode
|
* @param[in] wait indicates if the caller is willing to block
|
||||||
* @param[in] timeout is the number of ticks the calling thread is willing
|
* @param[in] timeout is the number of ticks the calling thread is willing
|
||||||
* to wait if @a wait is TRUE.
|
* to wait if @a wait is TRUE.
|
||||||
*/
|
*/
|
||||||
void _CORE_semaphore_Seize(
|
void _CORE_semaphore_Seize(
|
||||||
CORE_semaphore_Control *the_semaphore,
|
CORE_semaphore_Control *the_semaphore,
|
||||||
Objects_Id id,
|
Objects_Id id,
|
||||||
Core_semaphore_Blocking_option wait,
|
boolean wait,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ void _CORE_message_queue_Seize(
|
|||||||
|
|
||||||
*size = the_message->Contents.size;
|
*size = the_message->Contents.size;
|
||||||
_Thread_Executing->Wait.count = the_message->priority;
|
_Thread_Executing->Wait.count = the_message->priority;
|
||||||
_CORE_message_queue_Copy_buffer(the_message->Contents.buffer,buffer,*size);
|
_CORE_message_queue_Copy_buffer(the_message->Contents.buffer, buffer,*size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There could be a thread waiting to send a message. If there
|
* There could be a thread waiting to send a message. If there
|
||||||
@@ -107,7 +107,7 @@ void _CORE_message_queue_Seize(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
the_message->priority = the_thread->Wait.count;
|
the_message->priority = the_thread->Wait.count;
|
||||||
the_message->Contents.size = (uint32_t )the_thread->Wait.return_argument_1;
|
the_message->Contents.size = (uint32_t)the_thread->Wait.option;
|
||||||
_CORE_message_queue_Copy_buffer(
|
_CORE_message_queue_Copy_buffer(
|
||||||
the_thread->Wait.return_argument,
|
the_thread->Wait.return_argument,
|
||||||
the_message->Contents.buffer,
|
the_message->Contents.buffer,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
void _CORE_semaphore_Seize(
|
void _CORE_semaphore_Seize(
|
||||||
CORE_semaphore_Control *the_semaphore,
|
CORE_semaphore_Control *the_semaphore,
|
||||||
Objects_Id id,
|
Objects_Id id,
|
||||||
Core_semaphore_Blocking_option wait,
|
boolean wait,
|
||||||
Watchdog_Interval timeout
|
Watchdog_Interval timeout
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -69,23 +69,20 @@ void _CORE_semaphore_Seize(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( wait ) {
|
if ( !wait ) {
|
||||||
case CORE_SEMAPHORE_NO_WAIT:
|
|
||||||
_ISR_Enable( level );
|
_ISR_Enable( level );
|
||||||
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
|
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
|
||||||
return;
|
return;
|
||||||
case CORE_SEMAPHORE_BAD_TIMEOUT:
|
}
|
||||||
_ISR_Enable( level );
|
|
||||||
executing->Wait.return_code = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE;
|
/*
|
||||||
return;
|
* If the semaphore is not available and the caller is willing to
|
||||||
case CORE_SEMAPHORE_BLOCK_FOREVER:
|
* block, then we now block the caller with optional timeout.
|
||||||
case CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT:
|
*/
|
||||||
_Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
|
_Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
|
||||||
executing->Wait.queue = &the_semaphore->Wait_queue;
|
executing->Wait.queue = &the_semaphore->Wait_queue;
|
||||||
executing->Wait.id = id;
|
executing->Wait.id = id;
|
||||||
_ISR_Enable( level );
|
_ISR_Enable( level );
|
||||||
_Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout );
|
_Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout );
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user