[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and to
From: |
Klaus Treichel |
Subject: |
[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. 2df493e8c0f5e8076e4d4136bced60842c154aa8 |
Date: |
Mon, 13 Jun 2011 17:04:17 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET engine, compilers and tools (pnet)".
The branch, master has been updated
via 2df493e8c0f5e8076e4d4136bced60842c154aa8 (commit)
from 05fc39b5cc7d675a627efbcce21f04b73d781a58 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/pnet.git/commit/?id=2df493e8c0f5e8076e4d4136bced60842c154aa8
commit 2df493e8c0f5e8076e4d4136bced60842c154aa8
Author: Klaus Treichel <address@hidden>
Date: Mon Jun 13 19:04:00 2011 +0200
Fix thread suspend and resume on Mac OSX.
diff --git a/ChangeLog b/ChangeLog
index e76d112..ddbaefe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2011-06-13 Klaus Treichel <address@hidden>
+
+ * support/pt_defs.c (_ILThreadSuspendUntinResumed): Clear
resumeRequested
+ on exit.
+ (_ILThreadInitHandleSelf): Set identifier to the native mach thread
+ on Darwin.
+ (_ILThreadInitSystem): Mask all signals during handling of an interrupt,
+ abort and resume signal.
+ Set identifier of the main thread to the native mach thread on Darwin.
+ (ThreadStart): Set identifier to the native mach thread on Darwin.
+
+ * support/pt_defs.h: (_ILThreadSuspendOther, _ILThreadResumeOther): Use
+ thread_suspend and thread_resume on darwin.
+ (_ILThreadResumeSelf): Don't clear resumeRequested.
+
+ * support/thr_defs.h (struct _tagILThread): Add member identifier only
if
+ requeted by the backend.
+
+ * support/thread.c (ILThreadSuspendRequest): Don't clear
resumeRequested.
+ Reset flags to IL_TS_SUSPEND_REQUESTED again if the thread has to
+ suspend itself.
+ (ILThreadResume): Clear suspendRequested if a thread is resumed before
it
+ had time to suspend itself.
+ (ILThreadJoin): Don't clear resumeRequested.
+ (_ILThreadLeaveWaitState): Don't clear resumeRequested.
+
+ * support/w32_defs.h: Notify thr_defs.h that the thread identifier is
+ needed for this backend.
+
+ * support/wait.c (_ILLeaveWait): Don't clear resumeRequested.
+
2011-04-26 Klaus Treichel <address@hidden>
* engine/coder.c (NestExceptionBlocks): Move from verify.c to here.
diff --git a/support/pt_defs.c b/support/pt_defs.c
index 24fdeae..a8170a8 100755
--- a/support/pt_defs.c
+++ b/support/pt_defs.c
@@ -229,6 +229,7 @@ void _ILThreadSuspendUntilResumed(ILThread *thread)
sigsuspend(&_suspendSet);
}
while(!(thread->resumeRequested));
+ thread->resumeRequested = 0;
}
/*
@@ -922,12 +923,13 @@ void _ILThreadInitHandleSelf(ILThread *thread)
{
/* Set the thread handle and identifier for the thread */
thread->handle = pthread_self();
- thread->identifier = thread->handle;
+#ifdef GC_DARWIN_THREADS
+ thread->identifier = pthread_mach_thread_np(thread->handle);
+#endif
}
void _ILThreadDestroyHandleSelf(ILThread *thread)
{
- /* there is nothing to do with pthreads. */
}
void _ILThreadInitSystem(ILThread *mainThread)
@@ -946,10 +948,16 @@ void _ILThreadInitSystem(ILThread *mainThread)
sigdelset(&(action.sa_mask), SIGTERM);
sigdelset(&(action.sa_mask), SIGABRT);
+ action.sa_flags = SA_RESTART;
+ action.sa_handler = SuspendSignal;
+ sigaction(IL_SIG_SUSPEND, &action, (struct sigaction *)0);
+
/*
* Abort signal - used to signal a thread abort.
* SA_RESTART must not be set.
*/
+ action.sa_flags = 0;
+ sigemptyset(&(action.sa_mask));
action.sa_handler = AbortSignal;
sigaction(IL_SIG_ABORT, &action, (struct sigaction *)0);
@@ -960,9 +968,10 @@ void _ILThreadInitSystem(ILThread *mainThread)
action.sa_handler = InterruptSignal;
sigaction(IL_SIG_INTERRUPT, &action, (struct sigaction *)0);
- action.sa_flags = SA_RESTART;
- action.sa_handler = SuspendSignal;
- sigaction(IL_SIG_SUSPEND, &action, (struct sigaction *)0);
+ /*
+ * Resume signal - used to resume a suspended thread.
+ * SA_RESTART must not be set.
+ */
action.sa_handler = ResumeSignal;
sigaction(IL_SIG_RESUME, &action, (struct sigaction *)0);
@@ -1018,8 +1027,9 @@ void _ILThreadInitSystem(ILThread *mainThread)
/* Set the thread handle and identifier for the main thread */
mainThread->handle = pthread_self();
- mainThread->identifier = mainThread->handle;
-
+#ifdef GC_DARWIN_THREADS
+ mainThread->identifier = pthread_mach_thread_np(mainThread->handle);
+#endif
/* Initialize the atomic operations */
ILInterlockedInit();
}
@@ -1044,7 +1054,9 @@ static void *ThreadStart(void *arg)
/* Store the thread identifier into the object */
thread->handle = pthread_self();
- thread->identifier = thread->handle;
+#ifdef GC_DARWIN_THREADS
+ thread->identifier = pthread_mach_thread_np(thread->handle);
+#endif
#if defined(USE_COMPILER_TLS)
/* Store the thread at the thread local storage */
@@ -1076,6 +1088,10 @@ static void *ThreadStart(void *arg)
/* Run the thread */
_ILThreadRun(thread);
+#ifdef GC_DARWIN_THREADS
+ thread->identifier = 0;
+#endif
+
/* The thread has exited back through its start function */
return 0;
}
@@ -1085,8 +1101,6 @@ int _ILThreadCreateSystem(ILThread *thread)
if(pthread_create((pthread_t *)&(thread->handle), (pthread_attr_t *)0,
ThreadStart, (void *)thread) == 0)
{
- /* Under pthreads, the thread identifier is the same as the
handle */
- thread->identifier = thread->handle;
return 1;
}
else
diff --git a/support/pt_defs.h b/support/pt_defs.h
index b4841e7..9234166 100755
--- a/support/pt_defs.h
+++ b/support/pt_defs.h
@@ -27,6 +27,10 @@
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
+#ifdef GC_DARWIN_THREADS
+#include <mach/mach.h>
+#include <mach/thread_act.h>
+#endif
#ifdef __cplusplus
extern "C" {
@@ -136,7 +140,10 @@ typedef pthread_mutex_t _ILMutex;
typedef pthread_mutex_t _ILCondMutex;
typedef pthread_cond_t _ILCondVar;
typedef pthread_t _ILThreadHandle;
-typedef pthread_t _ILThreadIdentifier;
+#ifdef GC_DARWIN_THREADS
+#define IL_THREAD_NEED_IDENTIFIER 1
+typedef mach_port_t _ILThreadIdentifier;
+#endif
typedef sem_t _ILSemaphore;
#ifdef IL_HAVE_RWLOCKS
typedef pthread_rwlock_t _ILRWLock;
@@ -228,6 +235,21 @@ typedef struct
#endif
/*
+ * Primitive semaphore operations.
+ */
+#define _ILSemaphoreCreate(sem) (sem_init((sem), 0, 0))
+#define _ILSemaphoreDestroy(sem) (sem_destroy((sem)))
+#define _ILSemaphoreWait(sem) \
+ do { \
+ while(sem_wait((sem)) == -1 && errno == EINTR) \
+ { \
+ continue; \
+ } \
+ } while(0)
+#define _ILSemaphorePost(sem) (sem_post((sem)))
+int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 count);
+
+/*
* Semaphore which allows to release multiple or all waiters.
* The semantic for posix and windows semaphores is the same and the
* implementation follows this semantics.
@@ -263,24 +285,50 @@ typedef struct
* Suspend and resume threads. Note: these are the primitive
* versions, which are not "suspend-safe".
*/
+#ifdef GC_DARWIN_THREADS
+#define _ILThreadSuspendOther(thread) \
+ do { \
+ thread_suspend((thread)->identifier); \
+ } while (0)
+#define _ILThreadResumeOther(thread) \
+ do { \
+ thread_resume((thread)->identifier); \
+ } while (0)
+#define _ILThreadSuspendSelf(thread) \
+ do { \
+ _ILThreadSuspendUntilResumed((thread)); \
+ _ILSemaphorePost(&((thread)->resumeAck)); \
+ } while (0)
+#define _ILThreadResumeSelf(thread) \
+ do { \
+ (thread)->resumeRequested = 1; \
+ pthread_kill((thread)->handle, IL_SIG_RESUME); \
+ _ILSemaphoreWait(&((thread)->resumeAck)); \
+ } while (0)
+#else
#define _ILThreadSuspendOther(thread) \
do { \
pthread_kill((thread)->handle, IL_SIG_SUSPEND);
\
_ILSemaphoreWait(&((thread)->suspendAck)); \
} while (0)
+#define _ILThreadResumeOther(thread) \
+ do { \
+ (thread)->resumeRequested = 1; \
+ pthread_kill((thread)->handle, IL_SIG_RESUME); \
+ _ILSemaphoreWait(&((thread)->resumeAck)); \
+ } while (0)
+#endif
#define _ILThreadSuspendSelf(thread) \
do { \
_ILThreadSuspendUntilResumed((thread)); \
- sem_post(&((thread)->resumeAck)); \
+ _ILSemaphorePost(&((thread)->resumeAck)); \
} while (0)
-#define _ILThreadResumeOther(thread) \
+#define _ILThreadResumeSelf(thread) \
do { \
(thread)->resumeRequested = 1; \
pthread_kill((thread)->handle, IL_SIG_RESUME); \
_ILSemaphoreWait(&((thread)->resumeAck)); \
- (thread)->resumeRequested = 0; \
} while (0)
-#define _ILThreadResumeSelf(thread)
_ILThreadResumeOther((thread))
/*
* Suspend the current thread until it is resumed.
@@ -390,21 +438,6 @@ int _ILCondMutexTimedLockUnsafe(_ILCondMutex *mutex,
ILUInt32 ms);
#endif
/*
- * Primitive semaphore operations.
- */
-#define _ILSemaphoreCreate(sem) (sem_init((sem), 0, 0))
-#define _ILSemaphoreDestroy(sem) (sem_destroy((sem)))
-#define _ILSemaphoreWait(sem) \
- do { \
- while(sem_wait((sem)) == -1 && errno == EINTR) \
- { \
- continue; \
- } \
- } while(0)
-#define _ILSemaphorePost(sem) (sem_post((sem)))
-int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 count);
-
-/*
* Primitive condition variable operations.
*/
#define _ILCondVarCreate(cond) \
diff --git a/support/thr_defs.h b/support/thr_defs.h
index 7ae44ea..5cf12f2 100755
--- a/support/thr_defs.h
+++ b/support/thr_defs.h
@@ -195,7 +195,12 @@ struct _tagILThread
{
_ILCriticalSection lock;
_ILThreadHandle volatile handle;
+#ifdef IL_THREAD_NEED_IDENTIFIER
+ /*
+ * Implementation specific native identification of the thread.
+ */
_ILThreadIdentifier volatile identifier;
+#endif
_ILThreadState state;
ILInt32 useCount;
unsigned char volatile resumeRequested;
diff --git a/support/thread.c b/support/thread.c
index 95d15eb..b83aff8 100644
--- a/support/thread.c
+++ b/support/thread.c
@@ -554,11 +554,10 @@ int ILThreadSuspendRequest(ILThread *thread, int
requestOnly)
else if(_ILThreadIsSelf(thread))
{
/* Mark the thread as suspended */
- threadState.split.pub &= ~ IL_TS_SUSPEND_REQUESTED;
+ threadState.split.pub &= ~IL_TS_SUSPEND_REQUESTED;
threadState.split.pub |= (IL_TS_SUSPENDED |
IL_TS_SUSPENDED_SELF);
ILInterlockedStoreU2(&(thread->state.split.pub),
threadState.split.pub);
- thread->resumeRequested = 0;
/* Unlock the thread object prior to suspending */
_ILCriticalSectionLeave(&(thread->lock));
@@ -575,7 +574,6 @@ int ILThreadSuspendRequest(ILThread *thread, int
requestOnly)
threadState.split.pub |= IL_TS_SUSPENDED;
ILInterlockedStoreU2(&(thread->state.split.pub),
threadState.split.pub);
- thread->resumeRequested = 0;
/* Put the thread to sleep temporarily */
_ILThreadSuspendOther(thread);
@@ -587,6 +585,12 @@ int ILThreadSuspendRequest(ILThread *thread, int
requestOnly)
return IL_SUSPEND_OK;
}
+ /* Mark the thread suspend itself */
+ threadState.split.pub &= ~IL_TS_SUSPENDED;
+ threadState.split.pub |= IL_TS_SUSPEND_REQUESTED;
+ ILInterlockedStoreU2(&(thread->state.split.pub),
+ threadState.split.pub);
+
/* Notify the thread that we want it to suspend itself */
thread->suspendRequested = 1;
@@ -645,6 +649,11 @@ void ILThreadResume(ILThread *thread)
threadState.split.pub &= ~IL_TS_SUSPEND_REQUESTED;
ILInterlockedStoreU2(&(thread->state.split.pub),
threadState.split.pub);
+ thread->suspendRequested = 0;
+ /*
+ * TODO: Notify the thread that requested the suspend becaue it
might be
+ * waiting for the ack.
+ */
}
/* Unlock the thread object */
@@ -977,7 +986,6 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
threadState.split.pub |=
(IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF);
ILInterlockedStoreU2(&(thread->state.split.pub),
threadState.split.pub);
- thread->resumeRequested = 0;
/* Remove ourselves from the foreign
thread's join queue */
_ILWakeupQueueRemove(&(thread->joinQueue), &(self->wakeup));
@@ -1184,11 +1192,10 @@ int _ILThreadLeaveWaitState(ILThread *thread, int
result)
{
threadState.split.pub &= ~IL_TS_SUSPEND_REQUESTED;
threadState.split.pub |= (IL_TS_SUSPENDED |
IL_TS_SUSPENDED_SELF);
- thread->resumeRequested = 0;
ILInterlockedStoreU2(&(thread->state.split.pub),
threadState.split.pub);
-
+
/* Unlock the thread object prior to suspending */
_ILCriticalSectionLeave(&(thread->lock));
@@ -1389,17 +1396,18 @@ void _ILThreadSuspendRequest(ILThread *thread)
_ILCriticalSectionEnter(&(thread->lock));
threadState = ILInterlockedLoadU2(&(thread->state.split.pub));
- /* Clear the "suspendRequested" and "resumeRequested" flags */
+ /* Clear the "suspendRequested" flag and set the suspended flags */
+ threadState &= ~IL_TS_SUSPEND_REQUESTED;
threadState |= (IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF);
ILInterlockedStoreU2(&(thread->state.split.pub), threadState);
thread->suspendRequested = 0;
- thread->resumeRequested = 0;
+
+ /* This implies a memory barrier */
+ _ILCriticalSectionLeave(&(thread->lock));
/* Signal the thread that wanted to make us suspend that we are */
_ILSemaphorePost(&(thread->suspendAck));
- _ILCriticalSectionLeave(&(thread->lock));
-
/* Suspend the current thread until we receive a resume signal */
_ILThreadSuspendSelf(thread);
}
diff --git a/support/w32_defs.h b/support/w32_defs.h
index 05f6937..a29f9cc 100755
--- a/support/w32_defs.h
+++ b/support/w32_defs.h
@@ -26,6 +26,11 @@ extern "C" {
#endif
/*
+ * We need the thread identifier in this implementation.
+ */
+#define IL_THREAD_NEED_IDENTIFIER 1
+
+/*
* Types that are needed elsewhere.
*/
typedef CRITICAL_SECTION _ILCriticalSection;
diff --git a/support/wait.c b/support/wait.c
index b3800b8..3129333 100644
--- a/support/wait.c
+++ b/support/wait.c
@@ -123,7 +123,6 @@ int _ILLeaveWait(ILThread *thread, int result)
threadState.split.pub &= ~(IL_TS_SUSPEND_REQUESTED |
IL_TS_INTERRUPTED);
threadState.split.pub |= (IL_TS_SUSPENDED |
IL_TS_SUSPENDED_SELF);
threadState.split.priv &= ~IL_TS_WAIT_SLEEP_JOIN;
- thread->resumeRequested = 0;
ILInterlockedStoreU4(&(thread->state.comb),
threadState.comb);
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 31 ++++++++++++++++++++++
support/pt_defs.c | 34 +++++++++++++++++-------
support/pt_defs.h | 73 +++++++++++++++++++++++++++++++++++++--------------
support/thr_defs.h | 5 +++
support/thread.c | 28 +++++++++++++-------
support/w32_defs.h | 5 +++
support/wait.c | 1 -
7 files changed, 136 insertions(+), 41 deletions(-)
hooks/post-receive
--
DotGNU Portable.NET engine, compilers and tools (pnet)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. 2df493e8c0f5e8076e4d4136bced60842c154aa8,
Klaus Treichel <=