-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsystem.cc
197 lines (168 loc) · 5.36 KB
/
system.cc
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
// system.cc
// Nachos initialization and cleanup routines.
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved. See copyright.h for copyright notice and limitation
// of liability and disclaimer of warranty provisions.
#include "copyright.h"
#include "system.h"
// This defines *all* of the global data structures used by Nachos.
// These are all initialized and de-allocated by this file.
Thread *currentThread; // the thread we are running now
Thread *threadToBeDestroyed; // the thread that just finished
Scheduler *scheduler; // the ready list
Interrupt *interrupt; // interrupt status
Statistics *stats; // performance metrics
Timer *timer; // the hardware timer device,
// for invoking context switches
#ifdef FILESYS_NEEDED
FileSystem *fileSystem;
#endif
#ifdef FILESYS
SynchDisk *synchDisk;
#endif
#ifdef USER_PROGRAM // requires either FILESYS or FILESYS_STUB
Machine *machine; // user program memory and registers
#endif
#ifdef NETWORK
PostOffice *postOffice;
#endif
// External definition, to allow us to take a pointer to this function
extern void Cleanup();
//----------------------------------------------------------------------
// TimerInterruptHandler
// Interrupt handler for the timer device. The timer device is
// set up to interrupt the CPU periodically (once every TimerTicks).
// This routine is called each time there is a timer interrupt,
// with interrupts disabled.
//
// Note that instead of calling Yield() directly (which would
// suspend the interrupt handler, not the interrupted thread
// which is what we wanted to context switch), we set a flag
// so that once the interrupt handler is done, it will appear as
// if the interrupted thread called Yield at the point it is
// was interrupted.
//
// "dummy" is because every interrupt handler takes one argument,
// whether it needs it or not.
//----------------------------------------------------------------------
static void
TimerInterruptHandler(int dummy)
{
if (interrupt->getStatus() != IdleMode)
interrupt->YieldOnReturn();
}
//----------------------------------------------------------------------
// Initialize
// Initialize Nachos global data structures. Interpret command
// line arguments in order to determine flags for the initialization.
//
// "argc" is the number of command line arguments (including the name
// of the command) -- ex: "nachos -d +" -> argc = 3
// "argv" is an array of strings, one for each command line argument
// ex: "nachos -d +" -> argv = {"nachos", "-d", "+"}
//----------------------------------------------------------------------
void
Initialize(int argc, char **argv)
{
int argCount;
char* debugArgs = "";
bool randomYield = FALSE;
#ifdef USER_PROGRAM
bool debugUserProg = FALSE; // single step user program
#endif
#ifdef FILESYS_NEEDED
bool format = FALSE; // format disk
#endif
#ifdef NETWORK
double rely = 1; // network reliability
int netname = 0; // UNIX socket name
#endif
for (argc--, argv++; argc > 0; argc -= argCount, argv += argCount) {
argCount = 1;
if (!strcmp(*argv, "-d")) {
if (argc == 1)
debugArgs = "+"; // turn on all debug flags
else {
debugArgs = *(argv + 1);
argCount = 2;
}
} else if (!strcmp(*argv, "-rs")) {
ASSERT(argc > 1);
RandomInit(atoi(*(argv + 1))); // initialize pseudo-random
// number generator
randomYield = TRUE;
argCount = 2;
}
#ifdef USER_PROGRAM
if (!strcmp(*argv, "-s"))
debugUserProg = TRUE;
#endif
#ifdef FILESYS_NEEDED
if (!strcmp(*argv, "-f"))
format = TRUE;
#endif
#ifdef NETWORK
if (!strcmp(*argv, "-l")) {
ASSERT(argc > 1);
rely = atof(*(argv + 1));
argCount = 2;
} else if (!strcmp(*argv, "-m")) {
ASSERT(argc > 1);
netname = atoi(*(argv + 1));
argCount = 2;
}
#endif
}
DebugInit(debugArgs); // initialize DEBUG messages
stats = new Statistics(); // collect statistics
interrupt = new Interrupt; // start up interrupt handling
scheduler = new Scheduler(); // initialize the ready queue
if (randomYield) // start the timer (if needed)
timer = new Timer(TimerInterruptHandler, 0, randomYield);
threadToBeDestroyed = NULL;
// We didn't explicitly allocate the current thread we are running in.
// But if it ever tries to give up the CPU, we better have a Thread
// object to save its state.
currentThread = new Thread("main");
currentThread->setStatus(RUNNING);
interrupt->Enable();
CallOnUserAbort(Cleanup); // if user hits ctl-C
#ifdef USER_PROGRAM
machine = new Machine(debugUserProg); // this must come first
#endif
#ifdef FILESYS
synchDisk = new SynchDisk("DISK");
#endif
#ifdef FILESYS_NEEDED
fileSystem = new FileSystem(format);
#endif
#ifdef NETWORK
postOffice = new PostOffice(netname, rely, 10);
#endif
}
//----------------------------------------------------------------------
// Cleanup
// Nachos is halting. De-allocate global data structures.
//----------------------------------------------------------------------
void
Cleanup()
{
printf("\nCleaning up...\n");
#ifdef NETWORK
delete postOffice;
#endif
#ifdef USER_PROGRAM
delete machine;
#endif
#ifdef FILESYS_NEEDED
delete fileSystem;
#endif
#ifdef FILESYS
delete synchDisk;
#endif
delete timer;
delete scheduler;
delete interrupt;
Exit(0);
}