* Written by Tim Wilkinson <tim@tjwassoc.demon.co.uk>, 1996.
*/
+#include "config.h"
+
#include <assert.h>
#include <sys/types.h>
#include "thread.h"
#include "locks.h"
-#include "sysdep/defines.h"
-#include "sysdep/threads.h"
+#include "defines.h"
+#include "threads.h"
-#include "../tables.h"
-#include "../native.h"
-#include "../loader.h"
-#include "../builtin.h"
-#include "../asmpart.h"
+#include "tables.h"
+#include "native.h"
+#include "loader.h"
+#include "builtin.h"
+#include "asmpart.h"
static classinfo *class_java_lang_ThreadDeath;
#if defined(USE_INTERNAL_THREADS)
-thread* currentThread;
+thread* currentThread = NULL;
+thread* mainThread;
thread* threadQhead[MAX_THREAD_PRIO + 1];
thread* threadQtail[MAX_THREAD_PRIO + 1];
-thread* liveThreads;
+thread* liveThreads = NULL;
thread* alarmList;
-thread* gcDaemonThread;
-
int blockInts;
bool needReschedule;
void
initThreads(u1 *stackbottom)
{
+ thread *the_main_thread;
int i;
initLocks();
- for (i = 0; i < MAXTHREADS; ++i)
+ for (i = 0; i < MAXTHREADS; ++i) {
contexts[i].free = true;
+ contexts[i].thread = NULL;
+ heap_addreference((void**)&contexts[i].thread);
+ }
/* Allocate a thread to be the main thread */
- currentThread = (thread*)builtin_new(loader_load(unicode_new_char("java/lang/Thread")));
- assert(currentThread != 0);
+ liveThreads = the_main_thread = (thread*)builtin_new(loader_load(unicode_new_char("java/lang/Thread")));
+ assert(the_main_thread != 0);
+ /* heap_addreference((void **) &liveThreads); */
- currentThread->PrivateInfo = 1;
- CONTEXT(currentThread).free = false;
-
- liveThreads = currentThread;
-
- currentThread->name = javastring_new(unicode_new_char("main"));
- currentThread->priority = NORM_THREAD_PRIO;
- CONTEXT(currentThread).priority = (u1)currentThread->priority;
- CONTEXT(currentThread).exceptionptr = 0;
- currentThread->next = 0;
- CONTEXT(currentThread).status = THREAD_SUSPENDED;
- CONTEXT(currentThread).stackBase = CONTEXT(currentThread).stackEnd = stackbottom;
- THREADINFO(&CONTEXT(currentThread));
+ the_main_thread->PrivateInfo = 1;
+ CONTEXT(the_main_thread).free = false;
+
+ the_main_thread->name = javastring_new(unicode_new_char("main"));
+ the_main_thread->priority = NORM_THREAD_PRIO;
+ CONTEXT(the_main_thread).priority = (u1)the_main_thread->priority;
+ CONTEXT(the_main_thread).exceptionptr = 0;
+ the_main_thread->next = 0;
+ CONTEXT(the_main_thread).status = THREAD_SUSPENDED;
+ CONTEXT(the_main_thread).stackBase = CONTEXT(the_main_thread).stackEnd = stackbottom;
+ THREADINFO(&CONTEXT(the_main_thread));
DBG( printf("main thread %p base %p end %p\n",
- currentThread,
- CONTEXT(currentThread).stackBase,
- CONTEXT(currentThread).stackEnd); );
-
- CONTEXT(currentThread).flags = THREAD_FLAGS_NOSTACKALLOC;
- CONTEXT(currentThread).nextlive = 0;
- currentThread->single_step = 0;
- currentThread->daemon = 0;
- currentThread->stillborn = 0;
- currentThread->target = 0;
- currentThread->interruptRequested = 0;
- currentThread->group =
+ the_main_thread,
+ CONTEXT(the_main_thread).stackBase,
+ CONTEXT(the_main_thread).stackEnd); );
+
+ CONTEXT(the_main_thread).flags = THREAD_FLAGS_NOSTACKALLOC;
+ CONTEXT(the_main_thread).nextlive = 0;
+ CONTEXT(the_main_thread).thread = the_main_thread;
+ the_main_thread->single_step = 0;
+ the_main_thread->daemon = 0;
+ the_main_thread->stillborn = 0;
+ the_main_thread->target = 0;
+ the_main_thread->interruptRequested = 0;
+ the_main_thread->group =
(threadGroup*)builtin_new(loader_load(unicode_new_char("java/lang/ThreadGroup")));
/* we should call the constructor */
- assert(currentThread->group != 0);
+ assert(the_main_thread->group != 0);
talive++;
- /* Add thread into runQ */
- iresumeThread(currentThread);
-
- /* Start garbage collection thread */
- gcDaemonThread = startDaemon(gc_thread, "gc", 1024*512);
- iresumeThread(gcDaemonThread);
-
- heap_addreference((void**)&gcDaemonThread);
-
/* Load exception classes */
class_java_lang_ThreadDeath = loader_load(unicode_new_char("java/lang/ThreadDeath"));
DBG( fprintf(stderr, "finishing initThreads\n"); );
+ mainThread = currentThread = the_main_thread;
+
+ /* heap_addreference((void**)&mainThread); */
+
+ /* Add thread into runQ */
+ iresumeThread(mainThread);
+
assert(blockInts == 0);
}
tid->PrivateInfo = i + 1;
CONTEXT(tid).free = false;
+ CONTEXT(tid).thread = tid;
CONTEXT(tid).nextlive = liveThreads;
liveThreads = tid;
allocThreadStack(tid, threadStackSize);
/* If we only have daemons left, then everyone is dead. */
if (talive == tdaemon) {
- /* Am I suppose to close things down nicely ?? */
+ /* atexit functions get called to clean things up */
exit(0);
}
freeThreadStack(tid);
/* free context */
- CONTEXT(tid).free = true;
+ if (tid != mainThread) {
+ CONTEXT(tid).free = true;
+ CONTEXT(tid).thread = NULL;
+ }
/* Run something else */
needReschedule = true;
if (threadQhead[i] != currentThread)
{
- USEDSTACKTOP((CONTEXT(currentThread).usedStackTop));
+ /* USEDSTACKTOP((CONTEXT(currentThread).usedStackTop)); */
lastThread = currentThread;
currentThread = threadQhead[i];