OSDN Git Service

lejos_NXJ_win32_0_6_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / nxtvm / javavm / threads.c
index 0b22697..503ef9c 100644 (file)
@@ -27,7 +27,8 @@ Thread* currentThread;
 /**
  * Priority queue of threads. Entry points at the last thread in the queue.
  */
-Thread *threadQ[10];
+REFERENCE threads;
+Thread **threadQ;
 
 /**
  * Thread id generator, always increasing.
@@ -51,15 +52,15 @@ StackFrame *current_stackframe()
 
 void update_stack_frame (StackFrame *stackFrame)
 {
-  stackFrame->stackTop = stackTop;
-  stackFrame->pc = pc;
+  stackFrame->stackTop = curStackTop;
+  stackFrame->pc = curPc;
 }  
 
 void update_registers (StackFrame *stackFrame)
 {
-  pc = stackFrame->pc;
-  stackTop = stackFrame->stackTop;
-  localsBase = stackFrame->localsBase;
+  curPc = stackFrame->pc;
+  curStackTop = stackFrame->stackTop;
+  curLocalsBase = stackFrame->localsBase;
 }
 
 /* Turns out inlines aren't really inlined.
@@ -88,6 +89,23 @@ inline void set_monitor_count (Object *obj, byte count)
 #define set_thread_id(obj,_threadId) ((obj)->threadId = (_threadId))
 #define inc_monitor_count(obj) ((obj)->monitorCount++)
 #define set_monitor_count(obj,count) ((obj)->monitorCount = (count))
+/**
+ * Initialise the thread pool. Note we use a Java object so that we can make
+ * the pool available to Java.
+ **/
+void init_threads()
+{
+  int i;
+  threads = ptr2ref(new_primitive_array(T_REFERENCE, 10));
+  threadQ = (Thread **)ref_array(threads);
+  Thread **pQ = threadQ;
+  gThreadCounter = 0;
+  currentThread = JNULL;
+  for (i = 0; i<10; i++)
+  {
+    *pQ++ = null;
+  }
+}
 
 /**
  * Allocate stack frames
@@ -360,16 +378,16 @@ done_pi:
               ClassRecord *classRecord;
               classRecord = get_class_record (get_entry_class (gProgramNumber));
               // Initialize top word with fake parameter for main():
-              set_top_ref (JNULL);
+              set_top_ref_cur (JNULL);
               // Push stack frame for main method:
               mRec= find_method (classRecord, main_4_1Ljava_3lang_3String_2_5V);
               dispatch_special (mRec, null);
               // Push another if necessary for the static initializer:
-              dispatch_static_initializer (classRecord, pc);
+              dispatch_static_initializer (classRecord, curPc);
             }
             else
             {
-              set_top_ref (ptr2word (candidate));
+              set_top_ref_cur (ptr2word (candidate));
               dispatch_virtual ((Object *) candidate, run_4_5V, null);
             }
             // The following is needed because the current stack frame
@@ -702,3 +720,55 @@ void set_thread_priority(Thread *thread, const FOURBYTES priority)
   enqueue_thread(thread);      
 }
 
+/**
+ * Suspend the specified thread. If thread is null suspend all threads
+ * except currentThread.
+ */
+void suspend_thread(Thread *thread)
+{
+  int i;
+  Thread *pThread;
+  if (thread)
+    thread->state |= SUSPENDED;
+  else
+  {
+    // Suspend all threads
+    for (i=MAX_PRIORITY-1; i >= 0; i--)
+    {
+      pThread = threadQ[i];
+      if (!pThread)
+        continue;
+      
+      do {
+        // Remember threadQ[i] is the last thread on the queue
+        pThread = word2ptr(pThread->nextThread);
+        if (pThread != currentThread) pThread->state |= SUSPENDED;
+      } while (pThread != threadQ[i]);
+    }
+  }
+  schedule_request( REQUEST_SWITCH_THREAD);
+}
+
+void resume_thread(Thread *thread)
+{
+  int i;
+  Thread *pThread;
+  if (thread)
+  {
+    thread->state &= ~SUSPENDED;
+    return;
+  }
+  // Suspend all threads
+  for (i=MAX_PRIORITY-1; i >= 0; i--)
+  {
+    pThread = threadQ[i];
+    if (!pThread)
+      continue;
+      
+    do {
+      // Remember threadQ[i] is the last thread on the queue
+      pThread = word2ptr(pThread->nextThread);
+      pThread->state &= ~SUSPENDED;
+    } while (pThread != threadQ[i]);
+  }
+}