/**
* 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.
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.
#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
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
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]);
+ }
+}