Exemple #1
0
        public Page Allocate(ProcessContextBlock pcb)
        {
            if (pcb == null)
            {
                throw new ArgumentNullException(nameof(pcb));
            }

            var firstFreeFrame =
                (
                    from frame in LiveFrames
                    where frame.ProcessId == 0
                    select frame
                ).FirstOrDefault();

            if (firstFreeFrame == null)
            {
                return(null);
            }

            var page = pcb.PageTable.CreatePage(this);

            firstFreeFrame.ProcessId  = pcb.Id;
            firstFreeFrame.PageNumber = page.PageNumber;
            page.Size        = FrameSize;
            page.FrameNumber = firstFreeFrame.FrameNumber;

            return(page);
        }
Exemple #2
0
        public ProcessContextBlock Load()
        {
            var pId = NextProcessId();
            var processContextBlock = new ProcessContextBlock
            {
                Id       = pId,
                Priority = 16,
            };

            return(processContextBlock);
        }
Exemple #3
0
        public void Enqueue(DeviceId deviceId, ProcessContextBlock pcb, OpCodeFlag flag = OpCodeFlag.Register, uint arg1 = 0)
        {
            var blockingProcess = new BlockingProcess
            {
                Process  = pcb,
                Flag     = flag,
                Argument = arg1,
                DeviceId = deviceId
            };

            _deviceQueue[deviceId].Enqueue(blockingProcess);
        }
Exemple #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();
 }
Exemple #5
0
        public Stream AllocateCodeBlock(ProcessContextBlock pcb, uint length)
        {
            var page = new PageInfo();

            while (length > Ram.FrameSize)
            {
                length -= Ram.FrameSize;
                page.Append(Ram.Allocate(pcb));
            }

            page.Append(Ram.Allocate(pcb));
            pcb.Code = page;

            return(GetMemoryStream(page));
        }
Exemple #6
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();
 }
Exemple #7
0
        public void Free()
        {
            var ram = new Ram(2, 1);

            var pcb = new ProcessContextBlock { Id = 1 };
            var frame = ram.Allocate(pcb);
            Assert.That(frame, Is.Not.Null);

            frame = ram.Allocate(pcb);
            Assert.That(frame, Is.Not.Null);

            ram.Free(frame);

            frame = ram.Allocate(pcb);
            Assert.That(frame, Is.Not.Null);
        }
Exemple #8
0
        public void CreateShared()
        {
            var ram = new Ram(1024, 256);
            var offset = ram.AllocateShared(512);
            Assert.That(offset, Is.EqualTo(0));

            var pcb = new ProcessContextBlock {Id = 10};
            var p1 = ram.Allocate(pcb);
            var p2 = ram.Allocate(pcb);

            var p1Offset = ram.ToPhysicalAddress(10, p1.VirtualAddress);
            var p2Offset = ram.ToPhysicalAddress(10, p2.VirtualAddress);
            Assert.That(p1Offset, Is.GreaterThan(offset));
            Assert.That(p2Offset, Is.GreaterThan(offset));
            Assert.That(p2Offset, Is.GreaterThan(p1Offset));
        }
Exemple #9
0
        public void Allocate()
        {
            var ram = new Ram(2, 1);

            var pcb = new ProcessContextBlock { Id = 1 };
            var page = ram.Allocate(pcb);
            Assert.That(page, Is.Not.Null);
            Assert.That(page.PageNumber, Is.Not.EqualTo(0));

            page = ram.Allocate(pcb);
            Assert.That(page, Is.Not.Null);
            Assert.That(page.PageNumber, Is.Not.EqualTo(0));

            page = ram.Allocate(pcb);
            Assert.That(page, Is.Null);
        }
Exemple #10
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;
        }
        public static uint Compile(this Cpu cpu, ProcessContextBlock pcb, string source)
        {
            var ms = new MemoryStream();
            using (var writer = new CodeWriter(ms))
            {
                var assembler = new Assembler(source);
                foreach (var i in assembler.Assemble())
                    writer.Write(i);

                writer.Close();

                var codeBlock = cpu.AllocateCodeBlock(pcb, (uint)ms.Length);
                ms.WriteTo(codeBlock);

                return (uint )ms.Length;
            }
        }
Exemple #12
0
        public static uint Compile(this Cpu cpu, ProcessContextBlock pcb, IEnumerable <Instruction> instructions)
        {
            var stream = new MemoryStream();

            using (var writer = new CodeWriter(stream))
            {
                foreach (var instruction in instructions)
                {
                    writer.Write(instruction);
                }

                writer.Close();
                using (var ps = cpu.AllocateCodeBlock(pcb, (uint)stream.Length))
                    stream.WriteTo(ps);

                return((uint)stream.Length);
            }
        }
Exemple #13
0
        public IEnumerable <Page> AllocateFromShared(ProcessContextBlock pcb, uint size)
        {
            long remaining = size;

            var index = 0;

            while (remaining > 0)
            {
                var sharedFrame = _shared[index];
                var page        = pcb.PageTable.CreatePage(this);
                page.Size        = FrameSize;
                page.FrameNumber = sharedFrame.FrameNumber;
                yield return(page);

                remaining -= FrameSize;
                index++;
            }
        }
Exemple #14
0
        public void Write()
        {
            var buffer = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
            const uint frameSize = 4;
            var ram = new Ram(buffer, frameSize);
            var pageSet = new PageInfo();

            var pcb = new ProcessContextBlock {Id = 1};
            ram.Allocate(pcb);
            pageSet.Append(ram.Allocate(pcb));
            pageSet.Append(ram.Allocate(pcb));

            var pageStream = new PageStream(ram, pageSet);
            Assert.That(pageStream.Length, Is.EqualTo(8));

            var b = new byte[] { 91, 92, 93, 94, };
            pageStream.Position = 2;
            pageStream.Write(b, 0, 4);

            Assert.That(buffer, Is.EquivalentTo(new[] { 1, 2, 3, 4, 5, 6, 91, 92, 93, 94, 11, 12, }));
        }
Exemple #15
0
        public void Read()
        {
            var buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
            const uint frameSize = 4;
            var ram = new Ram(buffer, frameSize);
            var pageSet = new PageInfo();

            var pcb = new ProcessContextBlock {Id = 1};
            ram.Allocate(pcb);
            pageSet.Append(ram.Allocate(pcb));
            pageSet.Append(ram.Allocate(pcb));

            var pageStream = new PageStream(ram, pageSet);
            Assert.That(pageStream.Length, Is.EqualTo(8));

            var b = new byte[6];
            pageStream.Read(b, 0, 6);

            Assert.That(pageStream.Position, Is.EqualTo(6));

            Assert.That(b, Is.EquivalentTo(new[] { 5, 6, 7, 8, 9, 10 }));
        }
Exemple #16
0
        public Page Allocate(ProcessContextBlock pcb)
        {
            if (pcb == null)
                throw new ArgumentNullException(nameof(pcb));

            var firstFreeFrame =
                (
                    from frame in LiveFrames
                    where frame.ProcessId == 0
                    select frame
                    ).FirstOrDefault();

            if (firstFreeFrame == null)
                return null;

            var page = pcb.PageTable.CreatePage(this);
            firstFreeFrame.ProcessId = pcb.Id;
            firstFreeFrame.PageNumber = page.PageNumber;
            page.Size = FrameSize;
            page.FrameNumber = firstFreeFrame.FrameNumber;

            return page;
        }
Exemple #17
0
 private void AcquireLock(ProcessContextBlock process, Lock @lock)
 {
     @lock.Owner = process.Id;
     @lock.RefCount++;
     process.Locks.Add(@lock);
 }
Exemple #18
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;
        }
Exemple #19
0
        public void SignalEvent()
        {
            var pA = _cpu.CurrentProcess;

            Instructions.Movi(_cpu, Register.A, 1);
            Instructions.WaitEvent(_cpu, Register.A);

            var pB = new ProcessContextBlock();
            _cpu.CurrentProcess = pB;
            Instructions.Movi(_cpu, Register.A, 1);
            Instructions.SignalEvent(_cpu, Register.A);

            Assert.That(_cpu.CurrentProcess, Is.EqualTo(pB));
            Assert.That(_cpu.ReadyQueue, Contains.Item(pA));
            Assert.That(_cpu.DeviceQueue, Is.Empty);
        }
Exemple #20
0
 private void AcquireLock(ProcessContextBlock process, Lock @lock)
 {
     @lock.Owner = process.Id;
     @lock.RefCount++;
     process.Locks.Add(@lock);
 }
 private ProcessContextBlock CreateProcess(uint pId)
 {
     var p = new ProcessContextBlock {Id = pId};
     p.Stack.Append(_cpu.Ram.Allocate(p));
     p.Code.Append(_cpu.Ram.Allocate(p));
     p.GlobalData.Append(_cpu.Ram.Allocate(p));
     return p;
 }
        public void SignalEvent()
        {
            var pA = _cpu.CurrentProcess;

            Invoke(InstructionsWithControlByte.WaitEvent, 1);

            var pB = new ProcessContextBlock();
            _cpu.CurrentProcess = pB;
            Invoke(InstructionsWithControlByte.SignalEvent, 1);

            Assert.That(_cpu.CurrentProcess, Is.EqualTo(pB));
            Assert.That(_cpu.ReadyQueue, Contains.Item(pA));
            Assert.That(_cpu.DeviceReadQueue, Is.Empty);
        }
Exemple #23
0
        public ProcessContextBlock Load()
        {
            var pId = NextProcessId();
            var processContextBlock = new ProcessContextBlock
            {
                Id = pId,
                Priority = 16,
            };

            return processContextBlock;
        }
Exemple #24
0
        public static uint Compile(this Cpu cpu, ProcessContextBlock pcb, IEnumerable<Instruction> instructions)
        {
            var stream = new MemoryStream();
            using (var writer = new CodeWriter(stream))
            {
                foreach (var instruction in instructions)
                    writer.Write(instruction);

                writer.Close();
                using (var ps = cpu.AllocateCodeBlock(pcb, (uint) stream.Length))
                    stream.WriteTo(ps);

                return (uint) stream.Length;
            }
        }
Exemple #25
0
        public IEnumerable<Page> AllocateFromShared(ProcessContextBlock pcb, uint size)
        {
            long remaining = size;

            var index = 0;
            while (remaining > 0)
            {
                var sharedFrame = _shared[index];
                var page = pcb.PageTable.CreatePage(this);
                page.Size = FrameSize;
                page.FrameNumber = sharedFrame.FrameNumber;
                yield return page;

                remaining -= FrameSize;
                index++;
            }
        }
Exemple #26
0
        public Stream AllocateCodeBlock(ProcessContextBlock pcb, uint length)
        {
            var page = new PageInfo();

            while ( length > Ram.FrameSize )
            {
                length -= Ram.FrameSize;
                page.Append(Ram.Allocate(pcb));
            }

            page.Append(Ram.Allocate(pcb));
            pcb.Code = page;

            return GetMemoryStream(page);
        }