5
5
#include <pthread.h>
6
6
7
7
static my_scheduler sch ;
8
- static int init_protect = 0 ;
8
+ static int init_protect = 0 ;
9
9
10
- void * add_rdy (my_thread * new_th , int front ) {
11
- node * new = malloc (sizeof (* new ));
10
+ void * add_rdy (my_thread * new_th , int front ) {
11
+ node * new = malloc (sizeof (* new ));
12
12
new_th -> state = RDY ;
13
13
new_th -> clk = 0 ;
14
14
new -> data = new_th ;
15
15
new -> next = NULL ;
16
16
17
17
int prio = new_th -> priority ;
18
- if (sch .ready [prio ]-> size == 0 ) {
18
+ if (sch .ready [prio ]-> size == 0 ) {
19
19
sch .ready [prio ]-> head = sch .ready [prio ]-> tail = new ;
20
20
sch .ready [prio ]-> size ++ ;
21
21
return NULL ;
22
22
}
23
-
24
- if (front ) {
23
+ // front = 1 --> add node to front
24
+ if (front ) {
25
25
sch .ready [prio ]-> head -> next = new ;
26
26
sch .ready [prio ]-> head = new ;
27
27
} else {
@@ -32,25 +32,24 @@ void *add_rdy(my_thread *new_th, int front) {
32
32
return NULL ;
33
33
}
34
34
35
- my_thread * get_rdy () {
35
+ my_thread * get_rdy () {
36
36
// search for highest prio
37
37
int prio = 5 ;
38
38
while (sch .ready [prio ]-> size == 0 && prio > 0 )
39
39
prio -- ;
40
40
41
41
node * rdy = sch .ready [prio ]-> head ;
42
- if (rdy == NULL ) {
42
+ if (rdy == NULL )
43
43
return NULL ;
44
- }
45
44
my_thread * data = rdy -> data ;
46
- free (rdy );
47
- if (sch .ready [prio ]-> size == 1 ) {
45
+ free (rdy );
46
+ if (sch .ready [prio ]-> size == 1 ) {
48
47
sch .ready [prio ]-> head = sch .ready [prio ]-> tail = NULL ;
49
48
sch .ready [prio ]-> size -- ;
50
49
return data ;
51
50
}
52
51
node * aux = sch .ready [prio ]-> tail ;
53
- while (aux -> next != rdy ) {
52
+ while (aux -> next != rdy ) {
54
53
aux = aux -> next ;
55
54
}
56
55
sch .ready [prio ]-> head = aux ;
@@ -60,227 +59,222 @@ my_thread *get_rdy() {
60
59
return data ;
61
60
}
62
61
63
- void * schedule () {
64
- pthread_mutex_lock (& sch .mutex );
62
+ void * schedule () {
63
+ pthread_mutex_lock (& sch .mutex );
65
64
my_thread * prev = sch .running ;
66
- my_thread * rdy = get_rdy ();
65
+ my_thread * rdy = get_rdy ();
67
66
68
- if (rdy == NULL ) {
69
- pthread_mutex_unlock (& sch .mutex );
67
+ if (rdy == NULL ) {
68
+ pthread_mutex_unlock (& sch .mutex );
70
69
return NULL ;
71
70
}
72
71
73
- if (prev == NULL ) {
72
+ if (prev == NULL ) {
74
73
rdy -> state = RUN ;
75
74
sch .running = rdy ;
76
- pthread_cond_signal ( & (rdy -> cond ));
77
- pthread_mutex_unlock (& sch .mutex );
75
+ pthread_cond_signal ( & (rdy -> cond ));
76
+ pthread_mutex_unlock (& sch .mutex );
78
77
return NULL ;
79
78
}
80
79
81
- if (sch .running -> clk == sch .sched_quantum ) {
80
+ if (sch .running -> clk == sch .sched_quantum ) {
82
81
prev -> clk = 0 ;
83
- if (prev -> priority > rdy -> priority ) {
84
- add_rdy (rdy , 1 );
85
- pthread_mutex_unlock (& sch .mutex );
82
+ if (prev -> priority > rdy -> priority ) {
83
+ add_rdy (rdy , 1 );
84
+ pthread_mutex_unlock (& sch .mutex );
86
85
return NULL ;
87
86
}
88
87
prev -> state = RDY ;
89
- add_rdy (prev , 0 );
88
+ add_rdy (prev , 0 );
90
89
sch .running = rdy ;
91
90
rdy -> state = RUN ;
92
- pthread_cond_signal ( & (rdy -> cond ));
91
+ pthread_cond_signal ( & (rdy -> cond ));
93
92
while (prev -> state != RUN )
94
- pthread_cond_wait ( & (prev -> cond ), & sch .mutex );
95
- pthread_mutex_unlock (& sch .mutex );
93
+ pthread_cond_wait ( & (prev -> cond ), & sch .mutex );
94
+ pthread_mutex_unlock (& sch .mutex );
96
95
return NULL ;
97
96
}
98
97
99
- if (sch .running -> priority < rdy -> priority ) {
98
+ if (sch .running -> priority < rdy -> priority ) {
100
99
sch .running -> clk = 0 ;
101
100
prev -> state = RDY ;
102
101
sch .running = rdy ;
103
- add_rdy (prev , 0 );
102
+ add_rdy (prev , 0 );
104
103
rdy -> state = RUN ;
105
- pthread_cond_signal ( & (rdy -> cond ));
104
+ pthread_cond_signal ( & (rdy -> cond ));
106
105
while (prev -> state != RUN )
107
- pthread_cond_wait ( & (prev -> cond ), & sch .mutex );
108
- pthread_mutex_unlock (& sch .mutex );
106
+ pthread_cond_wait ( & (prev -> cond ), & sch .mutex );
107
+ pthread_mutex_unlock (& sch .mutex );
109
108
return NULL ;
110
109
}
111
110
112
- add_rdy (rdy , 1 );
113
- pthread_mutex_unlock (& sch .mutex );
111
+ add_rdy (rdy , 1 );
112
+ pthread_mutex_unlock (& sch .mutex );
114
113
return NULL ;
115
114
}
116
115
117
- int so_init (unsigned int quantum , unsigned int io ) {
116
+ int so_init (unsigned int quantum , unsigned int io ) {
118
117
// check params
119
- if (io > SO_MAX_NUM_EVENTS || quantum <= 0 || init_protect )
118
+ if (io > SO_MAX_NUM_EVENTS || quantum <= 0 || init_protect )
120
119
return -1 ;
121
120
init_protect = 1 ; // protect double init
122
121
123
122
sch .sched_quantum = quantum ;
124
123
sch .sched_io = io ;
125
124
sch .running = NULL ;
126
125
127
- sch .ready = malloc (6 * sizeof (queue * ));
128
- for (int i = 0 ; i < 6 ; i ++ ) {
129
- sch .ready [i ] = malloc (sizeof (queue ));
126
+ sch .ready = malloc (6 * sizeof (queue * ));
127
+ for (int i = 0 ; i < 6 ; i ++ ) {
128
+ sch .ready [i ] = malloc (sizeof (queue ));
130
129
sch .ready [i ]-> size = 0 ;
131
130
sch .ready [i ]-> head = sch .ready [i ]-> tail = NULL ;
132
131
}
133
132
134
- return pthread_mutex_init (& sch .mutex , NULL );
133
+ return pthread_mutex_init (& sch .mutex , NULL );
135
134
}
136
135
137
- void so_end () {
138
- if (init_protect ) {
139
- for (int i = 0 ; i < sch .all .no_of_th ; i ++ ) {
140
- if (sch .all .threads [i ]-> state != TERM ) {
141
- pthread_join (sch .all .threads [i ]-> tid , NULL );
142
- }
143
- pthread_cond_destroy (& (sch .all .threads [i ]-> cond ));
144
- free (sch .all .threads [i ]);
136
+ void so_end () {
137
+ if (init_protect ) {
138
+ for (int i = 0 ; i < sch .all .no_of_th ; i ++ ) {
139
+ if (sch .all .threads [i ]-> state != TERM )
140
+ pthread_join (sch .all .threads [i ]-> tid , NULL );
141
+ pthread_cond_destroy (& (sch .all .threads [i ]-> cond ));
142
+ free (sch .all .threads [i ]);
145
143
}
146
- free (sch .all .threads );
144
+ free (sch .all .threads );
147
145
148
- for (int i = 0 ; i < 6 ; i ++ ) {
146
+ for (int i = 0 ; i < 6 ; i ++ ) {
149
147
node * aux = sch .ready [i ]-> tail ;
150
- while (aux ) {
148
+ while (aux ) {
151
149
node * temp = aux ;
152
150
aux = aux -> next ;
153
- free (temp );
151
+ free (temp );
154
152
}
155
- free (sch .ready [i ]);
153
+ free (sch .ready [i ]);
156
154
}
157
- free (sch .ready );
155
+ free (sch .ready );
158
156
159
- for (int i = 0 ; i < sch .waiting .no_of_th ; i ++ )
160
- free (sch .waiting .threads [i ]);
161
- free (sch .waiting .threads );
157
+ for (int i = 0 ; i < sch .waiting .no_of_th ; i ++ )
158
+ free (sch .waiting .threads [i ]);
159
+ free (sch .waiting .threads );
162
160
}
163
161
164
162
init_protect = 0 ;
165
- pthread_mutex_destroy (& (sch .mutex ));
166
- return ;
163
+ pthread_mutex_destroy (& (sch .mutex ));
167
164
}
168
165
169
- int so_wait (unsigned int io ) {
170
- if (io >= sch .sched_io || io < 0 )
166
+ int so_wait (unsigned int io ) {
167
+ if (io >= sch .sched_io || io < 0 )
171
168
return -1 ;
172
169
173
- pthread_mutex_lock (& sch .mutex );
170
+ pthread_mutex_lock (& sch .mutex );
174
171
// add to waiting list
175
172
sch .running -> waiting_io = io ;
176
- if (sch .waiting .no_of_th == 0 ) {
177
- sch .waiting .threads = malloc (sizeof (my_thread * ));
173
+ if (sch .waiting .no_of_th == 0 ) {
174
+ sch .waiting .threads = malloc (sizeof (my_thread * ));
178
175
} else {
179
- my_thread * * temp = realloc (sch .waiting .threads , sizeof (my_thread * ) * (sch .waiting .no_of_th + 1 ));
176
+ my_thread * * temp = realloc (sch .waiting .threads , sizeof (my_thread * ) * (sch .waiting .no_of_th + 1 ));
180
177
sch .waiting .threads = temp ;
181
178
}
182
179
sch .waiting .threads [sch .waiting .no_of_th ] = sch .running ;
183
180
sch .waiting .no_of_th ++ ;
184
181
185
182
// switch running thread
186
183
my_thread * prev = sch .running ;
187
- my_thread * rdy = get_rdy ();
184
+ my_thread * rdy = get_rdy ();
188
185
189
186
sch .running -> clk = 0 ;
190
187
prev -> state = WAIT ;
191
188
sch .running = rdy ;
192
189
rdy -> state = RUN ;
193
- pthread_cond_signal ( & (rdy -> cond ));
190
+ pthread_cond_signal ( & (rdy -> cond ));
194
191
while (prev -> state != RUN )
195
- pthread_cond_wait ( & (prev -> cond ), & sch .mutex );
196
- pthread_mutex_unlock (& sch .mutex );
192
+ pthread_cond_wait ( & (prev -> cond ), & sch .mutex );
193
+ pthread_mutex_unlock (& sch .mutex );
197
194
198
195
return 0 ;
199
196
}
200
197
201
- int so_signal (unsigned int io ) {
202
- if (io >= sch .sched_io || io < 0 )
198
+ int so_signal (unsigned int io ) {
199
+ if (io >= sch .sched_io || io < 0 )
203
200
return -1 ;
204
-
201
+
205
202
sch .running -> clk ++ ;
206
-
203
+
207
204
int cnt = 0 ;
208
- for (int i = 0 ; i < sch .waiting .no_of_th ; i ++ ) {
209
- if (sch .waiting .threads [i ] && sch .waiting .threads [i ]-> waiting_io == io ) {
205
+ for (int i = 0 ; i < sch .waiting .no_of_th ; i ++ ) {
206
+ if (sch .waiting .threads [i ] && sch .waiting .threads [i ]-> waiting_io == io ) {
210
207
cnt ++ ;
211
- add_rdy (sch .waiting .threads [i ], 0 );
208
+ add_rdy (sch .waiting .threads [i ], 0 );
212
209
sch .waiting .threads [i ] = NULL ;
213
210
}
214
211
}
215
- schedule ();
212
+ schedule ();
216
213
return cnt ;
217
214
}
218
215
219
216
// using pthread_create documentation model
220
- static void * thread_start (void * arg ) {
217
+ static void * thread_start (void * arg ) {
221
218
my_thread * th_arg = arg ;
222
219
so_handler * func = th_arg -> func ;
223
220
224
221
// context switch
225
- pthread_mutex_lock (& sch .mutex );
226
- while (th_arg -> state != RUN )
227
- pthread_cond_wait ( & (th_arg -> cond ), & sch .mutex );
222
+ pthread_mutex_lock (& sch .mutex );
223
+ while (th_arg -> state != RUN )
224
+ pthread_cond_wait ( & (th_arg -> cond ), & sch .mutex );
228
225
sch .running = th_arg ;
229
- pthread_mutex_unlock (& sch .mutex );
230
-
226
+ pthread_mutex_unlock (& sch .mutex );
231
227
232
- func (th_arg -> priority );
228
+ func (th_arg -> priority );
233
229
234
- pthread_mutex_lock (& sch .mutex );
230
+ pthread_mutex_lock (& sch .mutex );
235
231
th_arg -> state = TERM ;
236
232
sch .running = NULL ;
237
- pthread_mutex_unlock (& sch .mutex );
238
-
239
- schedule ();
233
+ pthread_mutex_unlock (& sch .mutex );
234
+
235
+ schedule ();
240
236
return NULL ;
241
237
}
242
238
243
239
244
- tid_t so_fork (so_handler * func , unsigned int priority ) {
245
- if (func == NULL || priority > 5 )
240
+ tid_t so_fork (so_handler * func , unsigned int priority ) {
241
+ if (func == NULL || priority > 5 )
246
242
return INVALID_TID ;
247
243
248
244
// new thread
249
- my_thread * new_thread = malloc (sizeof (* new_thread ));
245
+ my_thread * new_thread = malloc (sizeof (* new_thread ));
250
246
new_thread -> func = func ;
251
247
new_thread -> priority = priority ;
252
248
new_thread -> clk = 0 ;
253
- pthread_cond_init ( & (new_thread -> cond ), NULL );
249
+ pthread_cond_init ( & (new_thread -> cond ), NULL );
254
250
255
251
// create -> tid = id; NULL = def attr; thread_start func; func params
256
- if (pthread_create ( & (new_thread -> tid ), NULL , thread_start , (void * )new_thread ) < 0 )
252
+ if (pthread_create ( & (new_thread -> tid ), NULL , thread_start , (void * )new_thread ) < 0 )
257
253
return INVALID_TID ;
258
254
259
255
// add to thread list
260
- pthread_mutex_lock (& sch .mutex );
261
- if (sch .all .no_of_th == 0 ) {
262
- sch .all .threads = malloc (sizeof (my_thread * ));
256
+ pthread_mutex_lock (& sch .mutex );
257
+ if (sch .all .no_of_th == 0 ) {
258
+ sch .all .threads = malloc (sizeof (my_thread * ));
263
259
} else {
264
- my_thread * * temp = realloc (sch .all .threads , sizeof (my_thread * ) * (sch .all .no_of_th + 1 ));
260
+ my_thread * * temp = realloc (sch .all .threads , sizeof (my_thread * ) * (sch .all .no_of_th + 1 ));
265
261
sch .all .threads = temp ;
266
262
}
267
263
sch .all .threads [sch .all .no_of_th ] = new_thread ;
268
264
sch .all .no_of_th ++ ;
269
-
270
- add_rdy (new_thread , 0 );
271
- if (sch .running ) {
265
+
266
+ add_rdy (new_thread , 0 );
267
+ if (sch .running )
272
268
sch .running -> clk ++ ;
273
- }
274
- pthread_mutex_unlock (& sch .mutex );
275
- schedule ();
269
+ pthread_mutex_unlock (& sch .mutex );
270
+ schedule ();
276
271
277
272
return new_thread -> tid ;
278
273
}
279
274
280
- void so_exec () {
275
+ void so_exec () {
281
276
sch .running -> clk ++ ;
282
- if (sch .running -> clk == sch .sched_quantum ) {
283
- schedule ();
284
- }
277
+ if (sch .running -> clk == sch .sched_quantum )
278
+ schedule ();
285
279
return ;
286
280
}
0 commit comments