[kaffe] CVS kaffe (guilhem): A few fixes for thread and pthreads.
Kaffe CVS
cvs-commits at kaffe.org
Tue Oct 12 13:00:01 PDT 2004
PatchSet 5282
Date: 2004/10/12 19:55:57
Author: guilhem
Branch: HEAD
Tag: (none)
Log:
A few fixes for thread and pthreads.
* kaffe/kaffevm/thread.c
(startSpecialThread): Use arg to get the specific arguments to start
the special thread.
(createDaemon): Use the real argument to the thread instead of
exceptObj and exceptPtr to pass arguments.
* kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
(activeThreadsLock, tLock): Use a native mutex lock instead of a kaffe
lock for thread list.
(TLOCK, TUNLOCK): Removed.
(protectThreadList, unprotectThreadList): Added.
(*): Replaced TLOCK and TUNLOCK by protectThreadList and
unprotectThreadList.
(jthread_walkLiveThreads): Protect the thread list while we are
walking it.
Members:
ChangeLog:1.2834->1.2835
kaffe/kaffevm/thread.c:1.74->1.75
kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.44->1.45
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2834 kaffe/ChangeLog:1.2835
--- kaffe/ChangeLog:1.2834 Tue Oct 12 17:21:52 2004
+++ kaffe/ChangeLog Tue Oct 12 19:55:57 2004
@@ -1,3 +1,21 @@
+2004-10-12 Guilhem Lavaux <guilhem at kaffe.org>
+
+ * kaffe/kaffevm/thread.c
+ (startSpecialThread): Use arg to get the specific arguments to start
+ the special thread.
+ (createDaemon): Use the real argument to the thread instead of
+ exceptObj and exceptPtr to pass arguments.
+
+ * kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
+ (activeThreadsLock, tLock): Use a native mutex lock instead of a kaffe
+ lock for thread list.
+ (TLOCK, TUNLOCK): Removed.
+ (protectThreadList, unprotectThreadList): Added.
+ (*): Replaced TLOCK and TUNLOCK by protectThreadList and
+ unprotectThreadList.
+ (jthread_walkLiveThreads): Protect the thread list while we are
+ walking it.
+
2004-10-12 Dalibor Topic <robilad at kaffe.org>
* libraries/clib/native/ZipFile.c:
Index: kaffe/kaffe/kaffevm/thread.c
diff -u kaffe/kaffe/kaffevm/thread.c:1.74 kaffe/kaffe/kaffevm/thread.c:1.75
--- kaffe/kaffe/kaffevm/thread.c:1.74 Fri Oct 1 15:02:30 2004
+++ kaffe/kaffe/kaffevm/thread.c Tue Oct 12 19:55:59 2004
@@ -281,9 +281,10 @@
*/
static
void
-startSpecialThread(void *arg UNUSED)
+startSpecialThread(void *arg)
{
void (*func)(void *);
+ void **pointer_args = (void **)arg;
void *argument;
int iLockRoot;
@@ -293,10 +294,8 @@
signalStaticCond(&thread_start_lock);
unlockStaticMutex(&thread_start_lock);
- func = (void *)THREAD_DATA()->exceptPtr;
- THREAD_DATA()->exceptPtr = NULL;
-
- argument = (void *)THREAD_DATA()->exceptObj;
+ func = (void(*)(void*))pointer_args[0];
+ argument = pointer_args[1];
THREAD_DATA()->exceptObj = NULL;
func(argument);
@@ -320,6 +319,7 @@
jthread_t nativeTid;
int iLockRoot;
Hjava_lang_String* name;
+ void *specialArgument[2];
DBG(VMTHREAD, dprintf("createDaemon %s\n", nm); )
@@ -346,13 +346,26 @@
"()Ljava/lang/ClassLoader;").l;
lockStaticMutex(&thread_start_lock);
+
+ specialArgument[0] = func;
+ specialArgument[1] = arg;
- nativeTid = createThread(vmtid, startSpecialThread, stacksize, einfo);
+ nativeTid =
+ jthread_create(((unsigned char)unhand(tid)->priority),
+ startSpecialThread,
+ true,
+ specialArgument,
+ stacksize);
- linkNativeAndJavaThread (nativeTid, vmtid);
+ if (nativeTid == NULL) {
+ postOutOfMemory(einfo);
+ return 0;
+ }
+
+ jthread_get_data(nativeTid)->exceptPtr = NULL;
+ jthread_get_data(nativeTid)->exceptObj = NULL;
- jthread_get_data(nativeTid)->exceptPtr = func;
- jthread_get_data(nativeTid)->exceptObj = arg;
+ linkNativeAndJavaThread (nativeTid, vmtid);
waitStaticCond(&thread_start_lock, (jlong)0);
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.44 kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.45
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.44 Tue Oct 12 08:45:02 2004
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/thread-impl.c Tue Oct 12 19:55:59 2004
@@ -104,6 +104,12 @@
/** We keep a list of all active threads, so that we can enumerate them */
static jthread_t activeThreads;
+/** This mutex lock prevents somebody to modify or read the active thread
+ * concurrently with some other threads. This prevents some bug that may appear
+ * when a thread die, is created or is being walked.
+ */
+pthread_mutex_t activeThreadsLock = PTHREAD_MUTEX_INITIALIZER;
+
/** We don't throw away threads when their user func terminates, but suspend
* and cache them for later re-use */
static jthread_t cache;
@@ -130,9 +136,6 @@
/** thread-specific-data key to retrieve 'nativeData' */
pthread_key_t ntKey;
-/** our lock to protect list manipulation/iteration */
-static iStaticLock tLock;
-
/** a hint to avoid unnecessary pthread_creates (with pending exits) */
static volatile int pendingExits;
@@ -158,15 +161,19 @@
static void* (*thread_malloc)(size_t);
static void (*thread_free)(void*);
-#define TLOCK(_nt) do { \
- (_nt)->blockState |= BS_THREAD; \
- lockStaticMutex (&tLock); \
-} while(0)
-
-#define TUNLOCK(_nt) do { \
- unlockStaticMutex (&tLock); \
- (_nt)->blockState &= ~BS_THREAD; \
-} while(0)
+static inline void
+protectThreadList(jthread_t cur)
+{
+ cur->blockState |= BS_THREAD;
+ jmutex_lock(&activeThreadsLock);
+}
+
+static inline void
+unprotectThreadList(jthread_t cur)
+{
+ jmutex_unlock(&activeThreadsLock);
+ cur->blockState &= ~BS_THREAD;
+}
/***********************************************************************
* internal functions
@@ -219,7 +226,7 @@
//void *cvNat = tLock.heavyLock.cv ? unhand(tLock.heavyLock.cv)->PrivateInfo : 0;
int iLockRoot;
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
dprintf("\n======================== thread dump =========================\n");
@@ -240,7 +247,7 @@
dprintf("====================== end thread dump =======================\n");
- TUNLOCK( cur); /* ------------------------------------------------------ tLock */
+ unprotectThreadList(cur);
})
}
@@ -673,13 +680,14 @@
while ( 1 ) {
DBG( JTHREAD, TMSG_LONG( "calling user func of: ", cur))
+
/* Now call our thread function, which happens to be firstStartThread(),
* which will call TExit before it returns */
cur->func(cur->data.jlThread);
DBG( JTHREAD, TMSG_LONG( "exiting user func of: ", cur))
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
/* remove from active list */
if ( cur == activeThreads ){
@@ -705,7 +713,7 @@
pendingExits--;
- TUNLOCK( cur); /* ---------------------------------------------------- tLock */
+ unprotectThreadList(cur);
/* we are done using locks now. ok to destroy ksem */
KaffeVM_unlinkNativeAndJavaThread();
@@ -781,7 +789,7 @@
nonDaemons++;
if ( cache ) {
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
/* move thread from the cache to the active list */
nt = cache;
@@ -804,7 +812,7 @@
nt->active = 1;
sem_post( &nt->sem);
- TUNLOCK( cur); /* ---------------------------------------------------- tLock */
+ unprotectThreadList(cur);
}
else {
int creation_succeeded;
@@ -835,7 +843,7 @@
/* Link the new one into the activeThreads list. We lock until
* the newly created thread is set up correctly (i.e. is walkable)
*/
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
nt->active = 1;
nt->next = activeThreads;
@@ -866,7 +874,7 @@
}
sem_destroy( &nt->sem);
- TUNLOCK( cur);
+ unprotectThreadList(cur);
thread_free(nt);
return 0;
}
@@ -875,7 +883,7 @@
* is in a suspendable state */
sem_wait( &nt->sem);
- TUNLOCK( cur); /* ---------------------------------------------------- tLock */
+ unprotectThreadList(cur);
}
return (nt);
}
@@ -923,7 +931,7 @@
if ( !cur->daemon ) {
/* the last non daemon should shut down the process */
if ( --nonDaemons == 0 ) {
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
DBG( JTHREAD, dprintf("exit on last nonDaemon\n"))
@@ -955,7 +963,7 @@
pthread_exit( 0);
/* pretty useless, but clean */
- TUNLOCK( cur); /* -------------------------------------------------- tLock */
+ unprotectThreadList(cur);
/* we shouldn't get here, this is a last safeguard */
EXIT(0);
@@ -968,7 +976,7 @@
* that the firstThread always has to be the last entry in the activeThreads list
* (we just add new entries at the head)
*/
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
/* if we would be the head, we would have been the last, too (and already exited) */
assert( cur != activeThreads);
@@ -977,7 +985,7 @@
assert( t != NULL);
t->next = 0;
- TUNLOCK( cur); /* ---------------------------------------------------- tLock */
+ unprotectThreadList(cur);
/*
* Put us into a permanent freeze to avoid shut down of the whole process (it's
@@ -1149,7 +1157,7 @@
int iLockRoot;
/* don't allow any new thread to be created or recycled until this is done */
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
DBG( JTHREAD, dprintf("enter crit section[%d] from: %p [tid:%4ld, java:%p)\n",
critSection, cur, cur->tid, cur->data.jlThread))
@@ -1211,7 +1219,7 @@
#endif
}
- TUNLOCK( cur); /* ------------------------------------------------------ tLock */
+ unprotectThreadList(cur);
DBG( JTHREAD, dprintf("critical section (%d) established\n", critSection))
}
@@ -1236,7 +1244,7 @@
/* No need to sync, there's nobody else running. It's just a matter of
* defensive programming (and we use our fast locks)
*/
- TLOCK( cur); /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tLock */
+ protectThreadList(cur);
#if !defined(KAFFE_BOEHM_GC)
for ( t=activeThreads; t; t = t->next ){
@@ -1279,7 +1287,7 @@
#endif
- TUNLOCK( cur); /*----------------------------------------------------- tLock */
+ unprotectThreadList(cur);
}
DBG( JTHREAD, dprintf("exit crit section (%d)\n", critSection))
@@ -1308,12 +1316,15 @@
jthread_walkLiveThreads (void(*func)(jthread_t,void*), void *private)
{
jthread_t t;
+ jthread_t cur = jthread_current();
DBG( JTHREAD, dprintf("start walking threads\n"))
+ protectThreadList(cur);
for ( t = activeThreads; t != NULL; t = t->next) {
func(t, private);
}
+ unprotectThreadList(cur);
DBG( JTHREAD, dprintf("end walking threads\n"))
}
More information about the kaffe
mailing list