⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os.cs

📁 用C编写的一个微操作系统
💻 CS
📖 第 1 页 / 共 4 页
字号:
			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 + -