schedule: add sleep() function
[model-checker.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  * Prevent a Thread from being scheduled. The sleeping Thread should be
50  * re-awoken via Scheduler::wake.
51  * @param thread The Thread that should sleep
52  */
53 void Scheduler::sleep(Thread *t)
54 {
55         remove_thread(t);
56         t->set_state(THREAD_BLOCKED);
57 }
58
59 /**
60  * Wake a Thread up that was previously waiting (see Scheduler::wait)
61  * @param t The Thread to wake up
62  */
63 void Scheduler::wake(Thread *t)
64 {
65         add_thread(t);
66         t->set_state(THREAD_READY);
67 }
68
69 /**
70  * Remove one Thread from the scheduler. This implementation defaults to FIFO,
71  * if a thread is not already provided.
72  *
73  * @param t Thread to run, if chosen by an external entity (e.g.,
74  * ModelChecker). May be NULL to indicate no external choice.
75  * @return The next Thread to run
76  */
77 Thread * Scheduler::next_thread(Thread *t)
78 {
79         if (t != NULL) {
80                 current = t;
81                 readyList.remove(t);
82         } else if (readyList.empty()) {
83                 t = NULL;
84         } else {
85                 t = readyList.front();
86                 current = t;
87                 readyList.pop_front();
88         }
89
90         print();
91
92         return t;
93 }
94
95 /**
96  * @return The currently-running Thread
97  */
98 Thread * Scheduler::get_current_thread() const
99 {
100         return current;
101 }
102
103 /**
104  * Print debugging information about the current state of the scheduler. Only
105  * prints something if debugging is enabled.
106  */
107 void Scheduler::print() const
108 {
109         if (current)
110                 DEBUG("Current thread: %d\n", current->get_id());
111         else
112                 DEBUG("No current thread\n");
113         DEBUG("Num. threads in ready list: %zu\n", readyList.size());
114
115         std::list<Thread *, MyAlloc< Thread * > >::const_iterator it;
116         for (it = readyList.begin(); it != readyList.end(); it++)
117                 DEBUG("In ready list: thread %d\n", (*it)->get_id());
118 }