📄 os.cs
字号:
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
StackPush(currentProcess.PCB.pid, CPU.registers[register]);
}
/// <summary>
/// Pushes constant 1 onto stack
/// <pre>
/// 5 $1
/// </pre>
/// </summary>
public void Pushi()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.Pushi == instruction);
//move to the param containing the 1st param
CPU.ip++;
uint param = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} {2}",currentProcess.PCB.pid, instruction, param);
StackPush(currentProcess.PCB.pid, param);
}
/// <summary>
/// Terminate the process whose id is in the register r1
/// <pre>
/// 34 r1
/// </pre>
/// </summary>
public void TerminateProcess()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.TerminateProcess == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
foreach (Process p in this.runningProcesses)
{
if (p.PCB.pid == CPU.registers[register])
{
p.PCB.state = ProcessState.Terminated;
Console.WriteLine("Process {0} has forceably terminated Process {1}",currentProcess.PCB.pid, p.PCB.pid);
break;
}
}
}
/// <summary>
/// Pop the contents at the top of the stack into register r1
/// <pre>
/// 35 r1
/// </pre>
/// </summary>
public void Popr()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.Popr == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
CPU.registers[register] = StackPop(currentProcess.PCB.pid);
}
/// <summary>
/// set the bytes starting at address r1 of length r2 to zero
/// <pre>
/// 33 r1, r2
/// </pre>
/// </summary>
public void MemoryClear()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.MemoryClear == instruction);
//move to the param containing the 1st register
CPU.ip++;
uint register1 = FetchUIntAndMove();
uint register2 = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} r{3}",currentProcess.PCB.pid, instruction, register1, register2);
//move VALUE of memory pointed to by 2nd register into 1st register
this.memoryMgr.SetMemoryOfProcess(currentProcess.PCB.pid,CPU.registers[register1],CPU.registers[register2],0);
}
/// <summary>
/// Pop the contents at the top of the stack into the memory pointed to by register r1
/// <pre>
/// 36 r1
/// </pre>
/// </summary>
public void Popm()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.Popm == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
memoryMgr.setUIntAt(currentProcess.PCB.pid,CPU.registers[register],StackPop(currentProcess.PCB.pid));
}
/// <summary>
/// Acquire the OS lock whose # is provided in register r1.
/// Icf the lock is not held by the current process
/// the operation is a no-op
/// <pre>
/// 23 r1
/// </pre>
/// </summary>
public void AcquireLock()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.AcquireLock == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
//Are we the first ones here? with a valid lock?
if (CPU.registers[register] > 0 && CPU.registers[register] <= 10)
{
if (this.locks[CPU.registers[register]] == 0)
{
//Set the lock specified in the register as locked...
this.locks[CPU.registers[register]] = currentProcess.PCB.pid;
}
else if (this.locks[CPU.registers[register]] == currentProcess.PCB.pid)
{
//No-Op, we already have this lock
;
}
else
{
//Get in line for this lock
currentProcess.PCB.waitingLock = CPU.registers[register];
currentProcess.PCB.state = ProcessState.WaitingOnLock;
}
}
}
/// <summary>
/// Release the OS lock whose # is provided in register r1.
/// Another process or the idle process
/// must be scheduled at this point.
/// if the lock is not held by the current process,
/// the instruction is a no-op
/// <pre>
/// 24 r1
/// </pre>
/// </summary>
public void ReleaseLock()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.ReleaseLock == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
//Release only if we already have this lock, and it's a valid lock
if (CPU.registers[register] > 0 && CPU.registers[register] <= 10)
{
if (this.locks[CPU.registers[register]] == currentProcess.PCB.pid)
{
//set the lock back to 0 (the OS)
this.locks[CPU.registers[register]] = 0;
}
}
}
/// <summary>
/// Signal the event indicated by the value in register r1
/// <pre>
/// 30 r1
/// </pre>
/// </summary>
public void SignalEvent()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.SignalEvent == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
if (CPU.registers[register] > 0 && CPU.registers[register] <= 10)
{
this.events[CPU.registers[register]] = EventState.Signaled;
}
}
/// <summary>
/// Wait for the event in register r1 to be triggered resulting in a context-switch
/// <pre>
/// 31 r1
/// </pre>
/// </summary>
public void WaitEvent()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.WaitEvent == instruction);
//move to the param containing the register
CPU.ip++;
uint register = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);
if (CPU.registers[register] > 0 && CPU.registers[register] <= 10)
{
currentProcess.PCB.waitingEvent = CPU.registers[register];
currentProcess.PCB.state = ProcessState.WaitingOnEvent;
}
}
/// <summary>
/// Map the shared memory region identified by r1 and return the start address in r2
/// <pre>
/// 29 r1, r2
/// </pre>
/// </summary>
public void MapSharedMem()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.MapSharedMem == instruction);
//move to the param containing the register
CPU.ip++;
uint register1 = FetchUIntAndMove();
uint register2 = FetchUIntAndMove();
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} r{3}",currentProcess.PCB.pid, instruction, register1, register2);
CPU.registers[register2] = this.memoryMgr.MapSharedMemoryToProcess(CPU.registers[register1], currentProcess.PCB.pid);
}
/// <summary>
/// Allocate memory of the size equal to r1 bytes and return the address of the new memory in r2.
/// If failed, r2 is cleared to 0.
/// <pre>
/// 22 r1, r2
/// </pre>
/// </summary>
public void Alloc()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.Alloc == instruction);
//move to the param containing the register
CPU.ip++;
uint register1 = FetchUIntAndMove(); //bytes requested
uint register2 = FetchUIntAndMove(); //address returned
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} r{3}",currentProcess.PCB.pid, instruction, register1, register2);
uint addr = this.memoryMgr.ProcessHeapAlloc(currentProcess, CPU.registers[register1]);
CPU.registers[register2] = addr;
}
/// <summary>
/// Free the memory allocated whose address is in r1
/// <pre>
/// 28 r1
/// </pre>
/// </summary>
public void FreeMemory()
{
//get the instruction and make sure we should be here
InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
Debug.Assert(InstructionType.FreeMemory == instruction);
//move to the param containing the register
CPU.ip++;
uint register1 = FetchUIntAndMove(); //address of memory
if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register1);
this.memoryMgr.ProcessHeapFree(currentProcess, CPU.registers[register1]);
}
/// <summary>
/// Push a uint on the stack for this Process
/// </summary>
/// <param name="processid">The Process Id</param>
/// <param name="avalue">The uint for the stack</param>
public void StackPush(uint processid, uint avalue)
{
CPU.sp -= 4;
//Are we blowing the stack?
if (CPU.sp < (currentProcess.PCB.processMemorySize - 1 - currentProcess.PCB.stackSize))
throw (new StackException(currentProcess.PCB.pid, currentProcess.PCB.processMemorySize - 1 - currentProcess.PCB.stackSize - CPU.sp));
this.memoryMgr.setUIntAt(processid,CPU.sp,avalue);
}
/// <summary>
/// Pop a uint off the stack for this Process
/// </summary>
/// <param name="processid">The Process ID</param>
/// <returns>the uint from the stack</returns>
public uint StackPop(uint processid)
{
uint retVal = this.memoryMgr.getUIntFrom(processid,CPU.sp);
this.memoryMgr.SetMemoryOfProcess(processid,CPU.sp,4,0);
CPU.sp += 4;
return retVal;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -