Advertisement
Dimension

Hypervisor.java

Dec 10th, 2011
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.08 KB | None | 0 0
  1. package emulator;
  2.  
  3. import java.util.*;
  4. import java.util.Map.Entry;
  5.  
  6. import emulator.code.*;
  7. import emulator.code.Code.Decl;
  8. import emulator.code.Operation.OperationType;
  9. import emulator.editor.*;
  10. import emulator.editor.Context.CodeContext;
  11. import emulator.editor.Context.CodeContext.CodeContextNew;
  12. import emulator.editor.Context.ThreadStackContext;
  13. import emulator.memory.*;
  14. import emulator.memory.Identifier.Process;
  15. import emulator.memory.Identifier.Stack;
  16. import emulator.memory.Memory.Access;
  17. import emulator.memory.Memory.Access.StructureAccess;
  18. import emulator.memory.Memory.FinalStack;
  19.  
  20. public class Hypervisor {
  21.     public static final int timeSliceNs = 20*1000*1000;
  22.    
  23.     public void run() {
  24.         // scheduling:
  25.         // atomic io, no suspend
  26.         // TODO: io buffer/register, dma, timeout
  27.        
  28.         // process priority:
  29.         // higher priority blocks lower priority
  30.         // same time per process (regardless of the number of thread)
  31.        
  32.         // thread priority: higher priority blocks lower priority, but only in same process
  33.         // one slice per thread
  34.        
  35.         while (true) {
  36.             float highestProcessPriority = 0; // TODO static update on create, terminate, suspend, priority-set
  37.             float priorizedProcessCount = 0;
  38.             boolean kernel = false;
  39.             for(Entry<Identifier.Process, Memory.Process> process1 : new Vector<Entry<Identifier.Process, Memory.Process>>(Memory.processTable.entrySet())) {
  40.                 Memory.Process process = process1.getValue();
  41.                
  42.                 if(process.terminated) {
  43.                     Memory.processTable.remove(process1.getKey());
  44.                 }
  45.                 else if((!kernel || process.kernel)
  46.                         && !process.suspended) {
  47.                     if(process.kernel) {
  48.                         if(!kernel) {
  49.                             highestProcessPriority = 0; // reset priority
  50.                             priorizedProcessCount = 0;
  51.                         }
  52.                         kernel = true;
  53.                     }
  54.                    
  55.                     //highestProcessPriority = Math.max(highestProcessPriority, process.priority);
  56.                     if(highestProcessPriority < process.priority) {
  57.                         highestProcessPriority = process.priority;
  58.                     }
  59.                     else if(highestProcessPriority == process.priority) {
  60.                         priorizedProcessCount++;
  61.                     }
  62.                 }
  63.             }
  64.  
  65.             for(Memory.Process process : Memory.processTable.values()) {
  66.                 if((!kernel || process.kernel)
  67.                         && !process.suspended
  68.                         && process.priority >= highestProcessPriority) {
  69.                    
  70.                     process.highestThreadPriority = 0; // TODO static update on create, terminate, suspend, priority-set
  71.                     for(Entry<Identifier.Thread, Memory.Thread> thread1 : new Vector<Entry<Identifier.Thread, Memory.Thread>>(process.threadTable.entrySet())) {
  72.                         Memory.Thread thread = thread1.getValue();
  73.                    
  74.                         if(thread.terminated) {
  75.                             process.threadTable.remove(thread1.getKey());
  76.                         }
  77.                         else if(!thread.suspended) {
  78.                             process.highestThreadPriority = Math.max(process.highestThreadPriority, thread.priority);
  79.                         }
  80.                     }
  81.  
  82.                     for(Memory.Thread thread : process.threadTable.values()) {
  83.                         if(!thread.suspended
  84.                                 && thread.priority >= process.highestThreadPriority) {
  85.                             runThread(process, thread);
  86.                         }
  87.                     }
  88.                 }
  89.             }
  90.         }
  91.     }
  92.  
  93.     public void runThread(Memory.Process process, Memory.Thread thread) {
  94.        
  95.         Structure.List.Vector callStack = null;
  96.         {
  97.             Memory.Stack stack = thread.threadStackContext.stackList.execute;
  98.             assert stack.isExecutable;
  99.            
  100.             callStack = (Structure.List.Vector) thread.threadStackContext.stackList.execute.itemList.get(0)[0];
  101.         }
  102.        
  103.         Structure.List.Vector evaluateStack = null;
  104.         {
  105.             Memory.Stack stack = thread.threadStackContext.stackList.execute;
  106.             assert stack.isExecutable;
  107.            
  108.             evaluateStack = (Structure.List.Vector) thread.threadStackContext.stackList.evaluate.itemList.get(0)[0];
  109.         }
  110.  
  111.         if (!thread.initialized) {
  112.             thread.initialized = true;
  113.            
  114.             CodeContextNew codeContext = null;
  115.             {
  116.                 Code code = (Code) Memory.Process.getStructureItem(process, (Structure) process.stackContext.stackList.control.itemList.get(0)[0], thread.rootCode)[0];
  117.                 codeContext = new CodeContext.CodeContextNew(process, thread, process.stackContext, thread.threadStackContext, code);
  118.                
  119.                 thread.threadStackContext.init(codeContext);
  120.             }
  121.  
  122.             {
  123.                 assert callStack.size() == 0;
  124.                 callStack.push(new Object[] { new Call(codeContext, false) });
  125.             }
  126.            
  127.         }
  128.  
  129.         long t0 = System.nanoTime();
  130.        
  131.         while(true) {
  132.  
  133.             Call call = null;
  134.             {
  135.                 assert callStack.size() == 0;
  136.                 call = (Call) callStack.dataTable.lastElement()[0];
  137.             }
  138.            
  139.             executeCode(callStack, evaluateStack, call);
  140.  
  141.             long t1 = System.nanoTime();
  142.             if(...) { // time overflow
  143.                 break;
  144.             }
  145.         }
  146.     }
  147.  
  148.     public void executeCode(Structure.List.Vector callStack, Structure.List.Vector evaluateStack, Call call) {
  149.         CodeContext.CodeContextNew context = call.context;
  150.        
  151.         // push stack
  152.         if(call.step == 0) {
  153.             if(context.code.operationType == OperationType.Control.OP_SEQUENCE) {
  154.                 call.declInitList = new Vector<Decl>();
  155.                 for (Entry<Identifier.Stack, Decl> decl1 : context.code.declList.entrySet()) {
  156.                     Identifier.Stack stackId = decl1.getKey();
  157.                     Code.Decl decl = decl1.getValue();
  158.                    
  159.                     assert decl.stackId == stackId;
  160.                     //assert stackId.typeId != null; // use ONLY non-init stacks
  161.        
  162.                     Object[] push = null;
  163.                    
  164.                     if(decl.passthrough) {
  165.                         assert decl.access != null;
  166.                         push = Memory.Process.resolveItem(context.process, decl.access); // for InitType.LITERAL
  167.                     }
  168.                     else {
  169.                         decl.access = new Access.StackAccess(stackId, 0); // for InitType.EXPRESSION
  170.                         push = new Object[1];
  171.                        
  172.                         if (!context.process.stackTable.containsKey(stackId)) {
  173.                             context.process.stackTable.put(stackId, new Memory.Stack());
  174.                         }
  175.                         Memory.Stack stack = context.process.stackTable.get(stackId);
  176.                         assert !(stack instanceof FinalStack); // use ONLY non-final stacks
  177.                         call.stackSizeTable.put(stackId, stack.itemList.size());
  178.                        
  179.                         stack.itemList.push(push);
  180.                     }
  181.        
  182.                     switch(decl.initType) {
  183.                     case EXPRESSION:
  184.                         call.declInitList.add(decl);
  185.                         break;
  186.                     case LITERAL:
  187.                         push[0] = decl.initLiteral;
  188.                         break;
  189.                     }
  190.                 }
  191.             }
  192.            
  193.             call.executeSize0 = sizeExecute(context.threadStackContext);
  194.             call.evaluateSize0 = sizeEvaluate(context.threadStackContext);
  195.         }
  196.  
  197.         if(CodeOut.execute(context, call)) {
  198.             callStack.pop();
  199.  
  200.             call.executeSize1 = sizeExecute(context.threadStackContext);
  201.             call.evaluateSize1 = sizeEvaluate(context.threadStackContext);
  202.            
  203.             assert call.executeSize1 == call.executeSize0;
  204.             if(call.executeAsExpression) {
  205.                 assert call.evaluateSize1 == call.evaluateSize0 + 1;
  206.             }
  207.             else {
  208.                 assert call.evaluateSize1 == call.evaluateSize0
  209.                 || call.evaluateSize1 == call.evaluateSize0 + 1; // e.g. OP_ASSIGN in OP_STRUCTURE
  210.             }
  211.             evaluateStack.dataTable.setSize(call.evaluateSize0);
  212.    
  213.             // pop stack
  214.             // TODO enable checked stack modifications push/pop without decl/scope-leave
  215.             // WARNING would not guarantee to contain the same stack during single sequence after function call ???
  216.             for (Entry<Stack, Integer> stackSize1 : call.stackSizeTable.entrySet()) {
  217.                 Memory.Stack stack = context.process.stackTable.get(stackSize1.getKey());
  218.                 assert !(stack instanceof FinalStack);
  219.                 stack.itemList.setSize(stackSize1.getValue());
  220.             }
  221.            
  222.             return;
  223.         }
  224.     }
  225.    
  226.     public static void pushExecute(ThreadStackContext threadStackContext, Call call) {
  227.         assert !call.executeAsExpression;
  228.         ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).push(new Object[] { call });
  229.     }
  230.    
  231.     public static void pushExecuteExpression(ThreadStackContext threadStackContext, Call call) {
  232.         assert call.executeAsExpression;
  233.         ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).push(new Object[] { call });
  234.     }
  235.    
  236.     public static void pushExecutePassthrough(ThreadStackContext threadStackContext, Call call, Call parent) {
  237.         assert call.executeAsExpression == parent.executeAsExpression;
  238.         ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).push(new Object[] { call });
  239.     }
  240.    
  241.     /*public static Call popExecute(ThreadStackContext threadStackContext) {
  242.         Structure.List.Vector structure = (Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0];
  243.         assert structure.size() >= 1;
  244.         return (Call) structure.pop()[0];
  245.     }*/
  246.    
  247.     public static int sizeExecute(ThreadStackContext threadStackContext) {
  248.         return ((Structure.List.Vector) threadStackContext.stackList.execute.itemList.get(0)[0]).size();
  249.     }
  250.    
  251.     public static void pushEvaluate(ThreadStackContext threadStackContext, Object value) {
  252.         assert !(value instanceof Call); // preliminary validation
  253.         ((Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0]).push(new Object[] { value });
  254.     }
  255.    
  256.     public static Object popEvaluate(ThreadStackContext threadStackContext) {
  257.         Structure.List.Vector structure = (Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0];
  258.         assert structure.size() >= 1;
  259.         return structure.pop()[0];
  260.     }
  261.    
  262.     public static Object getEvaluate(ThreadStackContext threadStackContext) {
  263.         Structure.List.Vector structure = (Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0];
  264.         assert structure.size() >= 1;
  265.         return structure.dataTable.lastElement()[0];
  266.     }
  267.    
  268.     public static int sizeEvaluate(ThreadStackContext threadStackContext) {
  269.         return ((Structure.List.Vector) threadStackContext.stackList.evaluate.itemList.get(0)[0]).size();
  270.     }
  271.    
  272.     public static class Call {
  273.         public CodeContext.CodeContextNew context;
  274.         public boolean executeAsExpression = false;
  275.         public int step = 0; // contract ?
  276.         //public int size = 0;
  277.         public int step2 = 0; // TODO provide iterator access
  278.         //public int size2 = 0;
  279.         public final LinkedHashMap<Identifier.Stack, Integer> stackSizeTable = new LinkedHashMap<Identifier.Stack, Integer>();
  280.         public int executeSize0, executeSize1, evaluateSize0, evaluateSize1;
  281.         public Vector<Decl> declInitList;
  282.        
  283.         public Call(CodeContext.CodeContextNew context, boolean executeAsExpression) {
  284.             this.context = context;
  285.             this.executeAsExpression = executeAsExpression;
  286.         }
  287.     }
  288. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement