1 // win32-threads.cc - interface between libjava and Win32 threads.
3 /* Copyright (C) 1998, 1999 Red Hat, Inc.
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
13 // If we're using the Boehm GC, then we need to override some of the
14 // thread primitives. This is fairly gross.
18 #include <boehm-config.h>
21 #endif /* HAVE_BOEHM_GC */
25 #include <java/lang/Thread.h>
26 #include <java/lang/System.h>
34 // This is used to implement thread startup.
37 _Jv_ThreadStartFunc *method;
38 java::lang::Thread *object;
42 // Controls access to the variable below
43 static HANDLE daemon_mutex;
44 static HANDLE daemon_cond;
45 // Number of non-daemon threads - _Jv_ThreadWait returns when this is 0
46 static int non_daemon_count;
48 // TLS key get Java object representing the thread
50 // TLS key to get _Jv_Thread_t* representing the thread
51 DWORD _Jv_ThreadDataKey;
54 // These are the flags that can appear in _Jv_Thread_t.
58 #define FLAG_START 0x01
60 #define FLAG_DAEMON 0x02
63 // Condition variables.
67 _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos)
72 // FIXME: check for mutex ownership?
76 if((millis == 0) && (nanos > 0))
83 rval = WaitForSingleObject (*cv, time);
86 if (rval == WAIT_FAILED)
87 return _JV_NOT_OWNER; // FIXME?
97 _Jv_MutexLock (_Jv_Mutex_t *mu)
101 // FIXME: Are Win32 mutexs recursive? Should we use critical section objects
102 rval = WaitForSingleObject (*mu, INFINITE);
104 if (rval == WAIT_FAILED)
105 return GetLastError (); // FIXME: Map to errno?
106 else if (rval == WAIT_TIMEOUT)
117 _Jv_InitThreads (void)
119 _Jv_ThreadKey = TlsAlloc();
120 _Jv_ThreadDataKey = TlsAlloc();
121 daemon_mutex = CreateMutex(NULL, 0, NULL);
122 daemon_cond = CreateEvent(NULL, 0, 0, NULL);
123 non_daemon_count = 0;
127 _Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *)
129 _Jv_Thread_t *info = new _Jv_Thread_t;
132 // FIXME register a finalizer for INFO here.
133 // FIXME also must mark INFO somehow.
139 _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio)
141 int actual = THREAD_PRIORITY_NORMAL;
143 if (data->flags & FLAG_START)
148 actual = THREAD_PRIORITY_TIME_CRITICAL;
151 actual = THREAD_PRIORITY_HIGHEST;
155 actual = THREAD_PRIORITY_ABOVE_NORMAL;
159 actual = THREAD_PRIORITY_NORMAL;
163 actual = THREAD_PRIORITY_BELOW_NORMAL;
166 actual = THREAD_PRIORITY_LOWEST;
169 actual = THREAD_PRIORITY_IDLE;
172 SetThreadPriority(data->handle, actual);
176 // This function is called when a thread is started. We don't arrange
177 // to call the `run' method directly, because this function must
179 static DWORD __stdcall
180 really_start (void* x)
182 struct starter *info = (struct starter *) x;
184 TlsSetValue (_Jv_ThreadKey, info->object);
185 TlsSetValue (_Jv_ThreadDataKey, info->data);
186 info->method (info->object);
188 if (! (info->data->flags & FLAG_DAEMON))
190 WaitForSingleObject (daemon_mutex, INFINITE);
192 if (! non_daemon_count)
193 PulseEvent (daemon_cond);
194 ReleaseMutex (daemon_mutex);
201 _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, _Jv_ThreadStartFunc *meth)
204 struct starter *info;
206 // Do nothing if thread has already started
207 if (data->flags & FLAG_START)
209 data->flags |= FLAG_START;
211 // FIXME: handle marking the info object for GC.
212 info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter));
214 info->object = thread;
217 if (! thread->isDaemon ())
219 WaitForSingleObject (daemon_mutex, INFINITE);
221 ReleaseMutex (daemon_mutex);
224 data->flags |= FLAG_DAEMON;
226 HANDLE h = CreateThread(NULL, 0, really_start, info, 0, &id);
227 _Jv_ThreadSetPriority(data, thread->getPriority());
234 _Jv_ThreadWait (void)
236 WaitForSingleObject(daemon_mutex, INFINITE);
238 SignalObjectAndWait(daemon_mutex, daemon_cond, INFINITE, 0);
239 ReleaseMutex(daemon_mutex);
243 _Jv_ThreadInterrupt (_Jv_Thread_t *data)
245 MessageBox(NULL, "Unimplemented", "win32-threads.cc:_Jv_ThreadInterrupt", MB_OK);