diff options
author | Dan Albert <danalbert@google.com> | 2015-06-17 11:09:54 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2015-06-17 14:15:22 -0700 |
commit | f378ebf14df0952eae870c9865bab8326aa8f137 (patch) | |
tree | 31794503eb2a8c64ea5f313b93100f1163afcffb /gcc-4.3.1/libjava/win32-threads.cc | |
parent | 2c58169824949d3a597d9fa81931e001ef9b1bd0 (diff) | |
download | toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.tar.gz toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.tar.bz2 toolchain_gcc-f378ebf14df0952eae870c9865bab8326aa8f137.zip |
Delete old versions of GCC.
Change-Id: I710f125d905290e1024cbd67f48299861790c66c
Diffstat (limited to 'gcc-4.3.1/libjava/win32-threads.cc')
-rw-r--r-- | gcc-4.3.1/libjava/win32-threads.cc | 567 |
1 files changed, 0 insertions, 567 deletions
diff --git a/gcc-4.3.1/libjava/win32-threads.cc b/gcc-4.3.1/libjava/win32-threads.cc deleted file mode 100644 index f2dbaaf94..000000000 --- a/gcc-4.3.1/libjava/win32-threads.cc +++ /dev/null @@ -1,567 +0,0 @@ -// win32-threads.cc - interface between libjava and Win32 threads. - -/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software - Foundation, Inc. - - 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. */ - -#include <config.h> - -// If we're using the Boehm GC, then we need to override some of the -// thread primitives. This is fairly gross. -#ifdef HAVE_BOEHM_GC -extern "C" -{ -#include <gc.h> -// <windows.h> #define's STRICT, which conflicts with Modifier.h -#undef STRICT -}; -#endif /* HAVE_BOEHM_GC */ - -#include <gcj/cni.h> -#include <jvm.h> -#include <java/lang/Thread.h> -#include <java/lang/System.h> - -#include <errno.h> - -#ifndef ETIMEDOUT -#define ETIMEDOUT 116 -#endif - -// This is used to implement thread startup. -struct starter -{ - _Jv_ThreadStartFunc *method; - _Jv_Thread_t *data; -}; - -// Controls access to the variable below -static HANDLE daemon_mutex; -static HANDLE daemon_cond; -// Number of non-daemon threads - _Jv_ThreadWait returns when this is 0 -static int non_daemon_count; - -// TLS key get Java object representing the thread -DWORD _Jv_ThreadKey; -// TLS key to get _Jv_Thread_t* representing the thread -DWORD _Jv_ThreadDataKey; - -// -// These are the flags that can appear in _Jv_Thread_t. -// - -// Thread started. -#define FLAG_START 0x01 -// Thread is daemon. -#define FLAG_DAEMON 0x02 - -// -// Helper -// -inline bool -compare_and_exchange(LONG volatile* dest, LONG cmp, LONG xchg) -{ - return InterlockedCompareExchange((LONG*) dest, xchg, cmp) == cmp; - // Seems like a bug in the MinGW headers that we have to do this cast. -} - -// -// Condition variables. -// - -// we do lazy creation of Events since CreateEvent() is insanely -// expensive, and because the rest of libgcj will call _Jv_CondInit -// when only a mutex is needed. - -inline void -ensure_condvar_initialized(_Jv_ConditionVariable_t *cv) -{ - if (cv->ev[0] == 0) - { - cv->ev[0] = CreateEvent (NULL, 0, 0, NULL); - if (cv->ev[0] == 0) JvFail("CreateEvent() failed"); - - cv->ev[1] = CreateEvent (NULL, 1, 0, NULL); - if (cv->ev[1] == 0) JvFail("CreateEvent() failed"); - } -} - -inline void -ensure_interrupt_event_initialized(HANDLE& rhEvent) -{ - if (!rhEvent) - { - rhEvent = CreateEvent (NULL, 0, 0, NULL); - if (!rhEvent) JvFail("CreateEvent() failed"); - } -} - -// Reimplementation of the general algorithm described at -// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (isomorphic to -// 3.2, not a cut-and-paste). - -int -_Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos) -{ - if (mu->owner != GetCurrentThreadId ( )) - return _JV_NOT_OWNER; - - _Jv_Thread_t *current = _Jv_ThreadCurrentData (); - java::lang::Thread *current_obj = _Jv_ThreadCurrent (); - - // Now that we hold the interrupt mutex, check if this thread has been - // interrupted already. - EnterCriticalSection (¤t->interrupt_mutex); - ensure_interrupt_event_initialized (current->interrupt_event); - jboolean interrupted = current_obj->interrupt_flag; - LeaveCriticalSection (¤t->interrupt_mutex); - - if (interrupted) - { - return _JV_INTERRUPTED; - } - - EnterCriticalSection (&cv->count_mutex); - ensure_condvar_initialized (cv); - cv->blocked_count++; - LeaveCriticalSection (&cv->count_mutex); - - DWORD time; - if ((millis == 0) && (nanos > 0)) time = 1; - else if (millis == 0) time = INFINITE; - else time = millis; - - // Record the current lock depth, so it can be restored - // when we reacquire it. - int count = mu->refcount; - int curcount = count; - - // Call _Jv_MutexUnlock repeatedly until this thread - // has completely released the monitor. - while (curcount > 0) - { - _Jv_MutexUnlock (mu); - --curcount; - } - - // Set up our array of three events: - // - the auto-reset event (for notify()) - // - the manual-reset event (for notifyAll()) - // - the interrupt event (for interrupt()) - // We wait for any one of these to be signaled. - HANDLE arh[3]; - arh[0] = cv->ev[0]; - arh[1] = cv->ev[1]; - arh[2] = current->interrupt_event; - DWORD rval = WaitForMultipleObjects (3, arh, 0, time); - - EnterCriticalSection (¤t->interrupt_mutex); - - // If we were unblocked by the third event (our thread's interrupt - // event), set the thread's interrupt flag. I think this sanity - // check guards against someone resetting our interrupt flag - // in the time between when interrupt_mutex is released in - // _Jv_ThreadInterrupt and the interval of time between the - // WaitForMultipleObjects call we just made and our acquisition - // of interrupt_mutex. - if (rval == (WAIT_OBJECT_0 + 2)) - current_obj->interrupt_flag = true; - - interrupted = current_obj->interrupt_flag; - LeaveCriticalSection (¤t->interrupt_mutex); - - EnterCriticalSection(&cv->count_mutex); - cv->blocked_count--; - // If we were unblocked by the second event (the broadcast one) - // and nobody is left, then reset the event. - int last_waiter = (rval == (WAIT_OBJECT_0 + 1)) && (cv->blocked_count == 0); - LeaveCriticalSection(&cv->count_mutex); - - if (last_waiter) - ResetEvent (cv->ev[1]); - - // Call _Jv_MutexLock repeatedly until the mutex's refcount is the - // same as before we originally released it. - while (curcount < count) - { - _Jv_MutexLock (mu); - ++curcount; - } - - return interrupted ? _JV_INTERRUPTED : 0; -} - -void -_Jv_CondInit (_Jv_ConditionVariable_t *cv) -{ - // we do lazy creation of Events since CreateEvent() is insanely expensive - cv->ev[0] = 0; - InitializeCriticalSection (&cv->count_mutex); - cv->blocked_count = 0; -} - -void -_Jv_CondDestroy (_Jv_ConditionVariable_t *cv) -{ - if (cv->ev[0] != 0) - { - CloseHandle (cv->ev[0]); - CloseHandle (cv->ev[1]); - - cv->ev[0] = 0; - } - - DeleteCriticalSection (&cv->count_mutex); -} - -int -_Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) -{ - if (mu->owner != GetCurrentThreadId ( )) - return _JV_NOT_OWNER; - - EnterCriticalSection (&cv->count_mutex); - ensure_condvar_initialized (cv); - int somebody_is_blocked = cv->blocked_count > 0; - LeaveCriticalSection (&cv->count_mutex); - - if (somebody_is_blocked) - SetEvent (cv->ev[0]); - - return 0; -} - -int -_Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) -{ - if (mu->owner != GetCurrentThreadId ( )) - return _JV_NOT_OWNER; - - EnterCriticalSection (&cv->count_mutex); - ensure_condvar_initialized (cv); - int somebody_is_blocked = cv->blocked_count > 0; - LeaveCriticalSection (&cv->count_mutex); - - if (somebody_is_blocked) - SetEvent (cv->ev[1]); - - return 0; -} - -// -// Threads. -// - -void -_Jv_InitThreads (void) -{ - _Jv_ThreadKey = TlsAlloc(); - _Jv_ThreadDataKey = TlsAlloc(); - daemon_mutex = CreateMutex (NULL, 0, NULL); - daemon_cond = CreateEvent (NULL, 1, 0, NULL); - non_daemon_count = 0; -} - -_Jv_Thread_t * -_Jv_ThreadInitData (java::lang::Thread* obj) -{ - _Jv_Thread_t *data = (_Jv_Thread_t*)_Jv_Malloc(sizeof(_Jv_Thread_t)); - data->flags = 0; - data->handle = 0; - data->thread_obj = obj; - data->interrupt_event = 0; - InitializeCriticalSection (&data->interrupt_mutex); - - return data; -} - -void -_Jv_ThreadDestroyData (_Jv_Thread_t *data) -{ - DeleteCriticalSection (&data->interrupt_mutex); - if (data->interrupt_event) - CloseHandle(data->interrupt_event); - CloseHandle(data->handle); - _Jv_Free(data); -} - -void -_Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio) -{ - int actual = THREAD_PRIORITY_NORMAL; - - if (data->flags & FLAG_START) - { - switch (prio) - { - case 10: - actual = THREAD_PRIORITY_TIME_CRITICAL; - break; - case 9: - actual = THREAD_PRIORITY_HIGHEST; - break; - case 8: - case 7: - actual = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case 6: - case 5: - actual = THREAD_PRIORITY_NORMAL; - break; - case 4: - case 3: - actual = THREAD_PRIORITY_BELOW_NORMAL; - break; - case 2: - actual = THREAD_PRIORITY_LOWEST; - break; - case 1: - actual = THREAD_PRIORITY_IDLE; - break; - } - SetThreadPriority(data->handle, actual); - } -} - -void -_Jv_ThreadRegister (_Jv_Thread_t *data) -{ - TlsSetValue (_Jv_ThreadKey, data->thread_obj); - TlsSetValue (_Jv_ThreadDataKey, data); -} - -void -_Jv_ThreadUnRegister () -{ - TlsSetValue (_Jv_ThreadKey, NULL); - TlsSetValue (_Jv_ThreadDataKey, NULL); -} - -// This function is called when a thread is started. We don't arrange -// to call the `run' method directly, because this function must -// return a value. -static DWORD WINAPI -really_start (void* x) -{ - struct starter *info = (struct starter *) x; - - _Jv_ThreadRegister (info->data); - - info->method (info->data->thread_obj); - - if (! (info->data->flags & FLAG_DAEMON)) - { - WaitForSingleObject (daemon_mutex, INFINITE); - non_daemon_count--; - if (! non_daemon_count) - SetEvent (daemon_cond); - ReleaseMutex (daemon_mutex); - } - - return 0; -} - -void -_Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data, _Jv_ThreadStartFunc *meth) -{ - DWORD id; - struct starter *info; - - // Do nothing if thread has already started - if (data->flags & FLAG_START) - return; - data->flags |= FLAG_START; - - info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter)); - info->method = meth; - info->data = data; - - if (! thread->isDaemon ()) - { - WaitForSingleObject (daemon_mutex, INFINITE); - non_daemon_count++; - ReleaseMutex (daemon_mutex); - } - else - data->flags |= FLAG_DAEMON; - - data->handle = GC_CreateThread(NULL, 0, really_start, info, 0, &id); - _Jv_ThreadSetPriority(data, thread->getPriority()); -} - -void -_Jv_ThreadWait (void) -{ - WaitForSingleObject (daemon_mutex, INFINITE); - if (non_daemon_count) - { - ReleaseMutex (daemon_mutex); - WaitForSingleObject (daemon_cond, INFINITE); - } -} - -// -// Interrupt support -// - -HANDLE -_Jv_Win32GetInterruptEvent (void) -{ - _Jv_Thread_t *current = _Jv_ThreadCurrentData (); - EnterCriticalSection (¤t->interrupt_mutex); - ensure_interrupt_event_initialized (current->interrupt_event); - HANDLE hEvent = current->interrupt_event; - LeaveCriticalSection (¤t->interrupt_mutex); - return hEvent; -} - -void -_Jv_ThreadInterrupt (_Jv_Thread_t *data) -{ - EnterCriticalSection (&data->interrupt_mutex); - ensure_interrupt_event_initialized (data->interrupt_event); - data->thread_obj->interrupt_flag = true; - SetEvent (data->interrupt_event); - LeaveCriticalSection (&data->interrupt_mutex); -} - -// park() / unpark() support - -void -ParkHelper::init () -{ - // We initialize our critical section, but not our event. - InitializeCriticalSection (&cs); - event = NULL; -} - -void -ParkHelper::init_event() -{ - EnterCriticalSection (&cs); - if (!event) - { - // Create an auto-reset event. - event = CreateEvent(NULL, 0, 0, NULL); - if (!event) JvFail("CreateEvent() failed"); - } - LeaveCriticalSection (&cs); -} - -void -ParkHelper::deactivate () -{ - permit = ::java::lang::Thread::THREAD_PARK_DEAD; -} - -void -ParkHelper::destroy() -{ - if (event) CloseHandle (event); - DeleteCriticalSection (&cs); -} - -/** - * Releases the block on a thread created by _Jv_ThreadPark(). This - * method can also be used to terminate a blockage caused by a prior - * call to park. This operation is unsafe, as the thread must be - * guaranteed to be live. - * - * @param thread the thread to unblock. - */ -void -ParkHelper::unpark () -{ - using namespace ::java::lang; - LONG volatile* ptr = &permit; - - // If this thread is in state RUNNING, give it a permit and return - // immediately. - if (compare_and_exchange - (ptr, Thread::THREAD_PARK_RUNNING, Thread::THREAD_PARK_PERMIT)) - return; - - // If this thread is parked, put it into state RUNNING and send it a - // signal. - if (compare_and_exchange - (ptr, Thread::THREAD_PARK_PARKED, Thread::THREAD_PARK_RUNNING)) - { - init_event (); - SetEvent (event); - } -} - -/** - * Blocks the thread until a matching _Jv_ThreadUnpark() occurs, the - * thread is interrupted or the optional timeout expires. If an - * unpark call has already occurred, this also counts. A timeout - * value of zero is defined as no timeout. When isAbsolute is true, - * the timeout is in milliseconds relative to the epoch. Otherwise, - * the value is the number of nanoseconds which must occur before - * timeout. This call may also return spuriously (i.e. for no - * apparent reason). - * - * @param isAbsolute true if the timeout is specified in milliseconds from - * the epoch. - * @param time either the number of nanoseconds to wait, or a time in - * milliseconds from the epoch to wait for. - */ -void -ParkHelper::park (jboolean isAbsolute, jlong time) -{ - using namespace ::java::lang; - LONG volatile* ptr = &permit; - - // If we have a permit, return immediately. - if (compare_and_exchange - (ptr, Thread::THREAD_PARK_PERMIT, Thread::THREAD_PARK_RUNNING)) - return; - - // Determine the number of milliseconds to wait. - jlong millis = 0, nanos = 0; - - if (time) - { - if (isAbsolute) - { - millis = time - ::java::lang::System::currentTimeMillis(); - nanos = 0; - } - else - { - millis = 0; - nanos = time; - } - - if (nanos) - { - millis += nanos / 1000000; - if (millis == 0) - millis = 1; - // ...otherwise, we'll block indefinitely. - } - } - - if (millis < 0) return; - // Can this ever happen? - - if (compare_and_exchange - (ptr, Thread::THREAD_PARK_RUNNING, Thread::THREAD_PARK_PARKED)) - { - init_event(); - - DWORD timeout = millis==0 ? INFINITE : (DWORD) millis; - WaitForSingleObject (event, timeout); - - // If we were unparked by some other thread, this will already - // be in state THREAD_PARK_RUNNING. If we timed out, we have to - // do it ourself. - compare_and_exchange - (ptr, Thread::THREAD_PARK_PARKED, Thread::THREAD_PARK_RUNNING); - } -} |