From 8b70aaea8a650607df5361c47aee0bd0c74e6e72 Mon Sep 17 00:00:00 2001 From: weiyu Date: Fri, 18 Oct 2019 16:24:40 -0700 Subject: [PATCH] Change the implementation of sleep and remove NOOP --- action.cc | 2 +- action.h | 1 - sleeps.cc | 36 +++++++++++++++++++++++++----------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/action.cc b/action.cc index 92bb30eb..88107294 100644 --- a/action.cc +++ b/action.cc @@ -46,7 +46,7 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, 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; diff --git a/action.h b/action.h index 80ac1fda..8a7743ff 100644 --- a/action.h +++ b/action.h @@ -78,7 +78,6 @@ typedef enum action_type { 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; diff --git a/sleeps.cc b/sleeps.cc index 0b4d32f6..becc98c8 100644 --- a/sleeps.cc +++ b/sleeps.cc @@ -1,5 +1,6 @@ #include #include +#include #include "action.h" #include "model.h" @@ -8,21 +9,33 @@ extern "C" { 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, @@ -30,7 +43,8 @@ int usleep (useconds_t useconds) 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; -- 2.34.1