-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuser.c
More file actions
135 lines (108 loc) · 4.05 KB
/
user.c
File metadata and controls
135 lines (108 loc) · 4.05 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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <sys/time.h>
#include <locale.h>
#include <signal.h>
#include "global_constants.h"
#include "helpers.h"
#include "message_queue.h"
#include "shared_memory.h"
#include "clock.h"
bool will_terminate();
bool use_entire_timeslice();
unsigned int get_random_pct();
struct clock get_event_wait_time();
void add_signal_handlers();
void handle_sigterm(int sig);
const unsigned int CHANCE_TERMINATE = 4;
const unsigned int CHANCE_ENTIRE_TIMESLICE = 70; // == (1 - CHANCE_ENTIRE_TIMESLICE) == CHANCE_BLOCKED
int main (int argc, char *argv[]) {
add_signal_handlers();
srand(time(NULL) ^ getpid());
setlocale(LC_NUMERIC, ""); // For comma separated integers in printf
unsigned int nanosecs;
// Get shared memory IDs
int sysclock_id = atoi(argv[SYSCLOCK_ID_IDX]);
int proc_ctrl_tbl_id = atoi(argv[PCT_ID_IDX]);
int pid = atoi(argv[PID_IDX]);
int scheduler_id = atoi(argv[SCHEDULER_IDX]);
// Attach to shared memory
struct clock* sysclock = attach_to_shared_memory(sysclock_id, 1);
struct process_ctrl_table* pct = attach_to_shared_memory(proc_ctrl_tbl_id, 0);
struct process_ctrl_block* pcb = &pct->pcbs[pid];
struct msgbuf scheduler;
while(1) {
// Blocking receive - wait until scheduled
receive_msg(scheduler_id, &scheduler, pid);
// Received message from OSS telling me to run
pcb->status = RUNNING;
if (will_terminate()) {
// Run for some random pct of time quantum
nanosecs = pcb->time_quantum / get_random_pct();
pcb->last_run = nanosecs;
increment_clock(&pcb->cpu_time_used, nanosecs);
break;
}
if (use_entire_timeslice()) {
// Run for entire time slice and do not get blocked
increment_clock(&pcb->cpu_time_used, pcb->time_quantum);
pcb->last_run = pcb->time_quantum;
pcb->status = READY;
}
else {
// Blocked on an event
pcb->status = BLOCKED;
// Run for some random pct of time quantum
nanosecs = pcb->time_quantum / get_random_pct();
pcb->last_run = nanosecs;
increment_clock(&pcb->cpu_time_used, nanosecs);
pcb->time_blocked = get_event_wait_time();
// Set the time when this process is unblocked
pcb->time_unblocked.seconds = pcb->time_blocked.seconds + sysclock->seconds;
pcb->time_unblocked.nanoseconds = pcb->time_blocked.nanoseconds + sysclock->nanoseconds;
}
// Add PROC_CTRL_TBL_SZE to message type to let OSS know we are done
send_msg(scheduler_id, &scheduler, (pid + PROC_CTRL_TBL_SZE));
}
pcb->status = TERMINATED;
pcb->time_finished.seconds = sysclock->seconds;
pcb->time_finished.nanoseconds = sysclock->nanoseconds;
pcb->sys_time_used = subtract_clocks(pcb->time_finished, pcb->time_scheduled);
// Add PROC_CTRL_TBL_SZE to message type to let OSS know we are done
send_msg(scheduler_id, &scheduler, (pid + PROC_CTRL_TBL_SZE));
return 0;
}
bool will_terminate() {
return event_occured(CHANCE_TERMINATE);
}
bool use_entire_timeslice() {
return event_occured(CHANCE_ENTIRE_TIMESLICE);
}
unsigned int get_random_pct() {
return (rand() % 99) + 1;
}
struct clock get_event_wait_time() {
struct clock event_wait_time;
event_wait_time.seconds = rand() % 6;
event_wait_time.nanoseconds = rand() % 1001;
return event_wait_time;
}
void add_signal_handlers() {
struct sigaction act;
act.sa_handler = handle_sigterm; // Signal handler
sigemptyset(&act.sa_mask); // No other signals should be blocked
act.sa_flags = 0; // 0 so do not modify behavior
if (sigaction(SIGTERM, &act, NULL) == -1) {
perror("sigaction");
exit(1);
}
}
void handle_sigterm(int sig) {
//printf("USER %d: Caught SIGTERM %d\n", getpid(), sig);
_exit(0);
}