diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2000-03-15 22:03:19 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2000-03-15 22:03:19 +0000 |
commit | 878885b41142dd76e858b1f705bd31f357a5acc5 (patch) | |
tree | 6ff411e4ce4a6ce8717905d98f2d63b7479a6539 /libjava/win32-threads.cc | |
parent | 1a7b4c697c6ea7b132db9fdb84d3c9ff97c48e19 (diff) | |
download | gcc-878885b41142dd76e858b1f705bd31f357a5acc5.zip gcc-878885b41142dd76e858b1f705bd31f357a5acc5.tar.gz gcc-878885b41142dd76e858b1f705bd31f357a5acc5.tar.bz2 |
[multiple changes]
2000-03-15 Tom Tromey <tromey@cygnus.com>
* java/io/natFileDescriptorWin32.cc (winerr): Now static.
* prims.cc (win32_exception_handler): Reformatted.
* include/win32-threads.h (_Jv_HaveCondDestroy): New define.
(_Jv_HaveMutexDestroy): Likewise.
2000-03-15 Jon Beniston <jb7216@bristol.ac.uk>
* java/io/natFileDescriptorWin32.cc: New file.
* java/io/natFileWin32.cc: New file.
* java/net/natInetAddress.cc: Added conditional inclusion of
Windows / Winsock headers.
* java/net/natPlainDatagramSocketImpl.cc: Added conditional
inclusion of Windows / Winsock headers.
* java/net/natPlainSocketImpl.cc: Added conditional inclusion of
Windows / Winsock headers.
* include/win32-signal.h: New file.
* include/win32-threads.h: New file.
* win32-threads.cc: New file.
* exception.cc (win32_get_restart_frame): New function.
* prims.cc (win32_exception_handler): New function.
(main_init) Performs Winsock initialisation.
(main_init) Installs exeception handler.
From-SVN: r32567
Diffstat (limited to 'libjava/win32-threads.cc')
-rw-r--r-- | libjava/win32-threads.cc | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/libjava/win32-threads.cc b/libjava/win32-threads.cc new file mode 100644 index 0000000..9c6ae8c --- /dev/null +++ b/libjava/win32-threads.cc @@ -0,0 +1,247 @@ +// win32-threads.cc - interface between libjava and Win32 threads. + +/* Copyright (C) 1998, 1999 Red Hat, Inc. + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +#include <config.h> + +// If we're using the Boehm GC, then we need to override some of the +// thread primitives. This is fairly gross. +#ifdef HAVE_BOEHM_GC +extern "C" +{ +#include <boehm-config.h> +#include <gc.h> +}; +#endif /* HAVE_BOEHM_GC */ + +#include <gcj/cni.h> +#include <jvm.h> +#include <java/lang/Thread.h> +#include <java/lang/System.h> + +#include <errno.h> + +#ifndef ETIMEDOUT +#define ETIMEDOUT 116 +#endif + +// This is used to implement thread startup. +struct starter +{ + _Jv_ThreadStartFunc *method; + java::lang::Thread *object; + _Jv_Thread_t *data; +}; + +// Controls access to the variable below +static HANDLE daemon_mutex; +static HANDLE daemon_cond; +// Number of non-daemon threads - _Jv_ThreadWait returns when this is 0 +static int non_daemon_count; + +// TLS key get Java object representing the thread +DWORD _Jv_ThreadKey; +// TLS key to get _Jv_Thread_t* representing the thread +DWORD _Jv_ThreadDataKey; + +// +// These are the flags that can appear in _Jv_Thread_t. +// + +// Thread started. +#define FLAG_START 0x01 +// Thread is daemon. +#define FLAG_DAEMON 0x02 + +// +// Condition variables. +// + +int +_Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos) +{ + DWORD time; + DWORD rval; + + _Jv_MutexUnlock (mu); + + if((millis == 0) && (nanos > 0)) + time = 1; + else if(millis == 0) + time = INFINITE; + else + time = millis; + + rval = WaitForSingleObject (*cv, time); + _Jv_MutexLock (mu); + + if (rval == WAIT_FAILED) + return GetLastError (); // FIXME: Map to errno? + else if (rval == WAIT_TIMEOUT) + return ETIMEDOUT; + else + return 0; +} + +// +// Mutexes. +// + +int +_Jv_MutexLock (_Jv_Mutex_t *mu) +{ + DWORD rval; + + // FIXME: Are Win32 mutexs recursive? Should we use critical section objects + rval = WaitForSingleObject (*mu, INFINITE); + + if (rval == WAIT_FAILED) + return GetLastError (); // FIXME: Map to errno? + else if (rval == WAIT_TIMEOUT) + return ETIMEDOUT; + else + return 0; +} + +// +// Threads. +// + +void +_Jv_InitThreads (void) +{ + _Jv_ThreadKey = TlsAlloc(); + _Jv_ThreadDataKey = TlsAlloc(); + daemon_mutex = CreateMutex(NULL, 0, NULL); + daemon_cond = CreateEvent(NULL, 0, 0, NULL); + non_daemon_count = 0; +} + +void +_Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *) +{ + _Jv_Thread_t *info = new _Jv_Thread_t; + info->flags = 0; + + // FIXME register a finalizer for INFO here. + // FIXME also must mark INFO somehow. + + *data = info; +} + +void +_Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio) +{ + int actual = THREAD_PRIORITY_NORMAL; + + if (data->flags & FLAG_START) + { + switch (prio) + { + case 10: + actual = THREAD_PRIORITY_TIME_CRITICAL; + break; + case 9: + actual = THREAD_PRIORITY_HIGHEST; + break; + case 8: + case 7: + actual = THREAD_PRIORITY_ABOVE_NORMAL; + break; + case 6: + case 5: + actual = THREAD_PRIORITY_NORMAL; + break; + case 4: + case 3: + actual = THREAD_PRIORITY_BELOW_NORMAL; + break; + case 2: + actual = THREAD_PRIORITY_LOWEST; + break; + case 1: + actual = THREAD_PRIORITY_IDLE; + break; + } + SetThreadPriority(data->handle, actual); + } +} + +// This function is called when a thread is started. We don't arrange +// to call the `run' method directly, because this function must +// return a value. +static DWORD __stdcall +really_start (void* x) +{ + struct starter *info = (struct starter *) x; + + TlsSetValue (_Jv_ThreadKey, info->object); + TlsSetValue (_Jv_ThreadDataKey, info->data); + info->method (info->object); + + if (! (info->data->flags & FLAG_DAEMON)) + { + WaitForSingleObject (daemon_mutex, INFINITE); + non_daemon_count--; + if (! non_daemon_count) + PulseEvent (daemon_cond); + ReleaseMutex (daemon_mutex); + } + + return 0; +} + +void +_Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, _Jv_ThreadStartFunc *meth) +{ + DWORD id; + struct starter *info; + + // Do nothing if thread has already started + if (data->flags & FLAG_START) + return; + data->flags |= FLAG_START; + + // FIXME: handle marking the info object for GC. + info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter)); + info->method = meth; + info->object = thread; + info->data = data; + + if (! thread->isDaemon ()) + { + WaitForSingleObject (daemon_mutex, INFINITE); + non_daemon_count++; + ReleaseMutex (daemon_mutex); + } + else + data->flags |= FLAG_DAEMON; + + HANDLE h = CreateThread(NULL, 0, really_start, info, 0, &id); + _Jv_ThreadSetPriority(data, thread->getPriority()); + + //if (!h) + //JvThrow (); +} + +void +_Jv_ThreadWait (void) +{ + WaitForSingleObject(daemon_mutex, INFINITE); + if(non_daemon_count) + SignalObjectAndWait(daemon_mutex, daemon_cond, INFINITE, 0); + ReleaseMutex(daemon_mutex); +} + +void +_Jv_ThreadInterrupt (_Jv_Thread_t *data) +{ + MessageBox(NULL, "Unimplemented", "win32-threads.cc:_Jv_ThreadInterrupt", MB_OK); + // FIXME: +} |