* Written by Tim Wilkinson <tim@tjwassoc.demon.co.uk>, 1996.
*/
-#include "config.h"
+#include "global.h"
+#include <stdlib.h>
+#include <string.h>
#include <assert.h>
-
#include <sys/types.h>
#include <sys/mman.h> /* for mprotect */
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
+#include "config.h"
#include "thread.h"
#include "locks.h"
-#include "defines.h"
-#include "threads.h"
-
#include "tables.h"
#include "native.h"
#include "loader.h"
#include "builtin.h"
#include "asmpart.h"
-
-#ifdef USE_BOEHM
+#include "toolbox/loging.h"
#include "toolbox/memory.h"
+#include "toolbox/avl.h"
+
+#if defined(NATIVE_THREADS)
+
+static struct avl_table *criticaltree;
+
+static int criticalcompare(const void *pa, const void *pb, void *param)
+{
+ const threadcritnode *na = pa;
+ const threadcritnode *nb = pb;
+
+ if (na->mcodebegin < nb->mcodebegin)
+ return -1;
+ if (na->mcodebegin > nb->mcodebegin)
+ return 1;
+ return 0;
+}
+
+static const threadcritnode *findcritical(u1 *mcodeptr)
+{
+ struct avl_node *n = criticaltree->avl_root;
+ const threadcritnode *m = NULL;
+ if (!n)
+ return NULL;
+ for (;;)
+ {
+ const threadcritnode *d = n->avl_data;
+ if (mcodeptr == d->mcodebegin)
+ return d;
+ if (mcodeptr < d->mcodebegin) {
+ if (n->avl_link[0])
+ n = n->avl_link[0];
+ else
+ return m;
+ } else {
+ if (n->avl_link[1]) {
+ m = n->avl_data;
+ n = n->avl_link[1];
+ } else
+ return n->avl_data;
+ }
+ }
+}
+
+void thread_registercritical(threadcritnode *n)
+{
+ avl_insert(criticaltree, n);
+}
+
+static int thread_checkcritical(u1 *mcodeptr)
+{
+ const threadcritnode *n = findcritical(mcodeptr);
+ if (!n)
+ return 0;
+ return (mcodeptr < n->mcodeend);
+}
+
+pthread_mutex_t cast_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t compiler_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
+int cast_counter;
+
+#ifndef HAVE___THREAD
+pthread_key_t tkey_threadinfo;
#endif
-static classinfo *class_java_lang_ThreadDeath;
+void cast_lock()
+{
+}
-#if defined(USE_INTERNAL_THREADS)
+void cast_unlock()
+{
+}
+
+#else // !defined(NATIVE_THREADS)
+
+static classinfo *class_java_lang_ThreadDeath;
thread* currentThread = NULL;
thread* mainThread;
allocThreadStack (thread *tid, int size)
{
int pageSize = getpagesize();
-#ifndef USE_BOEHM
- int result;
-#endif
unsigned long pageBegin;
assert(stack_to_be_freed == 0);
-#ifdef USE_BOEHM
CONTEXT(tid).stackMem = GCNEW(u1, size + 4 * pageSize);
-#else
- CONTEXT(tid).stackMem = malloc(size + 4 * pageSize);
-#endif
assert(CONTEXT(tid).stackMem != 0);
CONTEXT(tid).stackEnd = CONTEXT(tid).stackMem + size + 2 * pageSize;
pageBegin = (unsigned long)(CONTEXT(tid).stackMem) + pageSize - 1;
pageBegin = pageBegin - pageBegin % pageSize;
-#ifndef USE_BOEHM
- result = mprotect((void*)pageBegin, pageSize, PROT_NONE);
- assert(result == 0);
-#endif
-
CONTEXT(tid).stackBase = (u1*)pageBegin + pageSize;
}
if (!(CONTEXT(tid).flags & THREAD_FLAGS_NOSTACKALLOC))
{
int pageSize = getpagesize();
-#ifndef USE_BOEHM
- int result;
-#endif
unsigned long pageBegin;
pageBegin = (unsigned long)(CONTEXT(tid).stackMem) + pageSize - 1;
pageBegin = pageBegin - pageBegin % pageSize;
-#ifndef USE_BOEHM
- result = mprotect((void*)pageBegin, pageSize,
- PROT_READ | PROT_WRITE | PROT_EXEC);
- assert(result == 0);
-#endif
-
assert(stack_to_be_freed == 0);
stack_to_be_freed = CONTEXT(tid).stackMem;
void
initThreads(u1 *stackbottom)
{
+#if defined(NATIVE_THREADS)
+#if !defined(HAVE___THREAD)
+ pthread_key_create(&tkey_threadinfo, NULL);
+#endif
+
+ criticaltree = avl_create(criticalcompare, NULL, NULL);
+
+#endif
+
thread *the_main_thread;
int i;
char mainname[] = "main";
- int len = strlen(mainname);
+ /*int len = strlen(mainname);*/
signal(SIGPIPE, SIG_IGN);
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 */
- liveThreads = the_main_thread = (thread*)builtin_new(loader_load(utf_new_char("java/lang/Thread")));
+ liveThreads = the_main_thread = (thread*)builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Thread")));
assert(the_main_thread != 0);
- /* heap_addreference((void **) &liveThreads); */
the_main_thread->PrivateInfo = 1;
CONTEXT(the_main_thread).free = false;
{
/* stefan */
methodinfo *m;
- m = class_findmethod(
+ m = class_fetchmethod(
class_java_lang_String,
utf_new_char ("toCharArray"),
utf_new_char ("()[C")
the_main_thread->name = asm_calljavafunction (m, javastring_new(utf_new_char("main")), 0, 0, 0);
}
#endif
- the_main_thread->name = builtin_newarray_char(len);
+ the_main_thread->name=javastring_new(utf_new_char(mainname));
+/* the_main_thread->name = builtin_newarray_char(len);
{ u2 *d = the_main_thread->name->data;
for (i=0; i<len; i++)
d[i] = mainname[i];
- }
+ }*/
the_main_thread->priority = NORM_THREAD_PRIO;
CONTEXT(the_main_thread).priority = (u1)the_main_thread->priority;
- CONTEXT(the_main_thread).exceptionptr = 0;
+ CONTEXT(the_main_thread).texceptionptr = 0;
the_main_thread->next = 0;
CONTEXT(the_main_thread).status = THREAD_SUSPENDED;
CONTEXT(the_main_thread).stackBase = CONTEXT(the_main_thread).stackEnd = stackbottom;
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->single_step = 0;*/
the_main_thread->daemon = 0;
- the_main_thread->stillborn = 0;
- the_main_thread->target = 0;
+ /*the_main_thread->stillborn = 0;*/
+ /*the_main_thread->target = 0;*/
the_main_thread->contextClassLoader = 0;
- the_main_thread->inheritedAccessControlContext = 0;
- the_main_thread->values = 0;
+ /*the_main_thread->inheritedAccessControlContext = 0;*/
+ /*the_main_thread->values = 0;*/
/* Allocate and init ThreadGroup */
the_main_thread->group = (threadGroup*)native_new_and_init(loader_load(utf_new_char("java/lang/ThreadGroup")));
talive++;
/* Load exception classes */
- class_java_lang_ThreadDeath = loader_load(utf_new_char("java/lang/ThreadDeath"));
+ loader_load_sysclass(&class_java_lang_ThreadDeath,
+ utf_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);
CONTEXT(tid).flags = THREAD_FLAGS_GENERAL;
CONTEXT(tid).status = THREAD_SUSPENDED;
CONTEXT(tid).priority = (u1)tid->priority;
- CONTEXT(tid).exceptionptr = 0;
+ CONTEXT(tid).texceptionptr = 0;
/* Construct the initial restore point. */
THREADINIT((&CONTEXT(tid)), firstStartThread);
DBG( printf("startDaemon %s\n", nm); );
- tid = (thread*)builtin_new(loader_load(utf_new_char("java/lang/Thread")));
+ tid = (thread*)builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Thread")));
assert(tid != 0);
for (i = 0; i < MAXTHREADS; ++i)
CONTEXT(tid).status = THREAD_SUSPENDED;
allocThreadStack(tid, stackSize);
- tid->single_step = 0;
+ /*tid->single_step = 0;*/
tid->daemon = 1;
- tid->stillborn = 0;
- tid->target = 0;
+ /*tid->stillborn = 0;*/
+ /*tid->target = 0;*/
tid->group = 0;
/* Construct the initial restore point. */
firstStartThread(void)
{
methodinfo *method;
- java_objectheader *local_exceptionptr = NULL;
DBG( printf("firstStartThread %p\n", currentThread); );
- if (stack_to_be_freed != 0)
- {
-#ifndef USE_BOEHM
- free(stack_to_be_freed);
-#endif
+ if (stack_to_be_freed != 0) {
stack_to_be_freed = 0;
}
if (method == 0)
panic("Cannot find method \'void run ()\'");
- local_exceptionptr = asm_calljavamethod(method, currentThread, NULL, NULL, NULL);
+ asm_calljavafunction(method, currentThread, NULL, NULL, NULL);
- if (local_exceptionptr) {
- utf_display(local_exceptionptr->vftbl->class->name);
+ if (*exceptionptr) {
+ utf_display((*exceptionptr)->vftbl->class->name);
printf("\n");
}
lastThread = currentThread;
currentThread = threadQhead[i];
- CONTEXT(currentThread).exceptionptr = exceptionptr;
+ CONTEXT(currentThread).texceptionptr = *exceptionptr;
DBG( fprintf(stderr, "thread switch from: %p to: %p\n", lastThread, currentThread); );
THREADSWITCH((&CONTEXT(currentThread)),
(&CONTEXT(lastThread)));
blockInts = b;
- exceptionptr = CONTEXT(currentThread).exceptionptr;
+ *exceptionptr = CONTEXT(currentThread).texceptionptr;
- if (stack_to_be_freed != 0)
- {
-#ifndef USE_BOEHM
- free(stack_to_be_freed);
-#endif
+ if (stack_to_be_freed != 0) {
stack_to_be_freed = 0;
}
!= 0)
{
CONTEXT(lastThread).flags &= ~THREAD_FLAGS_KILLED;
- exceptionptr = native_new_and_init(class_java_lang_ThreadDeath);
+ *exceptionptr = native_new_and_init(class_java_lang_ThreadDeath);
}
}
/* Now we kill the schedule and turn ints