diff --git a/src/pmie/src/dstruct.c b/src/pmie/src/dstruct.c index d440ea3..84d7a7b 100644 --- a/src/pmie/src/dstruct.c +++ b/src/pmie/src/dstruct.c @@ -191,11 +191,11 @@ unrealizenano(RealTime rt, struct timespec *ts) /* sleep until given RealTime */ -void +int sleepTight(RealTime sched) { RealTime delay; /* interval to sleep */ - int sts; + int sts = 0; #ifdef HAVE_WAITPID pid_t pid; @@ -219,14 +219,17 @@ sleepTight(RealTime sched) struct timespec ts, tleft; delay = sched - getReal(); + if (delay < 0) + return EINVAL; + unrealizenano(delay, &ts); - for (;;) { /* loop to catch early wakeup from nanosleep */ + /* loop to catch early wakeup from nanosleep */ + do { sts = nanosleep(&ts, &tleft); - if (sts == 0 || (sts < 0 && errno != EINTR)) - break; ts = tleft; - } + } while (sts < 0 && errno == EINTR); } + return sts == 0 ? sts : errno; } diff --git a/src/pmie/src/dstruct.h b/src/pmie/src/dstruct.h index 550afb7..5735dbd 100644 --- a/src/pmie/src/dstruct.h +++ b/src/pmie/src/dstruct.h @@ -76,7 +76,7 @@ void unrealize(RealTime, struct timeval *); RealTime getReal(void); /* return current time */ void reflectTime(RealTime); /* update time vars to reflect now */ -void sleepTight(RealTime); /* sleep until given RealTime */ +int sleepTight(RealTime); /* sleep until given RealTime */ /*********************************************************************** diff --git a/src/pmie/src/eval.c b/src/pmie/src/eval.c index 7a0dbb8..5885805 100644 --- a/src/pmie/src/eval.c +++ b/src/pmie/src/eval.c @@ -729,7 +729,9 @@ findEval(Expr *x) void run(void) { + int sts; Task *t; + int warp = 0; /* empty task queue */ if (taskq == NULL) @@ -751,8 +753,9 @@ run(void) now = t->retry; if (now > stop) break; - sleepTight(t->retry); - enable(t); + sts = sleepTight(t->retry); + if (sts == 0) + enable(t); t->retry = waiting(t) ? now + RETRY : 0; } else { @@ -760,8 +763,20 @@ run(void) if (now > stop) break; reflectTime(t->delta); - sleepTight(t->eval); - eval(t); + sts = sleepTight(t->eval); + if (sts == 0) { + if (warp) { + __pmNotifyErr(LOG_INFO, + "System clock warped forward by %ld seconds\n", + now - warp); + warp = 0; + } + eval(t); + } else if (sts == EINVAL) { + /* system clock jumped forward */ + if (warp == 0) + warp = now; + } t->tick++; t->eval = t->epoch + t->tick * t->delta; if ((! t->retry) && waiting(t))