This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: Implement java.lang.Thread.holdsLock
- From: jlquinn at optonline dot net
- To: java-patches at gcc dot gnu dot org
- Date: Thu, 16 Oct 2003 21:57:40 -0400 (EDT)
- Subject: Patch: Implement java.lang.Thread.holdsLock
- Date-warning: Date header was inserted by mta11.srv.hcvlny.cv.net
I was looking at the API comparison and saw that this is the only function
missing from java/lang. What do you think?
Thanks,
Jerry
2003-10-16 Jerry Quinn <jlquinn@optonline.net>
* 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.
Index: posix-threads.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/posix-threads.cc,v
retrieving revision 1.33
diff -u -w -r1.33 posix-threads.cc
--- posix-threads.cc 2 Mar 2003 01:24:40 -0000 1.33
+++ posix-threads.cc 17 Oct 2003 01:44:29 -0000
@@ -193,7 +193,7 @@
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 @@
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;
Index: include/no-threads.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/include/no-threads.h,v
retrieving revision 1.6
diff -u -w -r1.6 no-threads.h
--- include/no-threads.h 22 May 2001 06:47:48 -0000 1.6
+++ include/no-threads.h 17 Oct 2003 01:44:30 -0000
@@ -75,6 +75,11 @@
// Mutexes.
//
+inline int _Jv_MutexCheckMonitor (_Jv_Mutex_t *mu)
+{
+ return 0;
+}
+
inline void
_Jv_MutexInit (_Jv_Mutex_t *)
{
Index: include/posix-threads.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/include/posix-threads.h,v
retrieving revision 1.24
diff -u -w -r1.24 posix-threads.h
--- include/posix-threads.h 5 Jun 2003 15:43:58 -0000 1.24
+++ include/posix-threads.h 17 Oct 2003 01:44:30 -0000
@@ -77,12 +77,9 @@
// 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 @@
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");
Index: include/win32-threads.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/include/win32-threads.h,v
retrieving revision 1.8
diff -u -w -r1.8 win32-threads.h
--- include/win32-threads.h 19 Sep 2003 08:28:42 -0000 1.8
+++ include/win32-threads.h 17 Oct 2003 01:44:30 -0000
@@ -86,6 +86,12 @@
// 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;
Index: java/lang/Object.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/java/lang/Object.h,v
retrieving revision 1.10
diff -u -w -r1.10 Object.h
--- java/lang/Object.h 14 Dec 2001 18:43:53 -0000 1.10
+++ java/lang/Object.h 17 Oct 2003 01:44:30 -0000
@@ -49,6 +49,7 @@
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;
Index: java/lang/Thread.java
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/java/lang/Thread.java,v
retrieving revision 1.27
diff -u -w -r1.27 Thread.java
--- java/lang/Thread.java 7 Aug 2003 01:12:27 -0000 1.27
+++ java/lang/Thread.java 17 Oct 2003 01:44:30 -0000
@@ -182,6 +182,15 @@
}
/**
+ * 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,
* <code>checkAccess</code>. Then, depending on the current state of the
* thread, various actions take place:
Index: java/lang/natObject.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/java/lang/natObject.cc,v
retrieving revision 1.27
diff -u -w -r1.27 natObject.cc
--- java/lang/natObject.cc 15 Mar 2003 01:04:08 -0000 1.27
+++ java/lang/natObject.cc 17 Oct 2003 01:44:31 -0000
@@ -264,6 +264,13 @@
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.
@@ -1086,6 +1093,45 @@
}
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
Index: java/lang/natThread.cc
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/java/lang/natThread.cc,v
retrieving revision 1.24
diff -u -w -r1.24 natThread.cc
--- java/lang/natThread.cc 10 Apr 2002 20:36:04 -0000 1.24
+++ java/lang/natThread.cc 17 Oct 2003 01:44:31 -0000
@@ -107,6 +107,14 @@
(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)
{