Implement timedwait
[c11tester.git] / fuzzer.cc
1 #include "fuzzer.h"
2 #include <stdlib.h>
3 #include "threads-model.h"
4 #include "model.h"
5 #include "action.h"
6
7 int Fuzzer::selectWrite(ModelAction *read, SnapVector<ModelAction *> * rf_set) {
8         int random_index = random() % rf_set->size();
9         return random_index;
10 }
11
12 Thread * Fuzzer::selectThread(int * threadlist, int numthreads) {
13         int random_index = random() % numthreads;
14         int thread = threadlist[random_index];
15         thread_id_t curr_tid = int_to_id(thread);
16         return model->get_thread(curr_tid);
17 }
18
19 Thread * Fuzzer::selectNotify(simple_action_list_t * waiters) {
20         int numwaiters = waiters->size();
21         int random_index = random() % numwaiters;
22         sllnode<ModelAction*> * it = waiters->begin();
23         while(random_index--)
24                 it=it->getNext();
25         Thread *thread = model->get_thread(it->getVal());
26         waiters->erase(it);
27         return thread;
28 }
29
30 bool Fuzzer::shouldSleep(const ModelAction *sleep) {
31         return true;
32 }
33
34 bool Fuzzer::shouldWake(const ModelAction *sleep) {
35         struct timespec currtime;
36         clock_gettime(CLOCK_MONOTONIC, &currtime);
37         uint64_t lcurrtime = currtime.tv_sec * 1000000000 + currtime.tv_nsec;
38
39         return ((sleep->get_time()+sleep->get_value()) < lcurrtime);
40 }
41
42 /* Decide whether wait should spuriously fail or not */
43 bool Fuzzer::waitShouldFail(ModelAction * wait)
44 {
45         if ((random() & 1) == 0) {
46                 struct timespec currtime;
47         clock_gettime(CLOCK_MONOTONIC, &currtime);
48         uint64_t lcurrtime = currtime.tv_sec * 1000000000 + currtime.tv_nsec;
49
50                 // The time after which wait fail spuriously, in nanoseconds
51                 uint64_t time = random() % 1000000;
52                 wait->set_time(time + lcurrtime);
53                 return true;
54         }
55
56         return false;
57 }
58
59 bool Fuzzer::waitShouldWakeUp(const ModelAction * wait)
60 {
61         struct timespec currtime;
62         clock_gettime(CLOCK_MONOTONIC, &currtime);
63         uint64_t lcurrtime = currtime.tv_sec * 1000000000 + currtime.tv_nsec;
64
65         return (wait->get_time() < lcurrtime);
66 }
67
68 bool Fuzzer::randomizeWaitTime(ModelAction * timed_wait)
69 {
70         uint64_t abstime = timed_wait->get_time();
71         struct timespec currtime;
72         clock_gettime(CLOCK_MONOTONIC, &currtime);
73         uint64_t lcurrtime = currtime.tv_sec * 1000000000 + currtime.tv_nsec;
74         if (abstime <= lcurrtime)
75                 return false;
76
77         // Shorten wait time
78         if ((random() & 1) == 0) {
79                 uint64_t tmp = abstime - lcurrtime;
80                 uint64_t time_to_expire = random() % tmp + lcurrtime;
81                 timed_wait->set_time(time_to_expire);
82         }
83
84         return true;
85 }