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

Last change on this file since 2228 was 1392, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.4 KB
RevLine 
[2]1// win32-threads.cc - interface between libjava and Win32 threads.
2
[1391]3/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software
4 Foundation, Inc.
[2]5
6 This file is part of libgcj.
7
8This software is copyrighted work licensed under the terms of the
9Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10details. */
11
12#include <config.h>
13
14// If we're using the Boehm GC, then we need to override some of the
15// thread primitives. This is fairly gross.
16#ifdef HAVE_BOEHM_GC
17extern "C"
18{
19#include <gc.h>
20// <windows.h> #define's STRICT, which conflicts with Modifier.h
21#undef STRICT
22};
23#endif /* HAVE_BOEHM_GC */
24
25#include <gcj/cni.h>
26#include <jvm.h>
27#include <java/lang/Thread.h>
28#include <java/lang/System.h>
29
30#include <errno.h>
31
32#ifndef ETIMEDOUT
33#define ETIMEDOUT 116
34#endif
35
36// This is used to implement thread startup.
37struct starter
38{
39 _Jv_ThreadStartFunc *method;
40 _Jv_Thread_t *data;
41};
42
43// Controls access to the variable below
44static HANDLE daemon_mutex;
45static HANDLE daemon_cond;
46// Number of non-daemon threads - _Jv_ThreadWait returns when this is 0
47static int non_daemon_count;
48
49// TLS key get Java object representing the thread
50DWORD _Jv_ThreadKey;
51// TLS key to get _Jv_Thread_t* representing the thread
52DWORD _Jv_ThreadDataKey;
53
54//
55// These are the flags that can appear in _Jv_Thread_t.
56//
57
58// Thread started.
59#define FLAG_START 0x01
60// Thread is daemon.
61#define FLAG_DAEMON 0x02
62
63//
64// Condition variables.
65//
66
67// we do lazy creation of Events since CreateEvent() is insanely
68// expensive, and because the rest of libgcj will call _Jv_CondInit
69// when only a mutex is needed.
70
71inline void
72ensure_condvar_initialized(_Jv_ConditionVariable_t *cv)
73{
[1391]74 if (cv->ev[0] == 0)
75 {
76 cv->ev[0] = CreateEvent (NULL, 0, 0, NULL);
77 if (cv->ev[0] == 0) JvFail("CreateEvent() failed");
78
79 cv->ev[1] = CreateEvent (NULL, 1, 0, NULL);
80 if (cv->ev[1] == 0) JvFail("CreateEvent() failed");
81 }
[2]82}
83
84// Reimplementation of the general algorithm described at
85// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (isomorphic to
86// 3.2, not a cut-and-paste).
87
88int
89_Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos)
90{
[1391]91 if (mu->owner != GetCurrentThreadId ( ))
92 return _JV_NOT_OWNER;
[2]93
[1391]94 EnterCriticalSection (&cv->count_mutex);
95 ensure_condvar_initialized (cv);
[2]96 cv->blocked_count++;
[1391]97 LeaveCriticalSection (&cv->count_mutex);
[2]98
99 DWORD time;
100 if ((millis == 0) && (nanos > 0)) time = 1;
101 else if (millis == 0) time = INFINITE;
102 else time = millis;
103
104 _Jv_MutexUnlock (mu);
105
106 DWORD rval = WaitForMultipleObjects (2, &(cv->ev[0]), 0, time);
107
108 EnterCriticalSection(&cv->count_mutex);
109 cv->blocked_count--;
[1391]110 // If we were unblocked by the second event (the broadcast one)
111 // and nobody is left, then reset the event.
112 int last_waiter = (rval == (WAIT_OBJECT_0 + 1)) && (cv->blocked_count == 0);
[2]113 LeaveCriticalSection(&cv->count_mutex);
114
[1391]115 if (last_waiter)
116 ResetEvent (cv->ev[1]);
[2]117
118 _Jv_MutexLock (mu);
119
[1391]120 return 0;
[2]121}
122
123void
124_Jv_CondInit (_Jv_ConditionVariable_t *cv)
125{
126 // we do lazy creation of Events since CreateEvent() is insanely expensive
127 cv->ev[0] = 0;
[1391]128 InitializeCriticalSection (&cv->count_mutex);
[2]129 cv->blocked_count = 0;
130}
131
132void
133_Jv_CondDestroy (_Jv_ConditionVariable_t *cv)
134{
[1391]135 if (cv->ev[0] != 0)
136 {
137 CloseHandle (cv->ev[0]);
138 CloseHandle (cv->ev[1]);
139
140 cv->ev[0] = 0;
141 }
142