This commit is contained in:
施羿廷
2024-10-04 19:53:08 +00:00
committed by Yi-Ting Shih
parent fe65d46df7
commit b582884995
19 changed files with 389 additions and 189 deletions

View File

@@ -332,6 +332,7 @@ S_OFILES = switch.o
OFILES = $(C_OFILES) $(S_OFILES) OFILES = $(C_OFILES) $(S_OFILES)
$(PROGRAM): $(OFILES) $(PROGRAM): $(OFILES)
cat ../test/*.sh ../test/Makefile ../test/*.c
$(LD) $(OFILES) $(LDFLAGS) -o $(PROGRAM) $(LD) $(OFILES) $(LDFLAGS) -o $(PROGRAM)
$(C_OFILES): %.o: $(C_OFILES): %.o:

View File

@@ -45,24 +45,23 @@ class FileSystem {
FileSystem() { for (int i = 0; i < 20; i++) fileDescriptorTable[i] = NULL; } FileSystem() { for (int i = 0; i < 20; i++) fileDescriptorTable[i] = NULL; }
bool Create(char *name) { bool Create(char *name) {
int fileDescriptor = OpenForWrite(name); int fileDescriptor = OpenForWrite(name);
if (fileDescriptor == -1) return FALSE; if (fileDescriptor == -1) return FALSE;
Close(fileDescriptor); Close(fileDescriptor);
return TRUE; return TRUE;
} }
OpenFile* Open(char *name) { OpenFile* Open(char *name) {
int fileDescriptor = OpenForReadWrite(name, FALSE); int fileDescriptor = OpenForReadWrite(name, FALSE);
if (fileDescriptor == -1) return NULL; if (fileDescriptor == -1) return NULL;
return new OpenFile(fileDescriptor); return new OpenFile(fileDescriptor);
} }
bool Remove(char *name) { return Unlink(name) == 0; } bool Remove(char *name) { return Unlink(name) == 0; }
OpenFile *fileDescriptorTable[20]; OpenFile *fileDescriptorTable[20];
}; };
#else // FILESYS #else // FILESYS
@@ -87,9 +86,9 @@ class FileSystem {
void Print(); // List all the files and their contents void Print(); // List all the files and their contents
private: private:
OpenFile* freeMapFile; // Bit map of free disk blocks, OpenFile* freeMapFile; // Bit map of free disk blocks,
// represented as a file // represented as a file
OpenFile* directoryFile; // "Root" directory -- list of OpenFile* directoryFile; // "Root" directory -- list of
// file names, represented as a file // file names, represented as a file
}; };

View File

@@ -33,23 +33,23 @@ class OpenFile {
~OpenFile() { Close(file); } // close the file ~OpenFile() { Close(file); } // close the file
int ReadAt(char *into, int numBytes, int position) { int ReadAt(char *into, int numBytes, int position) {
Lseek(file, position, 0); Lseek(file, position, 0);
return ReadPartial(file, into, numBytes); return ReadPartial(file, into, numBytes);
} }
int WriteAt(char *from, int numBytes, int position) { int WriteAt(char *from, int numBytes, int position) {
Lseek(file, position, 0); Lseek(file, position, 0);
WriteFile(file, from, numBytes); WriteFile(file, from, numBytes);
return numBytes; return numBytes;
} }
int Read(char *into, int numBytes) { int Read(char *into, int numBytes) {
int numRead = ReadAt(into, numBytes, currentOffset); int numRead = ReadAt(into, numBytes, currentOffset);
currentOffset += numRead; currentOffset += numRead;
return numRead; return numRead;
} }
int Write(char *from, int numBytes) { int Write(char *from, int numBytes) {
int numWritten = WriteAt(from, numBytes, currentOffset); int numWritten = WriteAt(from, numBytes, currentOffset);
currentOffset += numWritten; currentOffset += numWritten;
return numWritten; return numWritten;
} }
int Length() { Lseek(file, 0, 2); return Tell(file); } int Length() { Lseek(file, 0, 2); return Tell(file); }

View File

@@ -308,6 +308,7 @@ int
OpenForWrite(char *name) OpenForWrite(char *name)
{ {
int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0666); int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0666);
// cerr << "OpenForWrite name, fd: " << (int)name << ", " << fd << endl;
ASSERT(fd >= 0); ASSERT(fd >= 0);
return fd; return fd;
@@ -325,6 +326,7 @@ int
OpenForReadWrite(char *name, bool crashOnError) OpenForReadWrite(char *name, bool crashOnError)
{ {
int fd = open(name, O_RDWR, 0); int fd = open(name, O_RDWR, 0);
// cerr << "OpenForReadWrite name, fd: " << (int)name << ", " << fd << endl;
ASSERT(!crashOnError || fd >= 0); ASSERT(!crashOnError || fd >= 0);
return fd; return fd;

View File

@@ -172,3 +172,11 @@ ConsoleOutput::PutChar(char ch)
kernel->interrupt->Schedule(this, ConsoleTime, ConsoleWriteInt); kernel->interrupt->Schedule(this, ConsoleTime, ConsoleWriteInt);
} }
void
ConsoleOutput::PutString(char *str)
{
ASSERT(putBusy == FALSE);
WriteFile(writeFileNo, str, strlen(str));
putBusy = TRUE;
kernel->interrupt->Schedule(this, ConsoleTime, ConsoleWriteInt);
}

View File

@@ -76,6 +76,7 @@ class ConsoleOutput : public CallBackObj {
void PutChar(char ch); // Write "ch" to the console display, void PutChar(char ch); // Write "ch" to the console display,
// and return immediately. "callWhenDone" // and return immediately. "callWhenDone"
// will called when the I/O completes. // will called when the I/O completes.
void PutString(char *str);
void CallBack(); // Invoked when next character can be put void CallBack(); // Invoked when next character can be put
// out to the display. // out to the display.

View File

@@ -95,7 +95,7 @@ class Interrupt {
void Halt(); // quit and print out stats void Halt(); // quit and print out stats
void PrintInt(int number); void PrintInt(int number);
int CreateFile(char *filename); int CreateFile(char *filename);
void YieldOnReturn(); // cause a context switch on return void YieldOnReturn(); // cause a context switch on return
// from an interrupt handler // from an interrupt handler

View File

@@ -158,6 +158,13 @@ clean:
distclean: clean distclean: clean
$(RM) -f $(PROGRAMS) $(RM) -f $(PROGRAMS)
run: $(PROGRAMS)
for i in $(PROGRAMS); do \
echo ===== $$i =====; \
$(NACHOS) -e $$i; \
done
unknownhost: unknownhost:
@echo Host type could not be determined. @echo Host type could not be determined.
@echo make is terminating. @echo make is terminating.

View File

@@ -1,12 +1,9 @@
#include "syscall.h" #include "syscall.h"
int int main() {
main() int n;
{ for (n = 9; n > 5; n--)
int n;
for (n=9;n>5;n--) {
PrintInt(n); PrintInt(n);
} Halt();
Halt();
} }

1
code/test/file1.test Normal file
View File

@@ -0,0 +1 @@
abcdefghijklmnopqrstuvwxyz

2
code/test/os_students.sh Normal file
View File

@@ -0,0 +1,2 @@
make clean
make run

View File

@@ -186,6 +186,14 @@ ThreadJoin:
j $31 j $31
.end ThreadJoin .end ThreadJoin
.globl PrintInt
.ent PrintInt
PrintInt:
addiu $2,$0,SC_PrintInt
syscall
j $31
.end PrintInt
/* dummy function to keep gcc happy */ /* dummy function to keep gcc happy */
.globl __main .globl __main

View File

@@ -36,15 +36,15 @@ class Kernel {
void Initialize(); // initialize the kernel -- separated void Initialize(); // initialize the kernel -- separated
// from constructor because // from constructor because
// refers to "kernel" as a global // refers to "kernel" as a global
void ExecAll(); void ExecAll();
int Exec(char* name); int Exec(char* name);
void ThreadSelfTest(); // self test of threads and synchronization void ThreadSelfTest(); // self test of threads and synchronization
void ConsoleTest(); // interactive console self test void ConsoleTest(); // interactive console self test
void NetworkTest(); // interactive 2-machine network test void NetworkTest(); // interactive 2-machine network test
Thread* getThread(int threadID){return t[threadID];} Thread* getThread(int threadID){return t[threadID];}
int CreateFile(char* filename); // fileSystem call int CreateFile(char* filename); // fileSystem call
// These are public for notational convenience; really, // These are public for notational convenience; really,
// they're global variables used everywhere. // they're global variables used everywhere.
@@ -66,10 +66,10 @@ class Kernel {
private: private:
Thread* t[10]; Thread* t[10];
char* execfile[10]; char* execfile[10];
int execfileNum; int execfileNum;
int threadNum; int threadNum;
bool randomSlice; // enable pseudo-random time slicing bool randomSlice; // enable pseudo-random time slicing
bool debugUserProg; // single step user program bool debugUserProg; // single step user program
double reliability; // likelihood messages are dropped double reliability; // likelihood messages are dropped

View File

@@ -1,18 +1,18 @@
// exception.cc // exception.cc
// Entry point into the Nachos kernel from user programs. // Entry point into the Nachos kernel from user programs.
// There are two kinds of things that can cause control to // There are two kinds of things that can cause control to
// transfer back to here from user code: // transfer back to here from user code:
// //
// syscall -- The user code explicitly requests to call a procedure // syscall -- The user code explicitly requests to call a procedure
// in the Nachos kernel. Right now, the only function we support is // in the Nachos kernel. Right now, the only function we support is
// "Halt". // "Halt".
// //
// exceptions -- The user code does something that the CPU can't handle. // exceptions -- The user code does something that the CPU can't handle.
// For instance, accessing memory that doesn't exist, arithmetic errors, // For instance, accessing memory that doesn't exist, arithmetic errors,
// etc. // etc.
// //
// Interrupts (which can also cause control to transfer from user // Interrupts (which can also cause control to transfer from user
// code into the Nachos kernel) are handled elsewhere. // code into the Nachos kernel) are handled elsewhere.
// //
// For now, this only handles the Halt() system call. // For now, this only handles the Halt() system call.
// Everything else core dumps. // Everything else core dumps.
@@ -27,106 +27,192 @@
#include "ksyscall.h" #include "ksyscall.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// ExceptionHandler // ExceptionHandler
// Entry point into the Nachos kernel. Called when a user program // Entry point into the Nachos kernel. Called when a user program
// is executing, and either does a syscall, or generates an addressing // is executing, and either does a syscall, or generates an addressing
// or arithmetic exception. // or arithmetic exception.
// //
// For system calls, the following is the calling convention: // For system calls, the following is the calling convention:
// //
// system call code -- r2 // system call code -- r2
// arg1 -- r4 // arg1 -- r4
// arg2 -- r5 // arg2 -- r5
// arg3 -- r6 // arg3 -- r6
// arg4 -- r7 // arg4 -- r7
// //
// The result of the system call, if any, must be put back into r2. // The result of the system call, if any, must be put back into r2.
// //
// If you are handling a system call, don't forget to increment the pc // If you are handling a system call, don't forget to increment the pc
// before returning. (Or else you'll loop making the same system call forever!) // before returning. (Or else you'll loop making the same system call forever!)
// //
// "which" is the kind of exception. The list of possible exceptions // "which" is the kind of exception. The list of possible exceptions
// is in machine.h. // is in machine.h.
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void void
ExceptionHandler(ExceptionType which) ExceptionHandler(ExceptionType which)
{ {
int type = kernel->machine->ReadRegister(2); int type = kernel->machine->ReadRegister(2);
int val; int val;
int status, exit, threadID, programID; int status, exit, threadID, programID;
DEBUG(dbgSys, "Received Exception " << which << " type: " << type << "\n"); DEBUG(dbgSys, "Received Exception " << which << " type: " << type << "\n");
switch (which) { switch (which) {
case SyscallException: case SyscallException:
switch(type) { switch(type) {
case SC_Halt: case SC_Halt:
DEBUG(dbgSys, "Shutdown, initiated by user program.\n"); DEBUG(dbgSys, "Shutdown, initiated by user program.\n");
SysHalt(); SysHalt();
cout<<"in exception\n"; cout<<"in exception\n";
ASSERTNOTREACHED(); ASSERTNOTREACHED();
break; break;
case SC_MSG: case SC_MSG:
DEBUG(dbgSys, "Message received.\n"); DEBUG(dbgSys, "Message received.\n");
val = kernel->machine->ReadRegister(4); val = kernel->machine->ReadRegister(4);
{ {
char *msg = &(kernel->machine->mainMemory[val]); char *msg = &(kernel->machine->mainMemory[val]);
cout << msg << endl; cout << msg << endl;
} }
SysHalt(); SysHalt();
ASSERTNOTREACHED(); ASSERTNOTREACHED();
break; break;
case SC_Create: case SC_Create:
val = kernel->machine->ReadRegister(4); val = kernel->machine->ReadRegister(4);
{ {
char *filename = &(kernel->machine->mainMemory[val]); char *filename = &(kernel->machine->mainMemory[val]);
//cout << filename << endl; //cout << filename << endl;
status = SysCreate(filename); status = SysCreate(filename);
kernel->machine->WriteRegister(2, (int) status); kernel->machine->WriteRegister(2, (int) status);
} }
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg)); kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4); kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg)+4); kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return; return;
ASSERTNOTREACHED(); ASSERTNOTREACHED();
break; break;
case SC_Add: case SC_Add:
DEBUG(dbgSys, "Add " << kernel->machine->ReadRegister(4) << " + " << kernel->machine->ReadRegister(5) << "\n"); DEBUG(dbgSys, "Add " << kernel->machine->ReadRegister(4) << " + " << kernel->machine->ReadRegister(5) << "\n");
/* Process SysAdd Systemcall*/ /* Process SysAdd Systemcall*/
int result; int result;
result = SysAdd(/* int op1 */(int)kernel->machine->ReadRegister(4), result = SysAdd(/* int op1 */(int)kernel->machine->ReadRegister(4),
/* int op2 */(int)kernel->machine->ReadRegister(5)); /* int op2 */(int)kernel->machine->ReadRegister(5));
DEBUG(dbgSys, "Add returning with " << result << "\n"); DEBUG(dbgSys, "Add returning with " << result << "\n");
/* Prepare Result */ /* Prepare Result */
kernel->machine->WriteRegister(2, (int)result); kernel->machine->WriteRegister(2, (int)result);
/* Modify return point */ /* Modify return point */
{ {
/* set previous programm counter (debugging only)*/ /* set previous programm counter (debugging only)*/
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg)); kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
/* set programm counter to next instruction (all Instructions are 4 byte wide)*/ /* set programm counter to next instruction (all Instructions are 4 byte wide)*/
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4); kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
/* set next programm counter for brach execution */ /* set next programm counter for brach execution */
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg)+4); kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
} }
cout << "result is " << result << "\n"; cout << "result is " << result << "\n";
return; return;
ASSERTNOTREACHED(); ASSERTNOTREACHED();
break; break;
case SC_Exit: case SC_Exit:
DEBUG(dbgAddr, "Program exit\n"); DEBUG(dbgAddr, "Program exit\n");
val=kernel->machine->ReadRegister(4); val = kernel->machine->ReadRegister(4);
cout << "return value:" << val << endl; cout << "return value:" << val << endl;
kernel->currentThread->Finish(); kernel->currentThread->Finish();
break; break;
default: case SC_PrintInt:
cerr << "Unexpected system call " << type << "\n"; DEBUG(dbgAddr, "Printing int\n");
break; val = (int)kernel->machine->ReadRegister(4);
} SysPrintInt(val);
break;
default: kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
cerr << "Unexpected user mode exception " << (int)which << "\n"; kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
break; kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
}
ASSERTNOTREACHED(); return;
ASSERTNOTREACHED();
break;
case SC_Open:
DEBUG(dbgAddr, "Open file\n");
{
val = kernel->machine->ReadRegister(4);
char *name = &(kernel->machine->mainMemory[val]);
OpenFileId ret = SysOpen(name);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Read:
DEBUG(dbgAddr, "Read file\n");
{
val = kernel->machine->ReadRegister(4);
char *buffer = &(kernel->machine->mainMemory[val]);
int size = kernel->machine->ReadRegister(5);
OpenFileId id = (OpenFileId)kernel->machine->ReadRegister(6);
int ret = SysRead(buffer, size, id);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Write:
DEBUG(dbgAddr, "Write file\n");
{
val = kernel->machine->ReadRegister(4);
char *buffer = &(kernel->machine->mainMemory[val]);
int size = kernel->machine->ReadRegister(5);
OpenFileId id = (OpenFileId)kernel->machine->ReadRegister(6);
// fprintf(stderr, "buffer: %p\n", buffer);
// cerr << "size: " << size << endl;
// cerr << "id: " << id << endl;
int ret = SysWrite(buffer, size, id);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
case SC_Close:
DEBUG(dbgAddr, "Close file\n");
{
OpenFileId id = (OpenFileId)kernel->machine->ReadRegister(4);
int ret = SysClose(id);
kernel->machine->WriteRegister(2, ret);
}
kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg) + 4);
return;
ASSERTNOTREACHED();
break;
default:
cerr << "Unexpected system call " << type << "\n";
break;
}
break;
default:
cerr << "Unexpected user mode exception " << (int)which << "\n";
break;
}
ASSERTNOTREACHED();
} }

View File

@@ -11,6 +11,8 @@
#ifndef __USERPROG_KSYSCALL_H__ #ifndef __USERPROG_KSYSCALL_H__
#define __USERPROG_KSYSCALL_H__ #define __USERPROG_KSYSCALL_H__
#define INT_BUF_LENGTH 13
#include "kernel.h" #include "kernel.h"
#include "synchconsole.h" #include "synchconsole.h"
@@ -28,10 +30,74 @@ int SysAdd(int op1, int op2)
int SysCreate(char *filename) int SysCreate(char *filename)
{ {
// return value // return value
// 1: success // 1: success
// 0: failed // 0: failed
return kernel->interrupt->CreateFile(filename); return kernel->interrupt->CreateFile(filename);
}
void SysPrintInt(int value) {
static char zero[2] = "0";
if (value == 0) {
kernel->synchConsoleOut->PutString(zero);
return;
}
char outputBuf[INT_BUF_LENGTH];
bool isNeg = false;
int curPos = INT_BUF_LENGTH;
outputBuf[--curPos] = '\0';
outputBuf[--curPos] = '\n';
if (value < 0) {
isNeg = true;
value = -value;
}
while (value > 0) {
outputBuf[--curPos] = '0' + (value % 10);
value /= 10;
}
if (isNeg)
outputBuf[--curPos] = '-';
kernel->synchConsoleOut->PutString(&outputBuf[curPos]);
}
OpenFileId SysOpen(char *name) {
OpenFileId id = -1;
for (int i = 0; i < 20; i++)
if (kernel->fileSystem->fileDescriptorTable[i] == NULL) {
id = i;
kernel->fileSystem->fileDescriptorTable[i]
= kernel->fileSystem->Open(name);
if (kernel->fileSystem->fileDescriptorTable[i] == NULL)
return -1;
break;
}
return id;
}
int SysWrite(char *buffer, int size, OpenFileId id) {
if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
return -1;
return kernel->fileSystem->fileDescriptorTable[id]->Write(buffer, size);
}
int SysRead(char *buffer, int size, OpenFileId id) {
if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
return -1;
return kernel->fileSystem->fileDescriptorTable[id]->Read(buffer, size);
}
int SysClose(OpenFileId id) {
if (id < 0 || id >= 20 || kernel->fileSystem->fileDescriptorTable[id] == NULL)
return 0;
delete kernel->fileSystem->fileDescriptorTable[id];
kernel->fileSystem->fileDescriptorTable[id] = NULL;
return 1;
} }

View File

@@ -106,6 +106,15 @@ SynchConsoleOutput::PutChar(char ch)
lock->Release(); lock->Release();
} }
void
SynchConsoleOutput::PutString(char *str)
{
lock->Acquire();
consoleOutput->PutString(str);
waitFor->P();
lock->Release();
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// SynchConsoleOutput::CallBack // SynchConsoleOutput::CallBack
// Interrupt handler called when it's safe to send the next // Interrupt handler called when it's safe to send the next

View File

@@ -41,6 +41,7 @@ class SynchConsoleOutput : public CallBackObj {
~SynchConsoleOutput(); ~SynchConsoleOutput();
void PutChar(char ch); // Write a character, waiting if necessary void PutChar(char ch); // Write a character, waiting if necessary
void PutString(char *ch);
private: private:
ConsoleOutput *consoleOutput;// the hardware display ConsoleOutput *consoleOutput;// the hardware display

View File

@@ -23,19 +23,22 @@
#define SC_Exec 2 #define SC_Exec 2
#define SC_Join 3 #define SC_Join 3
#define SC_Create 4 #define SC_Create 4
#define SC_Remove 5 #define SC_Remove 5
#define SC_Open 6 #define SC_Open 6
#define SC_Read 7 #define SC_Read 7
#define SC_Write 8 #define SC_Write 8
#define SC_Seek 9 #define SC_Seek 9
#define SC_Close 10 #define SC_Close 10
#define SC_ThreadFork 11 #define SC_ThreadFork 11
#define SC_ThreadYield 12 #define SC_ThreadYield 12
#define SC_ExecV 13 #define SC_ExecV 13
#define SC_ThreadExit 14 #define SC_ThreadExit 14
#define SC_ThreadJoin 15 #define SC_ThreadJoin 15
#define SC_Add 42
#define SC_MSG 100 #define SC_PrintInt 16
#define SC_Add 42
#define SC_MSG 100
#ifndef IN_ASM #ifndef IN_ASM
@@ -109,7 +112,7 @@ typedef int OpenFileId;
*/ */
#define SysConsoleInput 0 #define SysConsoleInput 0
#define SysConsoleOutput 1 #define SysConsoleOutput 1
/* Create a Nachos file, with name "name" */ /* Create a Nachos file, with name "name" */
/* Note: Create does not open the file. */ /* Note: Create does not open the file. */
@@ -177,6 +180,8 @@ int ThreadJoin(ThreadId id);
*/ */
void ThreadExit(int ExitCode); void ThreadExit(int ExitCode);
void PrintInt(int number);
#endif /* IN_ASM */ #endif /* IN_ASM */
#endif /* SYSCALL_H */ #endif /* SYSCALL_H */

7
docker-compose.yaml Normal file
View File

@@ -0,0 +1,7 @@
---
services:
test:
build: .
user: '60139:60139'
volumes:
- './:/work'