Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package emulator;
- import java.util.*;
- import java.util.Map.Entry;
- import emulator.code.*;
- import emulator.code.Code.Decl;
- import emulator.code.Operation.OperationType;
- import emulator.editor.*;
- import emulator.editor.Context.CodeContext;
- import emulator.editor.Context.CodeContext.CodeContextNew;
- import emulator.editor.Context.ThreadStackContext;
- import emulator.memory.*;
- import emulator.memory.Identifier.Process;
- import emulator.memory.Identifier.Stack;
- import emulator.memory.Memory.Access;
- import emulator.memory.Memory.Access.StructureAccess;
- import emulator.memory.Memory.FinalStack;
- public class Hypervisor {
- public static final int timeSliceNs = 20*1000*1000;
- public void run() {
- // scheduling:
- // atomic io, no suspend
- // TODO: io buffer/register, dma, timeout
- // process priority:
- // higher priority blocks lower priority
- // same time per process (regardless of the number of thread)
- // thread priority: higher priority blocks lower priority, but only in same process
- // one slice per thread
- while (true) {
- float highestProcessPriority = 0; // TODO static update on create, terminate, suspend, priority-set
- float priorizedProcessCount = 0;
- boolean kernel = false;
- for(Entry<Identifier.Process, Memory.Process> process1 : new Vector<Entry<Identifier.Process, Memory.Process>>(Memory.processTable.entrySet())) {
- Memory.Process process = process1.getValue();
- if(process.terminated) {
- Memory.processTable.remove(process1.getKey());
- }
- else if((!kernel || process.kernel)
- && !process.suspended) {
- if(process.kernel) {
- if(!kernel) {
- highestProcessPriority = 0; // reset priority
- priorizedProcessCount = 0;
- }
- kernel = true;
- }
- //highestProcessPriority = Math.max(highestProcessPriority, process.priority);
- if(highestProcessPriority < process.priority) {
- highestProcessPriority = process.priority;
- }
- else if(highestProcessPriority == process.priority) {
- priorizedProcessCount++;
- }
- }
- }
- for(Memory.Process process : Memory.processTable.values()) {
- if((!kernel || process.kernel)
- && !process.suspended
- && process.priority >= highestProcessPriority) {
- process.highestThreadPriority = 0; // TODO static update on create, terminate, suspend, priority-set
- for(Entry<Identifier.Thread, Memory.Thread> thread1 : new Vector<Entry<Identifier.Thread, Memory.Thread>>(process.threadTable.entrySet())) {
- Memory.Thread thread = thread1.getValue();
- if(thread.terminated) {
- process.threadTable.remove(thread1.getKey());
- }
- else if(!thread.suspended) {
- process.highestThreadPriority = Math.max(process.highestThreadPriority, thread.priority);
- }
- }
- for(Memory.Thread thread : process.threadTable.values()) {
- if(!thread.suspended
- && thread.priority >= process.highestThreadPriority) {
- runThread(process, thread);
- }
- }
- }
- }
- }
- }
- public void runThread(Memory.Process process, Memory.Thread thread) {
- Structure.List.Vector callStack = null;
- {
- Memory.Stack stack = thread.threadStackContext.stackList.execute;
- assert stack.isExecutable;
- callStack = (Structure.List.Vector) thread.threadStackContext.stackList.execute.itemList.get(0)[0];
- }
- Structure.List.Vector evaluateStack = null;
- {
- Memory.Stack stack = thread.threadStackContext.stackList.execute;
- assert stack.isExecutable;
- evaluateStack = (Structure.List.Vector) thread.threadStackContext.stackList.evaluate.itemList.get(0)[0];
- }
- if (!thread.initialized) {
- thread.initialized = true;
- CodeContextNew codeContext = null;
- {
- Code code = (Code) Memory.Process.getStructureItem(process, (Structure) process.stackContext.stackList.control.itemList.get(0)[0], thread.rootCode)[0];
- codeContext = new CodeContext.CodeContextNew(process, thread, process.stackContext, thread.threadStackContext, code);
- thread.threadStackContext.init(codeContext);
- }
- {
- assert callStack.size() == 0;
- callStack.push(new Object[] { new Call(codeContext, false) });
- }
- }
- long t0 = System.nanoTime();
- while(true) {
- Call call = null;
- {
- assert callStack.size() == 0;
- call = (Call) callStack.dataTable.lastElement()[0];
- }
- executeCode(callStack, evaluateStack, call);
- long t1 = System.nanoTime();
- if(...) { // time overflow
- break;
- }
- }
- }
- public void executeCode(Structure.List.Vector callStack, Structure.List.Vector evaluateStack, Call call) {
- CodeContext.CodeContextNew context = call.context;
- // push stack
- if(call.step == 0) {
- if(context.code.operationType == OperationType.Control.OP_SEQUENCE) {
- call.declInitList = new Vector<Decl>();
- for (Entry<Identifier.Stack, Decl> decl1 : context.code.declList.entrySet()) {
- Identifier.Stack stackId = decl1.getKey();
- Code.Decl decl = decl1.getValue();
- assert decl.stackId == stackId;
- //assert stackId.typeId != null; // use ONLY non-init stacks
- Object[] push = null;
- if(decl.passthrough) {
- assert decl.access != null;
- push = Memory.Process.resolveItem(context.process, decl.access); // for InitType.LITERAL
- }
- else {
- decl.access = new Access.StackAccess(stackId, 0); // for InitType.EXPRESSION
- push = new Object[1];
- if (!context.process.stackTable.containsKey(stackId)) {
- context.process.stackTable.put(stackId, new Memory.Stack());
- }
- Memory.Stack stack = context.process.stackTable.get(stackId);
- assert !(stack instanceof FinalStack); // use ONLY non-final stacks
- call.stackSizeTable.put(stackId, stack.itemList.size());
- stack.itemList.push(push);
- }
- switch(decl.initType) {
- case EXPRESSION:
- call.declInitList.add(decl);
- break;
- case LITERAL:
- push[0] = decl.initLiteral;
- break;
- }
- }
- }
- call.executeSize0 = sizeExecute(context.threadStackContext);
- call.evaluateSize0 = sizeEvaluate(context.threadStackContext);
- }
- if(CodeOut.execute(context, call)) {
- callStack.pop();
- call.executeSize1 = sizeExecute(context.threadStackContext);
- call.evaluateSize1 = sizeEvaluate(context.threadStackContext);
- assert call.executeSize1 == call.executeSize0;
- if(call.executeAsExpression) {
- assert call.evaluateSize1 == call.evaluateSize0 + 1;
- }
- else {
- assert call.evaluateSize1 == call.evaluateSize0
- || call.evaluateSize1 == call.evaluateSize0 + 1; // e.g. OP_ASSIGN in OP_STRUCTURE
- }
- evaluateStack.dataTable.setSize(call.evaluateSize0);
- // pop stack
- // TODO enable checked stack modifications push/pop without decl/scope-leave
- // WARNING would not guarantee to contain the same stack during single sequence after function call ???
- for (Entry<Stack, Integer> stackSize1 : call.stackSizeTable.entrySet()) {
- Memory.Stack stack = context.process.stackTable.get(stackSize1.getKey());
- assert !(stack instanceof FinalStack);
- stack.itemList.setSize(stackSize1.getValue());
- }
- return;
- }
- }
- public static void pushExecute(ThreadStackContext threadStackContext, Call call) {
- assert !call.executeAsExpression;
- ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).push(new Object[] { call });
- }
- public static void pushExecuteExpression(ThreadStackContext threadStackContext, Call call) {
- assert call.executeAsExpression;
- ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).push(new Object[] { call });
- }
- public static void pushExecutePassthrough(ThreadStackContext threadStackContext, Call call, Call parent) {
- assert call.executeAsExpression == parent.executeAsExpression;
- ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).push(new Object[] { call });
- }
- /*public static Call popExecute(ThreadStackContext threadStackContext) {
- Structure.List.Vector structure = (Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0];
- assert structure.size() >= 1;
- return (Call) structure.pop()[0];
- }*/
- public static int sizeExecute(ThreadStackContext threadStackContext) {
- return ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).size();
- }
- public static void pushEvaluate(ThreadStackContext threadStackContext, Object value) {
- assert !(value instanceof Call); // preliminary validation
- ((Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0]).push(new Object[] { value });
- }
- public static Object popEvaluate(ThreadStackContext threadStackContext) {
- Structure.List.Vector structure = (Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0];
- assert structure.size() >= 1;
- return structure.pop()[0];
- }
- public static Object getEvaluate(ThreadStackContext threadStackContext) {
- Structure.List.Vector structure = (Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0];
- assert structure.size() >= 1;
- return structure.dataTable.lastElement()[0];
- }
- public static int sizeEvaluate(ThreadStackContext threadStackContext) {
- return ((Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0]).size();
- }
- public static class Call {
- public CodeContext.CodeContextNew context;
- public boolean executeAsExpression = false;
- public int step = 0; // contract ?
- //public int size = 0;
- public int step2 = 0; // TODO provide iterator access
- //public int size2 = 0;
- public final LinkedHashMap<Identifier.Stack, Integer> stackSizeTable = new LinkedHashMap<Identifier.Stack, Integer>();
- public int executeSize0, executeSize1, evaluateSize0, evaluateSize1;
- public Vector<Decl> declInitList;
- public Call(CodeContext.CodeContextNew context, boolean executeAsExpression) {
- this.context = context;
- this.executeAsExpression = executeAsExpression;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement