diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2015-09-17 23:16:13 +0200 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2015-09-18 03:25:32 +0200 |
commit | f65f17708609ab554ed106822bf6d27dd658b712 (patch) | |
tree | a2783287784b314fb2e07ad0e282abd813999658 | |
parent | d176041723f366c35fd71ee4b176253fefddfee1 (diff) | |
download | coreclr-f65f17708609ab554ed106822bf6d27dd658b712.tar.gz coreclr-f65f17708609ab554ed106822bf6d27dd658b712.tar.bz2 coreclr-f65f17708609ab554ed106822bf6d27dd658b712.zip |
Change PAL_InjectActivation to use pthread_kill
This change modifies the PAL_InjectActivation to use much more portable pthread_kill
instead of pthread_sigqueue.
Remove the activation function passing from the PAL_InjectActivation
and add a PAL API to set the activation function globally, since we need just one.
-rw-r--r-- | src/pal/inc/pal.h | 9 | ||||
-rw-r--r-- | src/pal/src/exception/signal.cpp | 51 | ||||
-rw-r--r-- | src/vm/ceemain.cpp | 2 | ||||
-rw-r--r-- | src/vm/threads.cpp | 2 | ||||
-rw-r--r-- | src/vm/threadsuspend.cpp | 10 | ||||
-rw-r--r-- | src/vm/threadsuspend.h | 3 |
6 files changed, 56 insertions, 21 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index 4ed5e9267e..26252c2642 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -5448,11 +5448,16 @@ FlushProcessWriteBuffers(); typedef void (*PAL_ActivationFunction)(CONTEXT *context); PALIMPORT +VOID +PALAPI +PAL_SetActivationFunction( + IN PAL_ActivationFunction pActivationFunction); + +PALIMPORT BOOL PALAPI PAL_InjectActivation( - IN HANDLE hThread, - IN PAL_ActivationFunction pActivationFunction + IN HANDLE hThread ); #define VER_PLATFORM_WIN32_WINDOWS 1 diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp index 74b69f5a0b..444639a957 100644 --- a/src/pal/src/exception/signal.cpp +++ b/src/pal/src/exception/signal.cpp @@ -101,6 +101,9 @@ int g_signalPipe[2] = { 0, 0 }; DWORD g_dwExternalSignalHandlerThreadId = 0; +// Activation function that gets called when an activation is injected into a thread. +PAL_ActivationFunction g_activationFunction = NULL; + /* public function definitions ************************************************/ /*++ @@ -566,6 +569,28 @@ static void sigbus_handler(int code, siginfo_t *siginfo, void *context) } /*++ +Function: + PAL_SetActivationFunction + + Register an activation function that gets called when an activation is injected + into a thread. + +Parameters: + pActivationFunction - activation function + +Return value: + None +--*/ +PALIMPORT +VOID +PALAPI +PAL_SetActivationFunction( + IN PAL_ActivationFunction pActivationFunction) +{ + g_activationFunction = pActivationFunction; +} + +/*++ Function : inject_activation_handler @@ -582,8 +607,7 @@ static void inject_activation_handler(int code, siginfo_t *siginfo, void *contex // Only accept activations from the current process if (siginfo->si_pid == getpid()) { - PAL_ActivationFunction activation = (PAL_ActivationFunction)siginfo->si_value.sival_ptr; - if (activation != NULL) + if (g_activationFunction != NULL) { native_context_t *ucontext = (native_context_t *)context; @@ -593,7 +617,7 @@ static void inject_activation_handler(int code, siginfo_t *siginfo, void *contex &winContext, CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT); - activation(&winContext); + g_activationFunction(&winContext); // Activation function may have modified the context, so update it. CONTEXTToNativeContext(&winContext, ucontext); @@ -613,12 +637,9 @@ Parameters : (no return value) --*/ -void InjectActivationInternal(CorUnix::CPalThread* pThread, PAL_ActivationFunction activationFunction) +void InjectActivationInternal(CorUnix::CPalThread* pThread) { -#if HAVE_PTHREAD_SIGQUEUE - sigval value; - value.sival_ptr = (void*)activationFunction; - int status = pthread_sigqueue(pThread->GetPThreadSelf(), INJECT_ACTIVATION_SIGNAL, value); + int status = pthread_kill(pThread->GetPThreadSelf(), INJECT_ACTIVATION_SIGNAL); if (status != 0) { // Failure to send the signal is fatal. There are only two cases when sending @@ -626,20 +647,17 @@ void InjectActivationInternal(CorUnix::CPalThread* pThread, PAL_ActivationFuncti // if the thread doesn't exist anymore. abort(); } -#else - ASSERT("InjectActivationInternal not yet implemented on this platform!"); -#endif } /*++ Function: PAL_InjectActivation -Interrupt the specified thread and have it call the activation function passed in +Interrupt the specified thread and have it call an activation function registered +using the PAL_SetActivationFunction Parameters: hThread - handle of the target thread -activationFunction - function to call Return: TRUE if it succeeded, FALSE otherwise. @@ -647,11 +665,10 @@ TRUE if it succeeded, FALSE otherwise. BOOL PALAPI PAL_InjectActivation( - IN HANDLE hThread, - IN PAL_ActivationFunction pActivationFunction) + IN HANDLE hThread) { PERF_ENTRY(PAL_InjectActivation); - ENTRY("PAL_InjectActivation(hThread=%p, pActivationFunction=%p)\n", hThread, pActivationFunction); + ENTRY("PAL_InjectActivation(hThread=%p)\n", hThread); CPalThread *pCurrentThread; CPalThread *pTargetThread; @@ -669,7 +686,7 @@ PAL_InjectActivation( if (palError == NO_ERROR) { - InjectActivationInternal(pTargetThread, pActivationFunction); + InjectActivationInternal(pTargetThread); } else { diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index c6e67d0e8c..c1899f24fb 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -1160,7 +1160,7 @@ void EEStartupHelper(COINITIEE fFlags) #endif // PROFILING_SUPPORTED InitializeExceptionHandling(); - + // // Install our global exception filter // diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp index 007d233f14..e90a220c64 100644 --- a/src/vm/threads.cpp +++ b/src/vm/threads.cpp @@ -1691,6 +1691,8 @@ void InitThreadManager() // Randomize OBJREF_HASH to handle hash collision. Thread::OBJREF_HASH = OBJREF_TABSIZE - (DbgGetEXETimeStamp()%10); #endif // _DEBUG + + ThreadSuspend::Initialize(); } diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp index be220f334a..cc9080116d 100644 --- a/src/vm/threadsuspend.cpp +++ b/src/vm/threadsuspend.cpp @@ -8370,7 +8370,7 @@ bool Thread::InjectGcSuspension() hThread = GetThreadHandle(); if (hThread != INVALID_HANDLE_VALUE && hThread != SWITCHOUT_HANDLE_VALUE) { - ::PAL_InjectActivation(hThread, HandleGCSuspensionForInterruptedThread); + ::PAL_InjectActivation(hThread); return true; } @@ -8379,6 +8379,14 @@ bool Thread::InjectGcSuspension() #endif // FEATURE_HIJACK && PLATFORM_UNIX +// Initialize thread suspension support +void ThreadSuspend::Initialize() +{ +#if defined(FEATURE_HIJACK) && defined(PLATFORM_UNIX) + ::PAL_SetActivationFunction(HandleGCSuspensionForInterruptedThread); +#endif +} + #ifdef _DEBUG BOOL Debug_IsLockedViaThreadSuspension() { diff --git a/src/vm/threadsuspend.h b/src/vm/threadsuspend.h index 73f2b8b803..df88629ad2 100644 --- a/src/vm/threadsuspend.h +++ b/src/vm/threadsuspend.h @@ -197,6 +197,9 @@ public: static HRESULT SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason); static void ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded); + // Initialize thread suspension support + static void Initialize(); + private: static CLREvent * g_pGCSuspendEvent; |