Пример #1
0
        public void ReleaseLock(uint lockNo)
        {
            if (lockNo == 0 || lockNo > LockCount)
            {
                return;
            }

            var @lock = Locks[lockNo - 1];

            if (@lock.Owner != CurrentProcess.Id)
            {
                return;
            }

            @lock.RefCount--;
            if (@lock.RefCount != 0)
            {
                return;
            }

            @lock.Owner    = 0;
            @lock.RefCount = 0;

            var blockingProcess = DeviceReadQueue.Dequeue(@lock.Handle);

            if (blockingProcess == null)
            {
                return;
            }

            var pcb = blockingProcess.Process;

            AcquireLock(pcb, @lock);
            ReadyQueue.Enqueue(pcb);
        }
Пример #2
0
        private void WriteTerminal()
        {
            BlockingProcess wakingProcess;

            while ((wakingProcess = DeviceWriteQueue.Dequeue(DeviceId.Terminal)) != null)
            {
                var process = wakingProcess.Process;
                (OutputMethod ?? Console.WriteLine)(wakingProcess.Argument);
                ReadyQueue.Enqueue(process);
            }
        }
Пример #3
0
        private ProcessContextBlock SwitchToNextProcess()
        {
            if (CurrentProcess != null)
            {
                ReadyQueue.Enqueue(CurrentProcess);
            }

            var process = ReadyQueue.Dequeue() ?? IdleProcess;

            process.Quanta = UserQuanta;

            return(process);
        }
Пример #4
0
 public Cpu(Ram ram)
 {
     Ram              = ram;
     ReadyQueue       = new ReadyQueue(PriorityCount);
     DeviceReadQueue  = new DeviceQueue();
     DeviceWriteQueue = new DeviceQueue();
     Locks            = Enumerable.Range(1, LockCount).Select(x => (DeviceId)(x + Devices.Locks)).Select(x => new Lock(x)).ToArray();
     Events           = Enumerable.Range(1, EventCount).Select(x => (DeviceId)(x + Devices.Events)).Select(x => new Event(x)).ToArray();
     SleepTimer       = new CpuSleepTimer();
     _processes       = new Dictionary <uint, ProcessContextBlock>();
     _operations      = OpCodeMetaInformationBuilder.GetMetaInformation().ToDictionary(x => x.OpCode, OpCodeMetaInformationBuilder.BuildOperation);
     IdleProcess      = new ProcessContextBlock {
         Id = 1,
     };
     InputDevice = new TerminalInputDevice();
 }
Пример #5
0
        public void SignalEvent(uint eventNo)
        {
            if (eventNo == 0 || eventNo > EventCount)
            {
                return;
            }

            var ev = Events[eventNo - 1];

            BlockingProcess blockingProcess;

            while ((blockingProcess = DeviceReadQueue.Dequeue(ev.Handle)) != null)
            {
                ReadyQueue.Enqueue(blockingProcess.Process);
            }
        }
Пример #6
0
        private void TickSleepTimer()
        {
            DeviceId sleepTimer;

            if (!SleepTimer.Tick(out sleepTimer))
            {
                return;
            }

            BlockingProcess wakingProcess;

            while ((wakingProcess = DeviceReadQueue.Dequeue(sleepTimer)) != null)
            {
                ReadyQueue.Enqueue(wakingProcess.Process);
            }
        }
Пример #7
0
        public void Run(ProcessContextBlock block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            block.Stack.Append(Ram.Allocate(block));
            block.GlobalData.Append(Ram.Allocate(block));
            block.Registers[Register.G] = block.Id;
            block.Registers[Register.H] = block.GlobalData.Offset;

            _processes.Add(block.Id, block);
            ReadyQueue.Enqueue(block);
            block.IsRunning = true;
        }
Пример #8
0
        private void ReadTerminal()
        {
            uint value;

            if (!InputDevice.Get(out value))
            {
                return;
            }

            BlockingProcess wakingProcess;

            while ((wakingProcess = DeviceReadQueue.Dequeue(DeviceId.Terminal)) != null)
            {
                var process = wakingProcess.Process;
                process.Registers[wakingProcess.Argument] = value;

                ReadyQueue.Enqueue(process);
            }
        }