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 (java::lang::Thread
*)
129 _Jv_Thread_t
*data
= new _Jv_Thread_t
;
136 _Jv_ThreadDestroyData (_Jv_Thread_t
*data
)
142 _Jv_ThreadSetPriority (_Jv_Thread_t
*data
, jint prio
)
144 int actual
= THREAD_PRIORITY_NORMAL
;
146 if (data
->flags
& FLAG_START
)
151 actual
= THREAD_PRIORITY_TIME_CRITICAL
;
154 actual
= THREAD_PRIORITY_HIGHEST
;
158 actual
= THREAD_PRIORITY_ABOVE_NORMAL
;
162 actual
= THREAD_PRIORITY_NORMAL
;
166 actual
= THREAD_PRIORITY_BELOW_NORMAL
;
169 actual
= THREAD_PRIORITY_LOWEST
;
172 actual
= THREAD_PRIORITY_IDLE
;
175 SetThreadPriority(data
->handle
, actual
);
179 // This function is called when a thread is started. We don't arrange
180 // to call the `run' method directly, because this function must
182 static DWORD __stdcall
183 really_start (void* x
)
185 struct starter
*info
= (struct starter
*) x
;
187 TlsSetValue (_Jv_ThreadKey
, info
->object
);
188 TlsSetValue (_Jv_ThreadDataKey
, info
->data
);
189 info
->method (info
->object
);
191 if (! (info
->data
->flags
& FLAG_DAEMON
))
193 WaitForSingleObject (daemon_mutex
, INFINITE
);
195 if (! non_daemon_count
)
196 PulseEvent (daemon_cond
);
197 ReleaseMutex (daemon_mutex
);
204 _Jv_ThreadStart (java::lang::Thread
*thread
, _Jv_Thread_t
*data
, _Jv_ThreadStartFunc
*meth
)
207 struct starter
*info
;
209 // Do nothing if thread has already started
210 if (data
->flags
& FLAG_START
)
212 data
->flags
|= FLAG_START
;
214 // FIXME: handle marking the info object for GC.
215 info
= (struct starter
*) _Jv_AllocBytes (sizeof (struct starter
));
217 info
->object
= thread
;
220 if (! thread
->isDaemon ())
222 WaitForSingleObject (daemon_mutex
, INFINITE
);
224 ReleaseMutex (daemon_mutex
);
227 data
->flags
|= FLAG_DAEMON
;
229 HANDLE h
= CreateThread(NULL
, 0, really_start
, info
, 0, &id
);
230 _Jv_ThreadSetPriority(data
, thread
->getPriority());
237 _Jv_ThreadWait (void)
239 WaitForSingleObject(daemon_mutex
, INFINITE
);
241 SignalObjectAndWait(daemon_mutex
, daemon_cond
, INFINITE
, 0);
242 ReleaseMutex(daemon_mutex
);
246 _Jv_ThreadInterrupt (_Jv_Thread_t
*data
)
248 MessageBox(NULL
, "Unimplemented", "win32-threads.cc:_Jv_ThreadInterrupt", MB_OK
);