dependency problem in the initialization routines.
Added a missing heap_addreference in main.c.
methodinfo *mainmethod;
java_objectarray *a;
+ heap_addreference(&a);
+
mainmethod = class_findmethod (
topclass,
unicode_new_char ("main"),
methodinfo *mainmethod;
java_objectarray *a;
+ heap_addreference(&a);
+
mainmethod = class_findmethod (
topclass,
unicode_new_char ("main"),
#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();
contexts[i].free = true;
/* Allocate a thread to be the main thread */
- mainThread = 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(&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;
+ 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", 16384);
- 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;
+
+ /* Add thread into runQ */
+ iresumeThread(mainThread);
+
assert(blockInts == 0);
}
#ifdef USE_THREADS
thread *aThread;
- for (aThread = liveThreads; aThread != 0;
- aThread = CONTEXT(aThread).nextlive) {
- mark((heapblock*)aThread);
- if (aThread == currentThread) {
- void **top_of_stack = &dummy;
-
- if (top_of_stack > (void**)CONTEXT(aThread).stackEnd)
- markreferences((void**)CONTEXT(aThread).stackEnd, top_of_stack);
- else
- markreferences(top_of_stack, (void**)CONTEXT(aThread).stackEnd);
+ if (currentThread == NULL) {
+ void **top_of_stack = &dummy;
+
+ if (top_of_stack > bottom_of_stack)
+ markreferences(bottom_of_stack, top_of_stack);
+ else
+ markreferences(top_of_stack, bottom_of_stack);
+ }
+ else {
+ for (aThread = liveThreads; aThread != 0;
+ aThread = CONTEXT(aThread).nextlive) {
+ mark((heapblock*)aThread);
+ if (aThread == currentThread) {
+ void **top_of_stack = &dummy;
+
+ if (top_of_stack > (void**)CONTEXT(aThread).stackEnd)
+ markreferences((void**)CONTEXT(aThread).stackEnd, top_of_stack);
+ else
+ markreferences(top_of_stack, (void**)CONTEXT(aThread).stackEnd);
}
- else {
- if (CONTEXT(aThread).usedStackTop > CONTEXT(aThread).stackEnd)
- markreferences((void**)CONTEXT(aThread).stackEnd,
- (void**)CONTEXT(aThread).usedStackTop);
- else
- markreferences((void**)CONTEXT(aThread).usedStackTop,
- (void**)CONTEXT(aThread).stackEnd);
+ else {
+ if (CONTEXT(aThread).usedStackTop > CONTEXT(aThread).stackEnd)
+ markreferences((void**)CONTEXT(aThread).stackEnd,
+ (void**)CONTEXT(aThread).usedStackTop);
+ else
+ markreferences((void**)CONTEXT(aThread).usedStackTop,
+ (void**)CONTEXT(aThread).stackEnd);
}
}
- markreferences((void**)&threadQhead[0],
- (void**)&threadQhead[MAX_THREAD_PRIO]);
-
+ markreferences((void**)&threadQhead[0],
+ (void**)&threadQhead[MAX_THREAD_PRIO]);
+ }
#else
void **top_of_stack = &dummy;
/************************* Function: gc_init **********************************
- Initializes the garbage collection thread mechanism.
+ Initializes anything that must be initialized to call the gc on the right
+ stack.
******************************************************************************/
-#ifdef USE_THREADS
-iMux gcStartMutex;
-iMux gcThreadMutex;
-iCv gcConditionStart;
-iCv gcConditionDone;
-
-void
-gc_init (void)
-{
- gcStartMutex.holder = 0;
- gcStartMutex.count = 0;
- gcStartMutex.muxWaiters = 0;
-
- gcThreadMutex.holder = 0;
- gcThreadMutex.count = 0;
- gcThreadMutex.muxWaiters = 0;
-
- gcConditionStart.cvWaiters = 0;
- gcConditionStart.mux = 0;
-
- gcConditionDone.cvWaiters = 0;
- gcConditionDone.mux = 0;
-}
-#else
void
gc_init (void)
{
}
-#endif
-/************************* Function: gc_thread ********************************
+/************************** Function: gc_call ********************************
- In an endless loop waits for a condition to be posted, then
- garbage collects the heap.
+ Calls the garbage collector. The garbage collector should always be called
+ using this function since it ensures that enough stack space is available.
******************************************************************************/
-#ifdef USE_THREADS
-void
-gc_thread (void)
-{
- intsRestore(); /* all threads start with interrupts disabled */
-
- assert(blockInts == 0);
-
- lock_mutex(&gcThreadMutex);
-
- for (;;)
- {
- wait_cond(&gcThreadMutex, &gcConditionStart, 0);
-
- intsDisable();
- assert(currentThread != mainThread);
- asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
- intsRestore();
-
- signal_cond(&gcConditionDone);
- }
-}
-#endif
-
void
gc_call (void)
{
#ifdef USE_THREADS
- lock_mutex(&gcThreadMutex);
-
- signal_cond(&gcConditionStart);
- wait_cond(&gcThreadMutex, &gcConditionDone, 0);
-
- unlock_mutex(&gcThreadMutex);
-#else
- heap_docollect();
+ assert(blockInts == 0);
#endif
+
+ intsDisable();
+ if (currentThread == NULL || currentThread == mainThread)
+ heap_docollect();
+ else
+ asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
+ intsRestore();
}
#ifdef USE_THREADS
thread *aThread;
- for (aThread = liveThreads; aThread != 0;
- aThread = CONTEXT(aThread).nextlive) {
- mark((heapblock*)aThread);
- if (aThread == currentThread) {
- void **top_of_stack = &dummy;
-
- if (top_of_stack > (void**)CONTEXT(aThread).stackEnd)
- markreferences((void**)CONTEXT(aThread).stackEnd, top_of_stack);
- else
- markreferences(top_of_stack, (void**)CONTEXT(aThread).stackEnd);
+ if (currentThread == NULL) {
+ void **top_of_stack = &dummy;
+
+ if (top_of_stack > bottom_of_stack)
+ markreferences(bottom_of_stack, top_of_stack);
+ else
+ markreferences(top_of_stack, bottom_of_stack);
+ }
+ else {
+ for (aThread = liveThreads; aThread != 0;
+ aThread = CONTEXT(aThread).nextlive) {
+ mark((heapblock*)aThread);
+ if (aThread == currentThread) {
+ void **top_of_stack = &dummy;
+
+ if (top_of_stack > (void**)CONTEXT(aThread).stackEnd)
+ markreferences((void**)CONTEXT(aThread).stackEnd, top_of_stack);
+ else
+ markreferences(top_of_stack, (void**)CONTEXT(aThread).stackEnd);
}
- else {
- if (CONTEXT(aThread).usedStackTop > CONTEXT(aThread).stackEnd)
- markreferences((void**)CONTEXT(aThread).stackEnd,
- (void**)CONTEXT(aThread).usedStackTop);
- else
- markreferences((void**)CONTEXT(aThread).usedStackTop,
- (void**)CONTEXT(aThread).stackEnd);
+ else {
+ if (CONTEXT(aThread).usedStackTop > CONTEXT(aThread).stackEnd)
+ markreferences((void**)CONTEXT(aThread).stackEnd,
+ (void**)CONTEXT(aThread).usedStackTop);
+ else
+ markreferences((void**)CONTEXT(aThread).usedStackTop,
+ (void**)CONTEXT(aThread).stackEnd);
}
}
- markreferences((void**)&threadQhead[0],
- (void**)&threadQhead[MAX_THREAD_PRIO]);
-
+ markreferences((void**)&threadQhead[0],
+ (void**)&threadQhead[MAX_THREAD_PRIO]);
+ }
#else
void **top_of_stack = &dummy;
/************************* Function: gc_init **********************************
- Initializes the garbage collection thread mechanism.
+ Initializes anything that must be initialized to call the gc on the right
+ stack.
******************************************************************************/
-#ifdef USE_THREADS
-iMux gcStartMutex;
-iMux gcThreadMutex;
-iCv gcConditionStart;
-iCv gcConditionDone;
-
-void
-gc_init (void)
-{
- gcStartMutex.holder = 0;
- gcStartMutex.count = 0;
- gcStartMutex.muxWaiters = 0;
-
- gcThreadMutex.holder = 0;
- gcThreadMutex.count = 0;
- gcThreadMutex.muxWaiters = 0;
-
- gcConditionStart.cvWaiters = 0;
- gcConditionStart.mux = 0;
-
- gcConditionDone.cvWaiters = 0;
- gcConditionDone.mux = 0;
-}
-#else
void
gc_init (void)
{
}
-#endif
-/************************* Function: gc_thread ********************************
+/************************** Function: gc_call ********************************
- In an endless loop waits for a condition to be posted, then
- garbage collects the heap.
+ Calls the garbage collector. The garbage collector should always be called
+ using this function since it ensures that enough stack space is available.
******************************************************************************/
-#ifdef USE_THREADS
-void
-gc_thread (void)
-{
- intsRestore(); /* all threads start with interrupts disabled */
-
- assert(blockInts == 0);
-
- lock_mutex(&gcThreadMutex);
-
- for (;;)
- {
- wait_cond(&gcThreadMutex, &gcConditionStart, 0);
-
- intsDisable();
- assert(currentThread != mainThread);
- asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
- intsRestore();
-
- signal_cond(&gcConditionDone);
- }
-}
-#endif
-
void
gc_call (void)
{
#ifdef USE_THREADS
- lock_mutex(&gcThreadMutex);
-
- signal_cond(&gcConditionStart);
- wait_cond(&gcThreadMutex, &gcConditionDone, 0);
-
- unlock_mutex(&gcThreadMutex);
-#else
- heap_docollect();
+ assert(blockInts == 0);
#endif
+
+ intsDisable();
+ if (currentThread == NULL || currentThread == mainThread)
+ heap_docollect();
+ else
+ asm_switchstackandcall(CONTEXT(mainThread).usedStackTop, heap_docollect);
+ intsRestore();
}
#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();
contexts[i].free = true;
/* Allocate a thread to be the main thread */
- mainThread = 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(&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;
+ 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", 16384);
- 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;
+
+ /* Add thread into runQ */
+ iresumeThread(mainThread);
+
assert(blockInts == 0);
}