diff options
Diffstat (limited to 'libjava/include/win32-threads.h')
-rw-r--r-- | libjava/include/win32-threads.h | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/libjava/include/win32-threads.h b/libjava/include/win32-threads.h new file mode 100644 index 000000000..b8f70f5cb --- /dev/null +++ b/libjava/include/win32-threads.h @@ -0,0 +1,232 @@ +// -*- c++ -*- +// win32-threads.h - Defines for using Win32 threads. + +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software + Foundation + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +#ifndef __JV_WIN32_THREADS__ +#define __JV_WIN32_THREADS__ + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +// +// Typedefs. +// + +typedef struct +{ + // ev[0] (signal) is a Win32 auto-reset event for _Jv_CondNotify + // ev[1] (broadcast) is a Win32 manual-reset event for _Jv_CondNotifyAll + HANDLE ev[2]; + + // Number of threads waiting on this condition variable + int blocked_count; + + // Protects access to the blocked_count variable + CRITICAL_SECTION count_mutex; + +} _Jv_ConditionVariable_t; + +typedef struct +{ + // The thread-id of the owner thread if any, 0 otherwise + DWORD owner; + + // Track nested mutex acquisitions by the same thread + int refcount; + + // The actual Windows construct used to implement this mutex + CRITICAL_SECTION cs; + +} _Jv_Mutex_t; + +typedef struct _Jv_Thread_t +{ + int flags; // Flags are defined in implementation. + HANDLE handle; // Actual handle to the thread + + // Protects access to the thread's interrupt_flag and + // interrupt_event variables within this module. + CRITICAL_SECTION interrupt_mutex; + + // A Win32 auto-reset event for thread interruption + HANDLE interrupt_event; + + java::lang::Thread *thread_obj; +} _Jv_Thread_t; + +typedef DWORD _Jv_ThreadId_t; + +inline _Jv_ThreadId_t +_Jv_ThreadSelf (void) +{ + return GetCurrentThreadId(); +} + +typedef void _Jv_ThreadStartFunc (java::lang::Thread *); + +// Type identifying a win32 thread. +typedef HANDLE _Jv_ThreadDesc_t; + +inline _Jv_ThreadDesc_t +_Jv_GetPlatformThreadID(_Jv_Thread_t *t) +{ + return t->handle; +} + +// +// Condition variables. +// + +#define _Jv_HaveCondDestroy +int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos); +void _Jv_CondInit (_Jv_ConditionVariable_t *cv); +void _Jv_CondDestroy (_Jv_ConditionVariable_t *cv); +int _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *); +int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *); + +// +// Mutexes. +// We use CRITICAL_SECTIONs instead of CreateMutex() for better performance +// + +// Returns 0 if the mutex lock is held by the current thread, and 1 otherwise. +inline int _Jv_MutexCheckMonitor (_Jv_Mutex_t *mu) +{ + return (mu->owner != GetCurrentThreadId ( )); +} + +inline void _Jv_MutexInit (_Jv_Mutex_t *mu) +{ + mu->owner = 0UL; + mu->refcount = 0; + InitializeCriticalSection (&(mu->cs)); +} + +#define _Jv_HaveMutexDestroy +inline void _Jv_MutexDestroy (_Jv_Mutex_t *mu) +{ + mu->owner = 0UL; + mu->refcount = 0; + DeleteCriticalSection (&(mu->cs)); + mu = NULL; +} + +inline int _Jv_MutexUnlock (_Jv_Mutex_t *mu) +{ + if (mu->owner == GetCurrentThreadId ( )) + { + mu->refcount--; + if (mu->refcount == 0) + mu->owner = 0UL; + LeaveCriticalSection (&(mu->cs)); + return 0; + } + else + return 1; +} + +inline int _Jv_MutexLock (_Jv_Mutex_t *mu) +{ + EnterCriticalSection (&(mu->cs)); + mu->owner = GetCurrentThreadId ( ); + mu->refcount++; + return 0; +} + +// +// Thread creation and manipulation. +// + +void _Jv_InitThreads (void); +_Jv_Thread_t *_Jv_ThreadInitData (java::lang::Thread *thread); +void _Jv_ThreadDestroyData (_Jv_Thread_t *data); + +inline java::lang::Thread* _Jv_ThreadCurrent (void) +{ + extern DWORD _Jv_ThreadKey; + return (java::lang::Thread *) TlsGetValue(_Jv_ThreadKey); +} + +inline _Jv_Thread_t *_Jv_ThreadCurrentData(void) +{ + extern DWORD _Jv_ThreadDataKey; + return (_Jv_Thread_t *) TlsGetValue(_Jv_ThreadDataKey); +} + +inline void _Jv_ThreadYield (void) +{ + Sleep (0); +} + +void _Jv_ThreadRegister (_Jv_Thread_t *data); +void _Jv_ThreadUnRegister (); + +void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio); +void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, + _Jv_ThreadStartFunc *meth); +void _Jv_ThreadWait (void); +void _Jv_ThreadInterrupt (_Jv_Thread_t *data); + +// +// Thread interruption support +// + +// Gets the auto-reset event for the current thread which is +// signalled by _Jv_ThreadInterrupt. The caller can wait on this +// event in addition to other waitable objects. +// +// NOTE: After waiting on this event with WaitForMultipleObjects, +// you should ALWAYS use the return value of WaitForMultipleObjects +// to test whether this event was signalled and whether thread +// interruption has occurred. You should do this instead of checking +// the thread's interrupted_flag, because someone could have reset +// this flag in the interval of time between the return of +// WaitForMultipleObjects and the time you query interrupted_flag. +// See java/lang/natWin32Process.cc (waitFor) for an example. +HANDLE _Jv_Win32GetInterruptEvent (void); + +// park() / unpark() support + +struct ParkHelper +{ + // We use LONG instead of obj_addr_t to avoid pulling in locks.h, + // which depends on size_t, ... + volatile LONG permit; + + // The critical section is used for lazy initialization of our event + CRITICAL_SECTION cs; + HANDLE event; + + void init (); + void deactivate (); + void destroy (); + void park (jboolean isAbsolute, jlong time); + void unpark (); + +private: + void init_event(); +}; + +// Remove defines from <windows.h> that conflict with various things in libgcj code + +#undef TRUE +#undef FALSE +#undef MAX_PRIORITY +#undef MIN_PRIORITY +#undef min +#undef max +#undef interface +#undef STRICT +#undef VOID +#undef TEXT +#undef OUT + +#endif /* __JV_WIN32_THREADS__ */ |