From 7c2ddf15e59cec9fe51ad7eeac50ecb31762bc4c Mon Sep 17 00:00:00 2001 From: jlquinn Date: Tue, 21 Oct 2003 04:46:19 +0000 Subject: [PATCH] 2003-10-21 Jerry Quinn * posix-threads.cc (_Jv_CondNotify,_Jv_CondNotifyAll): Rename _Jv_PthreadCheckMonitor to _Jv_MutexCheckMonitor. * include/no-threads.h (_Jv_MutexCheckMonitor): New. * include/posix-threads.h (_Jv_MutexCheckMonitor): Rename from _Jv_PthreadCheckMonitor. Simplify code. (_Jv_MutexUnlock): Use _Jv_MutexCheckMonitor. * include/win32-threads.h (_Jv_MutexCheckMonitor): New. * java/lang/Object.h (_Jv_ObjectCheckMonitor): Declare. * java/lang/Thread.java (holdsLock): New. * java/lang/natObject.cc (_Jv_ObjectCheckMonitor): New, with and without JV_HASH_SYNCHRONIZATION. * java/lang/natThread.cc (java::lang::Thread::holdsLock): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72741 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 15 +++++++++++++ libjava/include/no-threads.h | 5 +++++ libjava/include/posix-threads.h | 9 +++----- libjava/include/win32-threads.h | 6 ++++++ libjava/java/lang/Object.h | 1 + libjava/java/lang/Thread.java | 9 ++++++++ libjava/java/lang/natObject.cc | 47 +++++++++++++++++++++++++++++++++++++++++ libjava/java/lang/natThread.cc | 8 +++++++ libjava/posix-threads.cc | 4 ++-- 9 files changed, 96 insertions(+), 8 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index e67710c..07d0127 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,18 @@ +2003-10-21 Jerry Quinn + + * posix-threads.cc (_Jv_CondNotify,_Jv_CondNotifyAll): Rename + _Jv_PthreadCheckMonitor to _Jv_MutexCheckMonitor. + * include/no-threads.h (_Jv_MutexCheckMonitor): New. + * include/posix-threads.h (_Jv_MutexCheckMonitor): Rename from + _Jv_PthreadCheckMonitor. Simplify code. + (_Jv_MutexUnlock): Use _Jv_MutexCheckMonitor. + * include/win32-threads.h (_Jv_MutexCheckMonitor): New. + * java/lang/Object.h (_Jv_ObjectCheckMonitor): Declare. + * java/lang/Thread.java (holdsLock): New. + * java/lang/natObject.cc (_Jv_ObjectCheckMonitor): New, with and + without JV_HASH_SYNCHRONIZATION. + * java/lang/natThread.cc (java::lang::Thread::holdsLock): New. + 2003-10-20 Michael Koch * java/text/RuleBasedCollator.java diff --git a/libjava/include/no-threads.h b/libjava/include/no-threads.h index 1cd2471..793cfad 100644 --- a/libjava/include/no-threads.h +++ b/libjava/include/no-threads.h @@ -75,6 +75,11 @@ _Jv_CondNotifyAll (_Jv_ConditionVariable_t *, _Jv_Mutex_t *) // Mutexes. // +inline int _Jv_MutexCheckMonitor (_Jv_Mutex_t *mu) +{ + return 0; +} + inline void _Jv_MutexInit (_Jv_Mutex_t *) { diff --git a/libjava/include/posix-threads.h b/libjava/include/posix-threads.h index 6c8dcec..01606df 100644 --- a/libjava/include/posix-threads.h +++ b/libjava/include/posix-threads.h @@ -77,12 +77,9 @@ typedef struct // this out. Returns 0 if the lock is held by the current thread, and // 1 otherwise. inline int -_Jv_PthreadCheckMonitor (_Jv_Mutex_t *mu) +_Jv_MutexCheckMonitor (_Jv_Mutex_t *mu) { - pthread_t self = pthread_self(); - if (mu->owner == self) - return 0; - else return 1; + return (mu->owner != pthread_self()); } // @@ -155,7 +152,7 @@ _Jv_MutexLock (_Jv_Mutex_t *mu) inline int _Jv_MutexUnlock (_Jv_Mutex_t *mu) { - if (_Jv_PthreadCheckMonitor (mu)) + if (_Jv_MutexCheckMonitor (mu)) { # ifdef LOCK_DEBUG fprintf(stderr, "_Jv_MutexUnlock: Not owner\n"); diff --git a/libjava/include/win32-threads.h b/libjava/include/win32-threads.h index ed5eb00..fdd21c5 100644 --- a/libjava/include/win32-threads.h +++ b/libjava/include/win32-threads.h @@ -86,6 +86,12 @@ int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *); // 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; diff --git a/libjava/java/lang/Object.h b/libjava/java/lang/Object.h index b0d8270..78ddbc4 100644 --- a/libjava/java/lang/Object.h +++ b/libjava/java/lang/Object.h @@ -49,6 +49,7 @@ public: friend void _Jv_MonitorExit (jobject obj); friend void _Jv_InitializeSyncMutex (void); friend void _Jv_FinalizeObject (jobject obj); + friend bool _Jv_ObjectCheckMonitor (jobject obj); #ifdef JV_MARKOBJ_DECL friend JV_MARKOBJ_DECL; diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java index 64498b2..d537220 100644 --- a/libjava/java/lang/Thread.java +++ b/libjava/java/lang/Thread.java @@ -182,6 +182,15 @@ public class Thread implements Runnable } /** + * Return true if this Thread holds the object's lock, false otherwise. + * + * @param obj the object to test lock ownership on. + * @throws NullPointerException if obj is null. + * @since 1.4 + */ + public static native boolean holdsLock (Object obj); + + /** * Interrupt this Thread. First, there is a security check, * checkAccess. Then, depending on the current state of the * thread, various actions take place: diff --git a/libjava/java/lang/natObject.cc b/libjava/java/lang/natObject.cc index 24faf29..a9f80d8 100644 --- a/libjava/java/lang/natObject.cc +++ b/libjava/java/lang/natObject.cc @@ -264,6 +264,13 @@ _Jv_MonitorExit (jobject obj) throw new java::lang::IllegalMonitorStateException; } +bool +_Jv_ObjectCheckMonitor (jobject obj) +{ + _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info; + return _Jv_MutexCheckMonitor (&si->mutex); +} + #else /* JV_HASH_SYNCHRONIZATION */ // FIXME: We shouldn't be calling GC_register_finalizer directly. @@ -1087,6 +1094,46 @@ retry: keep_live(addr); } +// Return false if obj's monitor is held by the current thread +bool +_Jv_ObjectCheckMonitor (jobject obj) +{ +#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS + obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS); +#else + obj_addr_t addr = (obj_addr_t)obj; +#endif + obj_addr_t address; + unsigned hash = JV_SYNC_HASH(addr); + hash_entry * he = light_locks + hash; + _Jv_ThreadId_t self = _Jv_ThreadSelf(); + + JvAssert(!(addr & FLAGS)); +retry: + // Acquire the hash table entry lock + address = ((he -> address) & ~LOCKED); + if (!compare_and_swap(&(he -> address), address, address | LOCKED)) + { + wait_unlocked(he); + goto retry; + } + + bool not_mine; + + if (!(address & ~FLAGS)) + not_mine = true; + else if ((address & ~FLAGS) == addr) + not_mine = (he -> light_thr_id != self); + else + { + heavy_lock* hl = find_heavy(addr, he); + not_mine = hl ? (hl->si.mutex.owner != self) : true; + } + + release_set(&(he -> address), address); // unlock hash entry + return not_mine; +} + // The rest of these are moderately thin veneers on _Jv_Cond ops. // The current version of Notify might be able to make the pthread // call AFTER releasing the lock, thus saving some context switches?? diff --git a/libjava/java/lang/natThread.cc b/libjava/java/lang/natThread.cc index 7fe8fb0..235f950 100644 --- a/libjava/java/lang/natThread.cc +++ b/libjava/java/lang/natThread.cc @@ -107,6 +107,14 @@ java::lang::Thread::destroy (void) (JvNewStringLatin1 ("Thread.destroy unimplemented")); } +jboolean +java::lang::Thread::holdsLock (jobject obj) +{ + if (!obj) + throw new NullPointerException; + return !_Jv_ObjectCheckMonitor (obj); +} + void java::lang::Thread::interrupt (void) { diff --git a/libjava/posix-threads.cc b/libjava/posix-threads.cc index 656f483..03ae453 100644 --- a/libjava/posix-threads.cc +++ b/libjava/posix-threads.cc @@ -193,7 +193,7 @@ _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, int _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) { - if (_Jv_PthreadCheckMonitor (mu)) + if (_Jv_MutexCheckMonitor (mu)) return _JV_NOT_OWNER; _Jv_Thread_t *target; @@ -232,7 +232,7 @@ _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu) { - if (_Jv_PthreadCheckMonitor (mu)) + if (_Jv_MutexCheckMonitor (mu)) return _JV_NOT_OWNER; _Jv_Thread_t *target; -- 2.7.4