-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.c
128 lines (110 loc) · 3.39 KB
/
utils.c
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
#include "utils.h"
int cmp_readytime_asc(const void *_a, const void *_b)
{
Process *a = (Process *)_a, *b = (Process *)_b;
if (a->ready_time < b->ready_time)
return -1;
else if (a->ready_time > b->ready_time)
return 1;
else if (a->ord < b->ord)
return -1;
else if (a->ord > b->ord)
return 1;
return 0;
}
int get_min_remaining_time_p(Process proc_list[], int N)
{
unsigned long mn = ULONG_MAX;
int ret = -1;
for (int i = 0; i < N; i++) {
if (proc_list[i].state != READY) continue;
if (proc_list[i].remaining_time < mn)
mn = proc_list[i].remaining_time, ret = i;
}
return ret;
}
void proc_set_cpu(pid_t pid, int cpu_id)
{
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
CPU_SET(cpu_id, &cpu_set);
if (sched_setaffinity(pid, sizeof(cpu_set), &cpu_set) != 0)
ERR_EXIT("sched_setaffinity");
}
void proc_start(Process *proc)
{
pid_t pid = fork();
if (pid == 0) { // child process
sched_yield();
// get starting time
long st_sec, st_nsec;
syscall(SYSCALL_GETTIME, &st_sec, &st_nsec);
for (int i = 0; i < proc->exec_time; i++)
TIME_UNIT;
// get finishing time
long ft_sec, ft_nsec;
syscall(SYSCALL_GETTIME, &ft_sec, &ft_nsec);
// print info to dmesg
syscall(SYSCALL_SHOWINFO, getpid(), st_sec, st_nsec, ft_sec, ft_nsec);
exit(EXIT_SUCCESS);
} else if (pid > 0) { // parent process
// set process attributes
proc->pid = pid;
proc->state = READY;
// block the new process immediately
proc_set_cpu(pid, CPU_CHILDREN);
proc_block(proc);
// print to stdout
printf("%s %d\n", proc->name, pid);
fflush(stdout);
} else {
ERR_EXIT("fork");
}
}
void proc_set_priority(pid_t pid, int priority)
{
struct sched_param param;
param.sched_priority = priority;
if (sched_setscheduler(pid, SCHED_FIFO, ¶m) != 0)
ERR_EXIT("sched_setscheduler");
}
void proc_set_other(pid_t pid)
{
struct sched_param param;
param.sched_priority = 0;
if (sched_setscheduler(pid, SCHED_OTHER, ¶m) != 0)
ERR_EXIT("sched_setscheduler");
}
void proc_block(Process *proc)
{
proc_set_other(proc->pid);
proc->state = READY;
}
void proc_wakeup(Process *proc)
{
proc_set_priority(proc->pid, PRIORITY_HIGH);
proc->state = RUNNING;
}
void proc_term(Process *proc)
{
waitpid(proc->pid, NULL, 0);
proc->state = TERMINATED;
}
pid_t proc_dummy()
{
pid_t pid = fork();
if (pid == 0) {
proc_set_cpu(getpid(), CPU_CHILDREN);
proc_set_other(getpid());
nice(-10);
while (1);
return 0;
} else if (pid > 0) {
proc_set_cpu(pid, CPU_CHILDREN);
proc_set_other(pid);
return pid;
} else {
ERR_EXIT("fork");
return -1;
}
}