Modified the implementation of usleep and make ModelExecution process "THREAD SLEEP...
[c11tester.git] / sleeps.cc
index 24e0eea..0b4d32f 100644 (file)
--- a/sleeps.cc
+++ b/sleeps.cc
@@ -4,6 +4,10 @@
 #include "action.h"
 #include "model.h"
 
+extern "C" {
+int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
+}
+
 unsigned int __sleep (unsigned int seconds)
 {
        model->switch_to_master(
@@ -19,8 +23,28 @@ unsigned int sleep(unsigned int seconds)
 
 int usleep (useconds_t useconds)
 {
-       model->switch_to_master(
-               new ModelAction(NOOP, std::memory_order_seq_cst, NULL)
-               );
+       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) {
+       if (model) {
+               uint64_t time = rqtp->tv_sec * 1000000000 + rqtp->tv_nsec;
+               struct timespec currtime;
+               clock_gettime(CLOCK_MONOTONIC, &currtime);
+               uint64_t lcurrtime = currtime.tv_sec * 1000000000 + currtime.tv_nsec;
+               model->switch_to_master(new ModelAction(THREAD_SLEEP, std::memory_order_seq_cst, time, lcurrtime));
+               if (rmtp != NULL) {
+                       clock_gettime(CLOCK_MONOTONIC, &currtime);
+                       uint64_t lendtime = currtime.tv_sec * 1000000000 + currtime.tv_nsec;
+                       uint64_t elapsed = lendtime - lcurrtime;
+                       rmtp->tv_sec = elapsed / 1000000000;
+                       rmtp->tv_nsec = elapsed - rmtp->tv_sec * 1000000000;
+               }
+       }
+
        return 0;
 }