diff options
Diffstat (limited to 'src/VBox/Runtime/r3/posix/thread-posix.cpp')
-rw-r--r-- | src/VBox/Runtime/r3/posix/thread-posix.cpp | 148 |
1 files changed, 90 insertions, 58 deletions
diff --git a/src/VBox/Runtime/r3/posix/thread-posix.cpp b/src/VBox/Runtime/r3/posix/thread-posix.cpp index b212181a..66ccafb0 100644 --- a/src/VBox/Runtime/r3/posix/thread-posix.cpp +++ b/src/VBox/Runtime/r3/posix/thread-posix.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -47,17 +47,22 @@ # include <mach/mach_init.h> # include <mach/mach_host.h> #endif -#if defined(RT_OS_DARWIN) /*|| defined(RT_OS_FREEBSD) - later */ || defined(RT_OS_LINUX) \ +#if defined(RT_OS_DARWIN) /*|| defined(RT_OS_FREEBSD) - later */ \ + || (defined(RT_OS_LINUX) && !defined(IN_RT_STATIC) /* static + dlsym = trouble */) \ || defined(IPRT_MAY_HAVE_PTHREAD_SET_NAME_NP) # define IPRT_MAY_HAVE_PTHREAD_SET_NAME_NP # include <dlfcn.h> #endif +#if defined(RT_OS_HAIKU) +# include <OS.h> +#endif #include <iprt/thread.h> #include <iprt/log.h> #include <iprt/assert.h> #include <iprt/asm.h> #include <iprt/err.h> +#include <iprt/initterm.h> #include <iprt/string.h> #include "internal/thread.h" @@ -115,20 +120,14 @@ static void rtThreadKeyDestruct(void *pvValue); static void rtThreadPosixPokeSignal(int iSignal); -DECLHIDDEN(int) rtThreadNativeInit(void) -{ - /* - * Allocate the TLS (key in posix terms) where we store the pointer to - * a threads RTTHREADINT structure. - */ - int rc = pthread_key_create(&g_SelfKey, rtThreadKeyDestruct); - if (rc) - return VERR_NO_TLS_FOR_SELF; - #ifdef RTTHREAD_POSIX_WITH_POKE +/** + * Try register the dummy signal handler for RTThreadPoke. + */ +static void rtThreadPosixSelectPokeSignal(void) +{ /* - * Try register the dummy signal handler for RTThreadPoke. - * Avoid SIGRTMIN thru SIGRTMIN+2 because of LinuxThreads. + * Note! Avoid SIGRTMIN thru SIGRTMIN+2 because of LinuxThreads. */ static const int s_aiSigCandidates[] = { @@ -144,34 +143,53 @@ DECLHIDDEN(int) rtThreadNativeInit(void) }; g_iSigPokeThread = -1; - for (unsigned iSig = 0; iSig < RT_ELEMENTS(s_aiSigCandidates); iSig++) + if (!RTR3InitIsUnobtrusive()) { - struct sigaction SigActOld; - if (!sigaction(s_aiSigCandidates[iSig], NULL, &SigActOld)) + for (unsigned iSig = 0; iSig < RT_ELEMENTS(s_aiSigCandidates); iSig++) { - if ( SigActOld.sa_handler == SIG_DFL - || SigActOld.sa_handler == rtThreadPosixPokeSignal) + struct sigaction SigActOld; + if (!sigaction(s_aiSigCandidates[iSig], NULL, &SigActOld)) { - struct sigaction SigAct; - RT_ZERO(SigAct); - SigAct.sa_handler = rtThreadPosixPokeSignal; - SigAct.sa_flags = 0; - sigfillset(&SigAct.sa_mask); - - /* ASSUMES no sigaction race... (lazy bird) */ - if (!sigaction(s_aiSigCandidates[iSig], &SigAct, NULL)) + if ( SigActOld.sa_handler == SIG_DFL + || SigActOld.sa_handler == rtThreadPosixPokeSignal) { - g_iSigPokeThread = s_aiSigCandidates[iSig]; - break; + struct sigaction SigAct; + RT_ZERO(SigAct); + SigAct.sa_handler = rtThreadPosixPokeSignal; + SigAct.sa_flags = 0; + sigfillset(&SigAct.sa_mask); + + /* ASSUMES no sigaction race... (lazy bird) */ + if (!sigaction(s_aiSigCandidates[iSig], &SigAct, NULL)) + { + g_iSigPokeThread = s_aiSigCandidates[iSig]; + break; + } + AssertMsgFailed(("rc=%Rrc errno=%d\n", RTErrConvertFromErrno(errno), errno)); } - AssertMsgFailed(("rc=%Rrc errno=%d\n", RTErrConvertFromErrno(errno), errno)); } + else + AssertMsgFailed(("rc=%Rrc errno=%d\n", RTErrConvertFromErrno(errno), errno)); } - else - AssertMsgFailed(("rc=%Rrc errno=%d\n", RTErrConvertFromErrno(errno), errno)); } +} #endif /* RTTHREAD_POSIX_WITH_POKE */ + +DECLHIDDEN(int) rtThreadNativeInit(void) +{ + /* + * Allocate the TLS (key in posix terms) where we store the pointer to + * a threads RTTHREADINT structure. + */ + int rc = pthread_key_create(&g_SelfKey, rtThreadKeyDestruct); + if (rc) + return VERR_NO_TLS_FOR_SELF; + +#ifdef RTTHREAD_POSIX_WITH_POKE + rtThreadPosixSelectPokeSignal(); +#endif + #ifdef IPRT_MAY_HAVE_PTHREAD_SET_NAME_NP if (RT_SUCCESS(rc)) g_pfnThreadSetName = (PFNPTHREADSETNAME)(uintptr_t)dlsym(RTLD_DEFAULT, "pthread_setname_np"); @@ -179,6 +197,35 @@ DECLHIDDEN(int) rtThreadNativeInit(void) return rc; } +static void rtThreadPosixBlockSignals(void) +{ + /* + * Block SIGALRM - required for timer-posix.cpp. + * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling. + * It will not help much if someone creates threads directly using pthread_create. :/ + */ + if (!RTR3InitIsUnobtrusive()) + { + sigset_t SigSet; + sigemptyset(&SigSet); + sigaddset(&SigSet, SIGALRM); + sigprocmask(SIG_BLOCK, &SigSet, NULL); + } +#ifdef RTTHREAD_POSIX_WITH_POKE + if (g_iSigPokeThread != -1) + siginterrupt(g_iSigPokeThread, 1); +#endif +} + +DECLHIDDEN(void) rtThreadNativeReInitObtrusive(void) +{ +#ifdef RTTHREAD_POSIX_WITH_POKE + Assert(!RTR3InitIsUnobtrusive()); + rtThreadPosixSelectPokeSignal(); +#endif + rtThreadPosixBlockSignals(); +} + /** * Destructor called when a thread terminates. @@ -221,19 +268,7 @@ static void rtThreadPosixPokeSignal(int iSignal) */ DECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread) { - /* - * Block SIGALRM - required for timer-posix.cpp. - * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling. - * It will not help much if someone creates threads directly using pthread_create. :/ - */ - sigset_t SigSet; - sigemptyset(&SigSet); - sigaddset(&SigSet, SIGALRM); - sigprocmask(SIG_BLOCK, &SigSet, NULL); -#ifdef RTTHREAD_POSIX_WITH_POKE - if (g_iSigPokeThread != -1) - siginterrupt(g_iSigPokeThread, 1); -#endif + rtThreadPosixBlockSignals(); int rc = pthread_setspecific(g_SelfKey, pThread); if (!rc) @@ -266,19 +301,7 @@ static void *rtThreadNativeMain(void *pvArgs) ASMMemoryFence(); #endif - /* - * Block SIGALRM - required for timer-posix.cpp. - * This is done to limit harm done by OSes which doesn't do special SIGALRM scheduling. - * It will not help much if someone creates threads directly using pthread_create. :/ - */ - sigset_t SigSet; - sigemptyset(&SigSet); - sigaddset(&SigSet, SIGALRM); - sigprocmask(SIG_BLOCK, &SigSet, NULL); -#ifdef RTTHREAD_POSIX_WITH_POKE - if (g_iSigPokeThread != -1) - siginterrupt(g_iSigPokeThread, 1); -#endif + rtThreadPosixBlockSignals(); /* * Set the TLS entry and, if possible, the thread name. @@ -412,6 +435,15 @@ RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUs *pUserTime = ThreadInfo.user_time.seconds * 1000 + ThreadInfo.user_time.microseconds / 1000; return VINF_SUCCESS; +#elif defined(RT_OS_HAIKU) + thread_info ThreadInfo; + status_t status = get_thread_info(find_thread(NULL), &ThreadInfo); + AssertReturn(status == B_OK, RTErrConvertFromErrno(status)); + + *pKernelTime = ThreadInfo.kernel_time / 1000; + *pUserTime = ThreadInfo.user_time / 1000; + + return VINF_SUCCESS; #else return VERR_NOT_IMPLEMENTED; #endif |