source: trunk/src/gcc/libjava/win32-threads.cc@ 853

Last change on this file since 853 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.1 KB
Line 
1// win32-threads.cc - interface between libjava and Win32 threads.
2
3/* Copyright (C) 1998, 1999 Free Software Foundation, 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 <gc.h>
19// <windows.h> #define's STRICT, which conflicts with Modifier.h
20#undef STRICT
21};
22#endif /* HAVE_BOEHM_GC */
23
24#include <gcj/cni.h>
25#include <jvm.h>
26#include <java/lang/Thread.h>
27#include <java/lang/System.h>
28
29#include <errno.h>
30
31#ifndef ETIMEDOUT
32#define ETIMEDOUT 116
33#endif
34
35// This is used to implement thread startup.
36struct starter
37{
38 _Jv_ThreadStartFunc *method;
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
66// we do lazy creation of Events since CreateEvent() is insanely
67// expensive, and because the rest of libgcj will call _Jv_CondInit
68// when only a mutex is needed.
69
70inline void
71ensure_condvar_initialized(_Jv_ConditionVariable_t *cv)
72{
73 if (cv->ev[0] == 0) {
74 cv->ev[0] = CreateEvent (NULL, 0, 0, NULL);
75 if (cv->ev[0] == 0) JvFail("CreateEvent() failed");
76 cv->ev[1] = CreateEvent (NULL, 1, 0, NULL);
77 if (cv->ev[1] == 0) JvFail("CreateEvent() failed");
78 }
79}
80
81// Reimplementation of the general algorithm described at
82// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (isomorphic to
83// 3.2, not a cut-and-paste).
84
85int
86_Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos)
87{
88
89 EnterCriticalSection(&cv->count_mutex);
90 ensure_condvar_initialized(cv);
91 cv->blocked_count++;
92 LeaveCriticalSection(&cv->count_mutex);
93
94 DWORD time;
95 if ((millis == 0) && (nanos > 0)) time = 1;
96 else if (millis == 0) time = INFINITE;
97 else time = millis;
98
99 _Jv_MutexUnlock (mu);
100
101 DWORD rval = WaitForMultipleObjects (2, &(cv->ev[0]), 0, time);
102
103 EnterCriticalSection(&cv->count_mutex);
104 cv->blocked_count--;
105 // If we were unblocked by the second event (the broadcast one) and nobody is
106 // left, then reset the signal.
107 int last_waiter = rval == WAIT_OBJECT_0 + 1 && cv->blocked_count == 0;
108 LeaveCriticalSection(&cv->count_mutex);
109
110 if (last_waiter) ResetEvent(&cv->ev[1]);
111
112 _Jv_MutexLock (mu);
113
114 if (rval == WAIT_FAILED) return GetLastError();
115 else if (rval == WAIT_TIMEOUT) return ETIMEDOUT;
116 else return 0;
117}
118
119void
120_Jv_CondInit (_Jv_ConditionVariable_t *cv)
121{
122 // we do lazy creation of Events since CreateEvent() is insanely expensive
123 cv->ev[0] = 0;
124 InitializeCriticalSection(&cv->count_mutex);
125 cv->blocked_count = 0;
126}
127
128void
129_Jv_CondDestroy (_Jv_ConditionVariable_t *cv)
130{
131 if (cv->ev[0] != 0) CloseHandle(cv->ev[0]);