seq_number(ACTION_INITIAL_CLOCK)
{
/* References to NULL atomic variables can end up here */
- ASSERT(loc || type == ATOMIC_FENCE || type == NOOP);
+ ASSERT(loc || type == ATOMIC_FENCE);
Thread *t = thread ? thread : thread_current();
this->tid = t!= NULL ? t->get_id() : -1;
ATOMIC_WAIT, // < A wait action
ATOMIC_TIMEDWAIT, // < A timed wait action
ATOMIC_ANNOTATION, // < An annotation action to pass information to a trace analysis
- NOOP // no operation, which returns control to scheduler
} action_type_t;
#include <time.h>
#include <unistd.h>
+#include <sys/param.h>
#include "action.h"
#include "model.h"
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
}
-unsigned int __sleep (unsigned int seconds)
-{
- model->switch_to_master(
- new ModelAction(NOOP, std::memory_order_seq_cst, NULL)
- );
- return 0;
-}
-
unsigned int sleep(unsigned int seconds)
{
- return __sleep(seconds);
+ /* https://code.woboq.org/userspace/glibc/sysdeps/posix/sleep.c.html */
+ const unsigned int max
+ = (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1);
+
+ struct timespec ts = { 0, 0 };
+ do {
+ if (sizeof (ts.tv_sec) <= sizeof (seconds)) {
+ /* Since SECONDS is unsigned assigning the value to .tv_sec can
+ overflow it. In this case we have to wait in steps. */
+ ts.tv_sec += MIN (seconds, max);
+ seconds -= (unsigned int) ts.tv_sec;
+ } else {
+ ts.tv_sec = (time_t) seconds;
+ seconds = 0;
+ }
+
+ nanosleep(&ts, &ts);
+ } while (seconds > 0);
+
+ return 0;
}
-int usleep (useconds_t useconds)
+int usleep(useconds_t useconds)
{
+ /* https://code.woboq.org/userspace/glibc/sysdeps/posix/usleep.c.html */
struct timespec ts = {
.tv_sec = (long int) (useconds / 1000000),
.tv_nsec = (long int) (useconds % 1000000) * 1000l,
return nanosleep(&ts, NULL);
}
-int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) {
+int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
+{
if (model) {
uint64_t time = rqtp->tv_sec * 1000000000 + rqtp->tv_nsec;
struct timespec currtime;