-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutility.c
More file actions
113 lines (86 loc) · 2.56 KB
/
utility.c
File metadata and controls
113 lines (86 loc) · 2.56 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
#include "utility.h"
#include "ts_scheduler.h"
#include <stdio.h>
void __increment_time(void) { ++time_counter; };
void __reset_time(void) { time_counter = 0; };
void ts_barrier_init(TS_BARRIER *barrier, int threshold)
{
barrier->threshold = threshold;
barrier->cond = malloc(sizeof(*barrier->cond));
barrier->mutex = malloc(sizeof(*barrier->mutex));
pthread_cond_init(barrier->cond, NULL);
pthread_mutex_init(barrier->mutex, NULL);
}
void ts_barrier_wait(TS_BARRIER *barrier)
{
static int cnt;
pthread_mutex_lock(barrier->mutex);
++cnt;
if (cnt == barrier->threshold) {
cnt = 0;
pthread_cond_broadcast(barrier->cond);
}
else {
pthread_cond_wait(barrier->cond, barrier->mutex);
}
pthread_mutex_unlock(barrier->mutex);
}
void ts_barrier_destroy(TS_BARRIER *barrier)
{
pthread_cond_destroy(barrier->cond);
pthread_mutex_destroy(barrier->mutex);
free(barrier->cond);
free(barrier->mutex);
free(barrier);
}
TS_THREAD *ts_get_thread(void)
{
int curr_max_priority = TS_MAX_PRIO;
while(cq_is_empty(&ready_threads[curr_max_priority])) {
if (--curr_max_priority < 0)
return NULL;
}
return (TS_THREAD*)cq_pop(&ready_threads[curr_max_priority]);
}
void *start_thread(void *params)
{
TS_TH_PARAMS *aux = (TS_TH_PARAMS*)params;
so_handler *func = aux->func;
unsigned int priority = aux->priority;
pthread_cond_t *cond = aux->cond;
TS_BARRIER *barr = aux->barr;
pthread_mutex_lock(&mutex);
ts_barrier_wait(barr);
pthread_cond_wait(cond, &mutex);
pthread_mutex_unlock(&mutex);
func(priority);
running = ts_get_thread();
__reset_time();
if(running != NULL)
pthread_cond_signal(running->cond);
return NULL;
}
void ts_preempt(void)
{
TS_THREAD *next_thread;
TS_THREAD *current_thread;
if (time_counter == time_quantum) {
current_thread = running;
next_thread = ts_get_thread();
if (next_thread != NULL && next_thread->priority >= current_thread->priority) {
running = next_thread;
__reset_time();
cq_push(&ready_threads[current_thread->priority], current_thread);
pthread_mutex_lock(&mutex);
pthread_cond_signal(running->cond);
pthread_cond_wait(current_thread->cond, &mutex);
pthread_mutex_unlock(&mutex);
}
else {
__reset_time();
if (next_thread != NULL) {
cq_push_front(&ready_threads[next_thread->priority], next_thread);
}
}
}
}