-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrobin_round.cpp
More file actions
180 lines (166 loc) · 6.04 KB
/
robin_round.cpp
File metadata and controls
180 lines (166 loc) · 6.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include <queue>
#include <cstdint>
int current_thread_id = -1;
uint64_t m_timeslice = 0;
uint64_t m_time = 0;
std::queue<int> thread_pool;
/**
* Функция будет вызвана перед каждым тестом, если вы
* используете глобальные и/или статические переменные
* не полагайтесь на то, что они заполнены 0 - в них
* могут храниться значения оставшиеся от предыдущих
* тестов.
*
* timeslice - квант времени, который нужно использовать.
* Поток смещается с CPU, если пока он занимал CPU функция
* timer_tick была вызвана timeslice раз.
**/
void scheduler_setup(int timeslice) {
current_thread_id = -1;
::m_timeslice = timeslice;
m_time = 0;
thread_pool = {};
}
/**
* Функция вызывается, когда создается новый поток управления.
* thread_id - идентификатор этого потока и гарантируется, что
* никакие два потока не могут иметь одинаковый идентификатор.
**/
void new_thread(int thread_id) {
if (current_thread_id == -1) {
current_thread_id = thread_id;
m_time = 0;
} else {
thread_pool.push(thread_id);
}
}
/**
* Функция вызывается, когда поток, исполняющийся на CPU,
* завершается. Завершится может только поток, который сейчас
* исполняется, поэтому thread_id не передается. CPU должен
* быть отдан другому потоку, если есть активный
* (незаблокированный и незавершившийся) поток.
**/
void exit_thread() {
if (thread_pool.empty()) {
current_thread_id = -1;
} else {
current_thread_id = thread_pool.front();
thread_pool.pop();
m_time = 0;
}
}
/**
* Функция вызывается, когда поток, исполняющийся на CPU,
* блокируется. Заблокироваться может только поток, который
* сейчас исполняется, поэтому thread_id не передается. CPU
* должен быть отдан другому активному потоку, если таковой
* имеется.
**/
void block_thread() {
if (thread_pool.empty()) {
current_thread_id = -1;
} else {
current_thread_id = thread_pool.front();
thread_pool.pop();
m_time = 0;
}
}
/**
* Функция вызывается, когда один из заблокированных потоков
* разблокируется. Гарантируется, что thread_id - идентификатор
* ранее заблокированного потока.
**/
void wake_thread(int thread_id) {
if (current_thread_id == -1) {
current_thread_id = thread_id;
m_time = 0;
} else {
thread_pool.push(thread_id);
}
}
/**
* Ваш таймер. Вызывается каждый раз, когда проходит единица
* времени.
**/
void timer_tick() {
++m_time;
if (m_time == m_timeslice) {
if (!thread_pool.empty()) {
thread_pool.push(current_thread_id);
current_thread_id = thread_pool.front();
thread_pool.pop();
}
m_time = 0;
}
}
/**
* Функция должна возвращать идентификатор потока, который в
* данный момент занимает CPU, или -1 если такого потока нет.
* Единственная ситуация, когда функция может вернуть -1, это
* когда нет ни одного активного потока (все созданные потоки
* либо уже завершены, либо заблокированы).
**/
int current_thread() {
return current_thread_id;
}
using namespace std;
static void test(int timeslice) {
printf("Start test for RoundRobin algorithm\n");
scheduler_setup(timeslice);
new_thread(1);
new_thread(2);
new_thread(3);
cout << "outside loop current thread: " << current_thread() << endl;
int iter_count = 7;
for (int i = 0; i < iter_count; i++) {
timer_tick();
cout << "current thread: " << current_thread() << endl;
}
new_thread(4);
int block = current_thread();
cout << "block thread: " << block << endl;
block_thread();
cout << "outside loop current thread: " << current_thread() << endl;
for (int i = 0; i < iter_count; i++) {
timer_tick();
cout << "current thread: " << current_thread() << endl;
}
wake_thread(block);
cout << "wake thread: " << block << endl;
cout << "outside loop current thread: " << current_thread() << endl;
for (int i = 0; i < iter_count; i++) {
timer_tick();
cout << "current thread: " << current_thread() << endl;
}
cout << "exit thread: " << current_thread() << endl;
exit_thread();
cout << "outside loop current thread: " << current_thread() << endl;
for (int i = 0; i < iter_count; i++) {
timer_tick();
cout << "current thread: " << current_thread() << endl;
}
cout << "exit thread: " << current_thread() << endl;
exit_thread();
cout << "outside loop current thread: " << current_thread() << endl;
for (int i = 0; i < iter_count; i++) {
timer_tick();
cout << "current thread: " << current_thread() << endl;
}
cout << "exit thread: " << current_thread() << endl;
exit_thread();
cout << "outside loop current thread: " << current_thread() << endl;
for (int i = 0; i < iter_count; i++){
timer_tick();
cout << "current thread: " << current_thread() << endl;
}
}
void testRoundRobin() {
printf("---------- Start RoundRobin algorithm test ----------\n");
cout << "TimeSlice is 4\n";
test(4);
cout << "\nTimeSlice is 10 \n";
test(10);
printf("---------- End RoundRobin algorithm test ----------\n");
}