Merge branch 'master' of ssh://demsky.eecs.uci.edu/home/git/model-checker
[c11tester.git] / schedule.cc
1 #include "threads.h"
2 #include "schedule.h"
3 #include "common.h"
4 #include "model.h"
5
6 /** Constructor */
7 Scheduler::Scheduler() :
8         current(NULL)
9 {
10 }
11
12 /**
13  * Add a Thread to the scheduler's ready list.
14  * @param t The Thread to add
15  */
16 void Scheduler::add_thread(Thread *t)
17 {
18         DEBUG("thread %d\n", t->get_id());
19         readyList.push_back(t);
20 }
21
22 /**
23  * Remove a given Thread from the scheduler.
24  * @param t The Thread to remove
25  */
26 void Scheduler::remove_thread(Thread *t)
27 {
28         if (current == t)
29                 current = NULL;
30         else
31                 readyList.remove(t);
32 }
33
34 /**
35  * Force one Thread to wait on another Thread. The "join" Thread should
36  * eventually wake up the waiting Thread via Scheduler::wake.
37  * @param wait The Thread that should wait
38  * @param join The Thread on which we are waiting.
39  */
40 void Scheduler::wait(Thread *wait, Thread *join)
41 {
42         ASSERT(!join->is_complete());
43         remove_thread(wait);
44         join->push_wait_list(wait);
45         wait->set_state(THREAD_BLOCKED);
46 }
47
48 /**
49  * Wake a Thread up that was previously waiting (see Scheduler::wait)
50  * @param t The Thread to wake up
51  */
52 void Scheduler::wake(Thread *t)
53 {
54         add_thread(t);
55         t->set_state(THREAD_READY);
56 }
57
58 /**
59  * Remove one Thread from the scheduler. This implementation defaults to FIFO,
60  * if a thread is not already provided.
61  *
62  * @param t Thread to run, if chosen by an external entity (e.g.,
63  * ModelChecker). May be NULL to indicate no external choice.
64  * @return The next Thread to run
65  */
66 Thread * Scheduler::next_thread(Thread *t)
67 {
68         if (t != NULL) {
69                 current = t;
70                 readyList.remove(t);
71         } else if (readyList.empty()) {
72                 t = NULL;
73         } else {
74                 t = readyList.front();
75                 current = t;
76                 readyList.pop_front();
77         }
78
79         print();
80
81         return t;
82 }
83
84 /**
85  * @return The currently-running Thread
86  */
87 Thread * Scheduler::get_current_thread() const
88 {
89         return current;
90 }
91
92 /**
93  * Print debugging information about the current state of the scheduler. Only
94  * prints something if debugging is enabled.
95  */
96 void Scheduler::print() const
97 {
98         if (current)
99                 DEBUG("Current thread: %d\n", current->get_id());
100         else
101                 DEBUG("No current thread\n");
102         DEBUG("Num. threads in ready list: %zu\n", readyList.size());
103
104         std::list<Thread *, MyAlloc< Thread * > >::const_iterator it;
105         for (it = readyList.begin(); it != readyList.end(); it++)
106                 DEBUG("In ready list: thread %d\n", (*it)->get_id());
107 }