]> gcc.gnu.org Git - gcc.git/blame - libjava/win32-threads.cc
[multiple changes]
[gcc.git] / libjava / win32-threads.cc
CommitLineData
878885b4
TT
1// win32-threads.cc - interface between libjava and Win32 threads.
2
3/* Copyright (C) 1998, 1999 Red Hat, Inc.
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11#include <config.h>
12
13// If we're using the Boehm GC, then we need to override some of the
14// thread primitives. This is fairly gross.
15#ifdef HAVE_BOEHM_GC
16extern "C"
17{
18#include <boehm-config.h>
19#include <gc.h>
20};
21#endif /* HAVE_BOEHM_GC */
22
23#include <gcj/cni.h>
24#include <jvm.h>
25#include <java/lang/Thread.h>
26#include <java/lang/System.h>
27
28#include <errno.h>
29
30#ifndef ETIMEDOUT
31#define ETIMEDOUT 116
32#endif
33
34// This is used to implement thread startup.
35struct starter
36{
37 _Jv_ThreadStartFunc *method;
38 java::lang::Thread *object;
39 _Jv_Thread_t *data;
40};
41
42// Controls access to the variable below
43static HANDLE daemon_mutex;
44static HANDLE daemon_cond;
45// Number of non-daemon threads - _Jv_ThreadWait returns when this is 0
46static int non_daemon_count;
47
48// TLS key get Java object representing the thread
49DWORD _Jv_ThreadKey;
50// TLS key to get _Jv_Thread_t* representing the thread
51DWORD _Jv_ThreadDataKey;
52
53//
54// These are the flags that can appear in _Jv_Thread_t.
55//
56
57// Thread started.
58#define FLAG_START 0x01
59// Thread is daemon.
60#define FLAG_DAEMON 0x02
61
62//
63// Condition variables.
64//
65
66int
67_Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos)
68{
69 DWORD time;
70 DWORD rval;
71
72 _Jv_MutexUnlock (mu);
73
74 if((millis == 0) && (nanos > 0))
75 time = 1;
76 else if(millis == 0)
77 time = INFINITE;
78 else
79 time = millis;
80
81 rval = WaitForSingleObject (*cv, time);
82 _Jv_MutexLock (mu);
83
84 if (rval == WAIT_FAILED)
85 return GetLastError (); // FIXME: Map to errno?
86 else if (rval == WAIT_TIMEOUT)
87 return ETIMEDOUT;
88 else
89 return 0;
90}
91
92//
93// Mutexes.
94//
95
96int
97_Jv_MutexLock (_Jv_Mutex_t *mu)
98{
99 DWORD rval;
100
101 // FIXME: Are Win32 mutexs recursive? Should we use critical section objects
102 rval = WaitForSingleObject (*mu, INFINITE);
103
104 if (rval == WAIT_FAILED)
105 return GetLastError (); // FIXME: Map to errno?
106 else if (rval == WAIT_TIMEOUT)
107 return ETIMEDOUT;
108 else
109 return 0;
110}
111
112//
113// Threads.
114//
115
116void
117_Jv_InitThreads (void)
118{
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;
124}
125
126void
127_Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *)
128{
129 _Jv_Thread_t *info = new _Jv_Thread_t;
130 info->flags = 0;
131
132 // FIXME register a finalizer for INFO here.
133 // FIXME also must mark INFO somehow.
134
135 *data = info;
136}
137
138void
139_Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio)
140{
141 int actual = THREAD_PRIORITY_NORMAL;
142
143 if (data->flags & FLAG_START)
144 {
145 switch (prio)
146 {
147 case 10:
148 actual = THREAD_PRIORITY_TIME_CRITICAL;
149 break;
150 case 9:
151 actual = THREAD_PRIORITY_HIGHEST;
152 break;
153 case 8:
154 case 7:
155 actual = THREAD_PRIORITY_ABOVE_NORMAL;
156 break;
157 case 6:
158 case 5:
159 actual = THREAD_PRIORITY_NORMAL;
160 break;
161 case 4:
162 case 3:
163 actual = THREAD_PRIORITY_BELOW_NORMAL;
164 break;
165 case 2:
166 actual = THREAD_PRIORITY_LOWEST;
167 break;
168 case 1:
169 actual = THREAD_PRIORITY_IDLE;
170 break;
171 }
172 SetThreadPriority(data->handle, actual);
173 }
174}
175
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
178// return a value.
179static DWORD __stdcall
180really_start (void* x)
181{
182 struct starter *info = (struct starter *) x;
183
184 TlsSetValue (_Jv_ThreadKey, info->object);
185 TlsSetValue (_Jv_ThreadDataKey, info->data);
186 info->method (info->object);
187
188 if (! (info->data->flags & FLAG_DAEMON))
189 {
190 WaitForSingleObject (daemon_mutex, INFINITE);
191 non_daemon_count--;
192 if (! non_daemon_count)
193 PulseEvent (daemon_cond);
194 ReleaseMutex (daemon_mutex);
195 }
196
197 return 0;
198}
199
200void
201_Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, _Jv_ThreadStartFunc *meth)
202{
203 DWORD id;
204 struct starter *info;
205
206 // Do nothing if thread has already started
207 if (data->flags & FLAG_START)
208 return;
209 data->flags |= FLAG_START;
210
211 // FIXME: handle marking the info object for GC.
212 info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter));
213 info->method = meth;
214 info->object = thread;
215 info->data = data;
216
217 if (! thread->isDaemon ())
218 {
219 WaitForSingleObject (daemon_mutex, INFINITE);
220 non_daemon_count++;
221 ReleaseMutex (daemon_mutex);
222 }
223 else
224 data->flags |= FLAG_DAEMON;
225
226 HANDLE h = CreateThread(NULL, 0, really_start, info, 0, &id);
227 _Jv_ThreadSetPriority(data, thread->getPriority());
228
229 //if (!h)
230 //JvThrow ();
231}
232
233void
234_Jv_ThreadWait (void)
235{
236 WaitForSingleObject(daemon_mutex, INFINITE);
237 if(non_daemon_count)
238 SignalObjectAndWait(daemon_mutex, daemon_cond, INFINITE, 0);
239 ReleaseMutex(daemon_mutex);
240}
241
242void
243_Jv_ThreadInterrupt (_Jv_Thread_t *data)
244{
245 MessageBox(NULL, "Unimplemented", "win32-threads.cc:_Jv_ThreadInterrupt", MB_OK);
246 // FIXME:
247}
This page took 0.051191 seconds and 5 git commands to generate.