libCom/osi: Fixed all epicsThreadSleep() implementations
All are now robust against overflow, NAN or negative argument. Passing seconds=0 calls the OS scheduler, offering to yield. Passing seconds>0 delays at least the requested time, up to a limit which usually depends on the OS tick rate.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <syslog.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/error.h>
|
||||
@@ -364,16 +365,15 @@ epicsThreadSleep (double seconds)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
rtems_interval delay;
|
||||
extern double rtemsTicksPerTwoSeconds_double;
|
||||
|
||||
if (seconds <= 0.0) {
|
||||
delay = 0;
|
||||
extern double rtemsTicksPerSecond_double;
|
||||
|
||||
if (seconds > 0.0) {
|
||||
seconds *= rtemsTicksPerSecond_double;
|
||||
seconds += 0.99999999; /* 8 9s here is optimal */
|
||||
delay = (seconds >= INT_MAX) ? INT_MAX : (int) seconds;
|
||||
}
|
||||
else {
|
||||
delay = seconds * rtemsTicksPerTwoSeconds_double;
|
||||
delay = (delay + 1) / 2;
|
||||
if (delay == 0)
|
||||
delay++;
|
||||
else { /* seconds <= 0 or NAN */
|
||||
delay = 0;
|
||||
}
|
||||
sc = rtems_task_wake_after (delay);
|
||||
if(sc != RTEMS_SUCCESSFUL)
|
||||
|
||||
@@ -779,18 +779,15 @@ epicsShareFunc void epicsShareAPI epicsThreadSleep ( double seconds )
|
||||
static const unsigned mSecPerSec = 1000;
|
||||
DWORD milliSecDelay;
|
||||
|
||||
if ( seconds <= 0.0 ) {
|
||||
if ( seconds > 0.0 ) {
|
||||
seconds *= mSecPerSec;
|
||||
seconds += 0.99999999; /* 8 9s here is optimal */
|
||||
milliSecDelay = ( seconds >= INFINITE ) ?
|
||||
INFINITE - 1 : ( DWORD ) seconds;
|
||||
}
|
||||
else { /* seconds <= 0 or NAN */
|
||||
milliSecDelay = 0u;
|
||||
}
|
||||
else if ( seconds >= INFINITE / mSecPerSec ) {
|
||||
milliSecDelay = INFINITE - 1;
|
||||
}
|
||||
else {
|
||||
milliSecDelay = ( DWORD ) ( ( seconds * mSecPerSec ) + 0.5 );
|
||||
if ( milliSecDelay == 0 ) {
|
||||
milliSecDelay = 1;
|
||||
}
|
||||
}
|
||||
Sleep ( milliSecDelay );
|
||||
}
|
||||
|
||||
|
||||
@@ -673,9 +673,15 @@ epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds)
|
||||
struct timespec remainingTime;
|
||||
double nanoseconds;
|
||||
|
||||
delayTime.tv_sec = (time_t)seconds;
|
||||
nanoseconds = (seconds - (double)delayTime.tv_sec) *1e9;
|
||||
delayTime.tv_nsec = (long)nanoseconds;
|
||||
if (seconds > 0) {
|
||||
delayTime.tv_sec = seconds;
|
||||
nanoseconds = (seconds - delayTime.tv_sec) *1e9;
|
||||
delayTime.tv_nsec = nanoseconds;
|
||||
}
|
||||
else {
|
||||
delayTime.tv_sec = 0;
|
||||
delayTime.tv_nsec = 0;
|
||||
}
|
||||
while (nanosleep(&delayTime, &remainingTime) == -1 &&
|
||||
errno == EINTR)
|
||||
delayTime = remainingTime;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
@@ -279,11 +280,13 @@ void epicsThreadSleep(double seconds)
|
||||
STATUS status;
|
||||
int ticks;
|
||||
|
||||
if(seconds<=0.0) {
|
||||
if (seconds > 0.0) {
|
||||
seconds *= sysClkRateGet();
|
||||
seconds += 0.99999999; /* 8 9s here is optimal */
|
||||
ticks = (seconds >= INT_MAX) ? INT_MAX : (int) seconds;
|
||||
}
|
||||
else { /* seconds <= 0 or NAN */
|
||||
ticks = 0;
|
||||
} else {
|
||||
ticks = seconds*sysClkRateGet() + 0.5;
|
||||
if(ticks<=0) ticks = 1;
|
||||
}
|
||||
status = taskDelay(ticks);
|
||||
if(status) errlogPrintf("epicsThreadSleep\n");
|
||||
|
||||
Reference in New Issue
Block a user