-
Notifications
You must be signed in to change notification settings - Fork 1
/
Kernel.java
287 lines (261 loc) · 9.94 KB
/
Kernel.java
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
import java.util.*;
import java.lang.reflect.*;
import java.io.*;
/* Some minor changes by Brendan Sweeney */
public class Kernel
{
// Interrupt requests
public final static int INTERRUPT_SOFTWARE = 1; // System calls
public final static int INTERRUPT_DISK = 2; // Disk interrupts
public final static int INTERRUPT_IO = 3; // Other I/O interrupts
// System calls
public final static int BOOT = 0; // SysLib.boot( )
public final static int EXEC = 1; // SysLib.exec(String args[])
public final static int WAIT = 2; // SysLib.join( )
public final static int EXIT = 3; // SysLib.exit( )
public final static int SLEEP = 4; // SysLib.sleep(int milliseconds)
public final static int RAWREAD = 5; // SysLib.rawread(int blk, byte b[])
public final static int RAWWRITE= 6; // SysLib.rawwrite(int blk, byte b[])
public final static int SYNC = 7; // SysLib.sync( )
public final static int READ = 8; // SysLib.cin( )
public final static int WRITE = 9; // SysLib.cout( ) and SysLib.cerr( )
// System calls to be added in Assignment 4
public final static int CREAD = 10; // SysLib.cread(int blk, byte b[])
public final static int CWRITE = 11; // SysLib.cwrite(int blk, byte b[])
public final static int CSYNC = 12; // SysLib.csync( )
public final static int CFLUSH = 13; // SysLib.cflush( )
// System calls to be added in Project
public final static int OPEN = 14; // SysLib.open( String fileName )
public final static int CLOSE = 15; // SysLib.close( int fd )
public final static int SIZE = 16; // SysLib.size( int fd )
public final static int SEEK = 17; // SysLib.seek( int fd, int offest,
// int whence )
public final static int FORMAT = 18; // SysLib.format( int files )
public final static int DELETE = 19; // SysLib.delete( String fileName )
// Predefined file descriptors
public final static int STDIN = 0;
public final static int STDOUT = 1;
public final static int STDERR = 2;
// Return values
public final static int OK = 0;
public final static int ERROR = -1;
// System thread references
private static Scheduler scheduler;
private static Disk disk;
private static Cache cache;
// Synchronized Queues
private static SyncQueue waitQueue; // for threads to wait for their child
private static SyncQueue ioQueue; // I/O queue
private final static int COND_DISK_REQ = 1; // wait condition
private final static int COND_DISK_FIN = 2; // wait condition
// Standard input
private static BufferedReader input
= new BufferedReader( new InputStreamReader( System.in ) );
// File System
private static FileSystem fs;
// The heart of Kernel
public static int interrupt( int irq, int cmd, int param, Object args ) {
TCB myTcb;
switch( irq ) {
case INTERRUPT_SOFTWARE: // System calls
switch( cmd ) {
case BOOT:
// instantiate and start a scheduler
scheduler = new Scheduler( );
scheduler.start( );
// instantiate and start a disk
disk = new Disk( 1000 );
disk.start( );
// instantiate a cache memory
cache = new Cache( disk.blockSize, 10 );
// instantiate synchronized queues
ioQueue = new SyncQueue( );
waitQueue = new SyncQueue( scheduler.getMaxThreads( ) );
// instantiate a file system
fs = new FileSystem(1000);
return OK;
case EXEC:
return sysExec( ( String[] )args );
case WAIT:
if ( ( myTcb = scheduler.getMyTcb( ) ) != null ) {
int myTid = myTcb.getTid( ); // get my thread ID
return waitQueue.enqueueAndSleep( myTid ); //wait on my tid
// woken up by my child thread
}
return ERROR;
case EXIT:
if ( ( myTcb = scheduler.getMyTcb( ) ) != null ) {
int myPid = myTcb.getPid( ); // get my parent ID
int myTid = myTcb.getTid( ); // get my ID
if ( myPid != -1 ) {
// wake up a thread waiting on my parent ID
waitQueue.dequeueAndWakeup( myPid, myTid );
// I'm terminated!
scheduler.deleteThread( );
return OK;
}
}
return ERROR;
case SLEEP: // sleep a given period of milliseconds
scheduler.sleepThread( param ); // param = milliseconds
return OK;
case RAWREAD: // read a block of data from disk
while ( disk.read( param, ( byte[] )args ) == false )
ioQueue.enqueueAndSleep( COND_DISK_REQ );
while ( disk.testAndResetReady( ) == false )
ioQueue.enqueueAndSleep( COND_DISK_FIN );
return OK;
case RAWWRITE: // write a block of data to disk
while ( disk.write( param, ( byte[] )args ) == false )
ioQueue.enqueueAndSleep( COND_DISK_REQ );
while ( disk.testAndResetReady( ) == false )
ioQueue.enqueueAndSleep( COND_DISK_FIN );
return OK;
case SYNC: // synchronize disk data to a real file
while(fs.sync() == false)
ioQueue.enqueueAndSleep(COND_DISK_REQ);
while ( disk.sync( ) == false )
ioQueue.enqueueAndSleep( COND_DISK_REQ );
while ( disk.testAndResetReady( ) == false )
ioQueue.enqueueAndSleep( COND_DISK_FIN );
return OK;
case READ:
switch ( param ) {
case STDIN:
try {
String s = input.readLine(); // read a keyboard input
if ( s == null ) {
return ERROR;
}
// prepare a read buffer
StringBuffer buf = ( StringBuffer )args;
// append the keyboard intput to this read buffer
buf.append( s );
// return the number of chars read from keyboard
return s.length( );
} catch ( IOException e ) {
System.out.println( e );
return ERROR;
}
case STDOUT:
case STDERR:
System.out.println( "threaOS: caused read errors" );
return ERROR;
}
if ((myTcb = scheduler.getMyTcb()) != null)
return fs.read(myTcb.getFtEnt(param), (byte[])args);
return ERROR;
case WRITE:
switch ( param ) {
case STDIN:
System.out.println( "threaOS: cannot write to System.in" );
return ERROR;
case STDOUT:
System.out.print( (String)args );
return OK;
case STDERR:
System.err.print( (String)args );
return OK;
}
if ((myTcb = scheduler.getMyTcb()) != null)
return fs.write(myTcb.getFtEnt(param), (byte[])args);
return ERROR;
case CREAD: // to be implemented in assignment 4
return cache.read( param, ( byte[] )args ) ? OK : ERROR;
case CWRITE: // to be implemented in assignment 4
return cache.write( param, ( byte[] )args ) ? OK : ERROR;
case CSYNC: // to be implemented in assignment 4
cache.sync( );
return OK;
case CFLUSH: // to be implemented in assignment 4
cache.flush( );
return OK;
case OPEN: // to be implemented in project
if ((myTcb = scheduler.getMyTcb()) != null) {
String[] s = (String[])args;
FileTableEntry ftEnt = fs.open(s[0], s[1]);
return myTcb.getFd(ftEnt);
} // end if (scheduler.getMyTcb()) != null)
return ERROR;
case CLOSE: // to be implemented in project
if ((myTcb = scheduler.getMyTcb()) != null)
return fs.close(myTcb.returnFd(param)) ? OK : ERROR;
return ERROR;
case SIZE: // to be implemented in project
if ((myTcb = scheduler.getMyTcb()) != null)
return fs.fsize(myTcb.getFtEnt(param));
return ERROR;
case SEEK: // to be implemented in project
if ((myTcb = scheduler.getMyTcb()) != null) {
int[] i = (int[])args;
return fs.seek(myTcb.getFtEnt(param), i[0], i[1]);
} // end if (scheduler.getMyTcb()) != null)
return ERROR;
case FORMAT: // to be implemented in project
return fs.format(param) ? OK : ERROR;
case DELETE: // to be implemented in project
return fs.delete((String)args) ? OK : ERROR;
}
return ERROR;
case INTERRUPT_DISK: // Disk interrupts
// wake up the thread waiting for a service completion
ioQueue.dequeueAndWakeup( COND_DISK_FIN );
// wake up the thread waiting for a request acceptance
ioQueue.dequeueAndWakeup( COND_DISK_REQ );
return OK;
case INTERRUPT_IO: // other I/O interrupts (not implemented)
return OK;
}
return OK;
}
// Spawning a new thread
private static int sysExec( String args[] ) {
String thrName = args[0]; // args[0] has a thread name
Object thrObj = null;
try {
//get the user thread class from its name
Class thrClass = Class.forName( thrName );
if ( args.length == 1 ) // no arguments
thrObj = thrClass.newInstance( ); // instantiate this class obj
else { // some arguments
// copy all arguments into thrArgs[] and make a new constructor
// argument object from thrArgs[]
String thrArgs[] = new String[ args.length - 1 ];
for ( int i = 1; i < args.length; i++ )
thrArgs[i - 1] = args[i];
Object[] constructorArgs = new Object[] { thrArgs };
// locate this class object's constructors
Constructor thrConst
= thrClass.getConstructor( new Class[] {String[].class} );
// instantiate this class object by calling this constructor
// with arguments
thrObj = thrConst.newInstance( constructorArgs );
}
// instantiate a new thread of this object
Thread t = new Thread( (Runnable)thrObj );
// add this thread into scheduler's circular list.
TCB newTcb = scheduler.addThread( t );
return ( newTcb != null ) ? newTcb.getTid( ) : ERROR;
}
catch ( ClassNotFoundException e ) {
System.out.println( e );
return ERROR;
}
catch ( NoSuchMethodException e ) {
System.out.println( e );
return ERROR;
}
catch ( InstantiationException e ) {
System.out.println( e );
return ERROR;
}
catch ( IllegalAccessException e ) {
System.out.println( e );
return ERROR;
}
catch ( InvocationTargetException e ) {
System.out.println( e );
return ERROR;
}
}
}