VirtualBox

Changeset 36233 in vbox


Ignore:
Timestamp:
Mar 9, 2011 5:05:12 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
70454
Message:

IPRT: linux R0 threads

Location:
trunk/src/VBox
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r36232 r36233  
    289289    { "RTThreadUserWait",                       (void *)RTThreadUserWait },
    290290    { "RTThreadUserWaitNoResume",               (void *)RTThreadUserWaitNoResume },
     291#else
     292    /** 
     293     * @todo: remove me, once above code enabled. 
     294     * We need RTThreadCreate/RTThreadWait in the PCI driver.
     295     */
     296    { "RTThreadCreate",                         (void *)RTThreadCreate },
     297    { "RTThreadWait",                           (void *)RTThreadWait },
    291298#endif
    292299    { "RTThreadPreemptIsEnabled",               (void *)RTThreadPreemptIsEnabled },
     
    54685475    }
    54695476}
    5470 
  • trunk/src/VBox/HostDrivers/Support/linux/Makefile

    r36190 r36233  
    119119        common/misc/handletable.o \
    120120        common/misc/handletablectx.o \
     121        common/misc/thread.o \
    121122        common/string/strformat.o \
    122123        common/string/strformatrt.o \
     
    124125        common/string/strprintf.o \
    125126        common/string/strtonum.o \
     127        common/table/avlpv.o \
    126128        common/time/time.o \
    127129        r0drv/linux/RTLogWriteDebugger-r0drv-linux.o \
  • trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv

    r36190 r36233  
    111111    ${PATH_ROOT}/src/VBox/Runtime/common/misc/handletable.h=>common/misc/handletable.h \
    112112    ${PATH_ROOT}/src/VBox/Runtime/common/misc/handletablectx.cpp=>common/misc/handletablectx.c \
     113    ${PATH_ROOT}/src/VBox/Runtime/common/misc/thread.cpp=>common/misc/thread.c \
    113114    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
    114115    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>common/string/strformatrt.c \
     
    116117    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
    117118    ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
     119    ${PATH_ROOT}/src/VBox/Runtime/common/table/avlpv.cpp=>common/table/avlpv.c \
     120    ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Base.cpp.h=>common/table/avl_Base.cpp.h \
     121    ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Get.cpp.h=>common/table/avl_Get.cpp.h \
     122    ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_GetBestFit.cpp.h=>common/table/avl_GetBestFit.cpp.h \
     123    ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_RemoveBestFit.cpp.h=>common/table/avl_RemoveBestFit.cpp.h \
     124    ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_DoWithAll.cpp.h=>common/table/avl_DoWithAll.cpp.h \
     125    ${PATH_ROOT}/src/VBox/Runtime/common/table/avl_Destroy.cpp.h=>common/table/avl_Destroy.cpp.h \
    118126    ${PATH_ROOT}/src/VBox/Runtime/common/time/time.cpp=>common/time/time.c \
    119127    ${PATH_ROOT}/src/VBox/Runtime/include/internal/assert.h=>include/internal/assert.h \
     
    124132    ${PATH_ROOT}/src/VBox/Runtime/include/internal/memobj.h=>include/internal/memobj.h \
    125133    ${PATH_ROOT}/src/VBox/Runtime/include/internal/string.h=>include/internal/string.h \
     134    ${PATH_ROOT}/src/VBox/Runtime/include/internal/sched.h=>include/internal/sched.h \
     135    ${PATH_ROOT}/src/VBox/Runtime/include/internal/process.h=>include/internal/process.h \
    126136    ${PATH_ROOT}/src/VBox/Runtime/include/internal/thread.h=>include/internal/thread.h \
    127137    ${PATH_ROOT}/src/VBox/Runtime/include/internal/time.h=>include/internal/time.h \
  • trunk/src/VBox/Runtime/common/misc/thread.cpp

    r34256 r36233  
    155155
    156156#elif defined(IN_RING0)
    157 
     157    int rc;
    158158    /*
    159159     * Create the spinlock and to native init.
    160160     */
    161161    Assert(g_ThreadSpinlock == NIL_RTSPINLOCK);
    162     int rc = RTSpinlockCreate(&g_ThreadSpinlock);
     162    rc = RTSpinlockCreate(&g_ThreadSpinlock);
    163163    if (RT_SUCCESS(rc))
    164164    {
     
    238238static int rtThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, uint32_t fIntFlags, const char *pszName)
    239239{
     240    int rc;
     241    PRTTHREADINT pThread;
    240242    Assert(!(fFlags & RTTHREADFLAGS_WAITABLE));
    241243    fFlags &= ~RTTHREADFLAGS_WAITABLE;
     
    246248     * we try inserting the thread because of locking.)
    247249     */
    248     int rc = VERR_NO_MEMORY;
    249     PRTTHREADINT pThread = rtThreadAlloc(enmType, fFlags, RTTHREADINT_FLAGS_ALIEN | fIntFlags, pszName);
     250    rc = VERR_NO_MEMORY;
     251    pThread = rtThreadAlloc(enmType, fFlags, RTTHREADINT_FLAGS_ALIEN | fIntFlags, pszName);
    250252    if (pThread)
    251253    {
     
    274276RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread)
    275277{
     278    int      rc;
     279    RTTHREAD Thread;
     280
    276281    AssertReturn(!(fFlags & RTTHREADFLAGS_WAITABLE), VERR_INVALID_PARAMETER);
    277282    AssertReturn(!pszName || VALID_PTR(pszName), VERR_INVALID_POINTER);
    278283    AssertReturn(!pThread || VALID_PTR(pThread), VERR_INVALID_POINTER);
    279284
    280     int      rc = VINF_SUCCESS;
    281     RTTHREAD Thread = RTThreadSelf();
     285    rc = VINF_SUCCESS;
     286    Thread = RTThreadSelf();
    282287    if (Thread == NIL_RTTHREAD)
    283288    {
     
    341346    if (pThread)
    342347    {
     348        size_t cchName;
     349        int rc;
     350
    343351        pThread->Core.Key   = (void*)NIL_RTTHREAD;
    344352        pThread->u32Magic   = RTTHREADINT_MAGIC;
    345         size_t cchName = strlen(pszName);
     353        cchName = strlen(pszName);
    346354        if (cchName >= RTTHREAD_NAME_LEN)
    347355            cchName = RTTHREAD_NAME_LEN - 1;
     
    361369        rtStrIconvCacheInit(pThread);
    362370#endif
    363         int rc = RTSemEventMultiCreate(&pThread->EventUser);
     371        rc = RTSemEventMultiCreate(&pThread->EventUser);
    364372        if (RT_SUCCESS(rc))
    365373        {
     
    389397    Assert(pThread->u32Magic == RTTHREADINT_MAGIC);
    390398
    391     RT_THREAD_LOCK_TMP(Tmp);
    392     RT_THREAD_LOCK_RW(Tmp);
    393 
    394     /*
    395      * Do not insert a terminated thread.
    396      *
    397      * This may happen if the thread finishes before the RTThreadCreate call
    398      * gets this far. Since the OS may quickly reuse the native thread ID
    399      * it should not be reinserted at this point.
    400      */
    401     if (rtThreadGetState(pThread) != RTTHREADSTATE_TERMINATED)
    402     {
     399    {
     400        RT_THREAD_LOCK_TMP(Tmp);
     401        RT_THREAD_LOCK_RW(Tmp);
     402
    403403        /*
    404          * Before inserting we must check if there is a thread with this id
    405          * in the tree already. We're racing parent and child on insert here
    406          * so that the handle is valid in both ends when they return / start.
     404         * Do not insert a terminated thread.
    407405         *
    408          * If it's not ourself we find, it's a dead alien thread and we will
    409          * unlink it from the tree. Alien threads will be released at this point.
     406         * This may happen if the thread finishes before the RTThreadCreate call
     407         * gets this far. Since the OS may quickly reuse the native thread ID
     408         * it should not be reinserted at this point.
    410409         */
    411         PRTTHREADINT pThreadOther = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
    412         if (pThreadOther != pThread)
     410        if (rtThreadGetState(pThread) != RTTHREADSTATE_TERMINATED)
    413411        {
    414             /* remove dead alien if any */
    415             if (pThreadOther)
     412            /*
     413             * Before inserting we must check if there is a thread with this id
     414             * in the tree already. We're racing parent and child on insert here
     415             * so that the handle is valid in both ends when they return / start.
     416             *
     417             * If it's not ourself we find, it's a dead alien thread and we will
     418             * unlink it from the tree. Alien threads will be released at this point.
     419             */
     420            PRTTHREADINT pThreadOther = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
     421            if (pThreadOther != pThread)
    416422            {
    417                 AssertMsg(pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN, ("%p:%s; %p:%s\n", pThread, pThread->szName, pThreadOther, pThreadOther->szName));
    418                 ASMAtomicBitClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT);
    419                 rtThreadRemoveLocked(pThreadOther);
    420                 if (pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN)
     423                bool fRc;
     424                /* remove dead alien if any */
     425                if (pThreadOther)
     426                {
     427                    AssertMsg(pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN, ("%p:%s; %p:%s\n", pThread, pThread->szName, pThreadOther, pThreadOther->szName));
     428                    ASMAtomicBitClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT);
     429                    rtThreadRemoveLocked(pThreadOther);
     430                    if (pThreadOther->fIntFlags & RTTHREADINT_FLAGS_ALIEN)
    421431                    rtThreadRelease(pThreadOther);
     432                }
     433
     434                /* insert the thread */
     435                ASMAtomicWritePtr(&pThread->Core.Key, (void *)NativeThread);
     436                fRc = RTAvlPVInsert(&g_ThreadTree, &pThread->Core);
     437                ASMAtomicOrU32(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE);
     438
     439                AssertReleaseMsg(fRc, ("Lock problem? %p (%RTnthrd) %s\n", pThread, NativeThread, pThread->szName));
     440                NOREF(fRc);
    422441            }
    423 
    424             /* insert the thread */
    425             ASMAtomicWritePtr(&pThread->Core.Key, (void *)NativeThread);
    426             bool fRc = RTAvlPVInsert(&g_ThreadTree, &pThread->Core);
    427             ASMAtomicOrU32(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE);
    428 
    429             AssertReleaseMsg(fRc, ("Lock problem? %p (%RTnthrd) %s\n", pThread, NativeThread, pThread->szName));
    430             NOREF(fRc);
    431442        }
    432     }
    433 
    434     RT_THREAD_UNLOCK_RW(Tmp);
     443
     444        RT_THREAD_UNLOCK_RW(Tmp);
     445    }
    435446}
    436447
     
    489500PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread)
    490501{
     502    PRTTHREADINT pThread;
    491503    /*
    492504     * Simple tree lookup.
     
    494506    RT_THREAD_LOCK_TMP(Tmp);
    495507    RT_THREAD_LOCK_RD(Tmp);
    496     PRTTHREADINT pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
     508    pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
    497509    RT_THREAD_UNLOCK_RD(Tmp);
    498510    return pThread;
     
    534546uint32_t rtThreadRelease(PRTTHREADINT pThread)
    535547{
     548    uint32_t cRefs;
     549
    536550    Assert(pThread);
    537     uint32_t cRefs;
    538551    if (pThread->cRefs >= 1)
    539552    {
     
    558571static void rtThreadDestroy(PRTTHREADINT pThread)
    559572{
     573    RTSEMEVENTMULTI hEvt1, hEvt2;
    560574    /*
    561575     * Remove it from the tree and mark it as dead.
     
    588602    ASMAtomicWritePtr(&pThread->Core.Key, (void *)NIL_RTTHREAD);
    589603    pThread->enmType         = RTTHREADTYPE_INVALID;
    590     RTSEMEVENTMULTI hEvt1    = pThread->EventUser;
     604    hEvt1    = pThread->EventUser;
    591605    pThread->EventUser       = NIL_RTSEMEVENTMULTI;
    592     RTSEMEVENTMULTI hEvt2    = pThread->EventTerminated;
     606    hEvt2    = pThread->EventTerminated;
    593607    pThread->EventTerminated = NIL_RTSEMEVENTMULTI;
    594608
     
    657671int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread, const char *pszThreadName)
    658672{
     673    int rc;
    659674    NOREF(pszThreadName);
    660675    rtThreadInsert(pThread, NativeThread);
     
    665680     * Change the priority.
    666681     */
    667     int rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
     682    rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
    668683#ifdef IN_RING3
    669684    AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d enmPriority=%d rc=%Rrc\n",
     
    714729                           RTTHREADTYPE enmType, unsigned fFlags, const char *pszName)
    715730{
     731    int             rc;
     732    PRTTHREADINT    pThreadInt;
     733
    716734    LogFlow(("RTThreadCreate: pThread=%p pfnThread=%p pvUser=%p cbStack=%#x enmType=%d fFlags=%#x pszName=%p:{%s}\n",
    717735             pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszName, pszName));
     
    744762     * Allocate thread argument.
    745763     */
    746     int             rc;
    747     PRTTHREADINT    pThreadInt = rtThreadAlloc(enmType, fFlags, 0, pszName);
     764    pThreadInt = rtThreadAlloc(enmType, fFlags, 0, pszName);
    748765    if (pThreadInt)
    749766    {
     767        RTNATIVETHREAD NativeThread;
     768
    750769        pThreadInt->pfnThread = pfnThread;
    751770        pThreadInt->pvUser    = pvUser;
    752771        pThreadInt->cbStack   = cbStack;
    753772
    754         RTNATIVETHREAD NativeThread;
    755773        rc = rtThreadNativeCreate(pThreadInt, &NativeThread);
    756774        if (RT_SUCCESS(rc))
     
    820838{
    821839    va_list va;
     840    int rc;
    822841    va_start(va, pszNameFmt);
    823     int rc = RTThreadCreateV(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszNameFmt, va);
     842    rc = RTThreadCreateV(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, pszNameFmt, va);
    824843    va_end(va);
    825844    return rc;
     
    898917RTDECL(const char *) RTThreadGetName(RTTHREAD Thread)
    899918{
     919    PRTTHREADINT pThread;
    900920    if (Thread == NIL_RTTHREAD)
    901921        return NULL;
    902     PRTTHREADINT pThread = rtThreadGet(Thread);
     922    pThread = rtThreadGet(Thread);
    903923    if (pThread)
    904924    {
     
    924944     * Validate input.
    925945     */
     946    PRTTHREADINT pThread;
    926947    size_t cchName = strlen(pszName);
    927948    if (cchName >= RTTHREAD_NAME_LEN)
     
    930951        return VERR_INVALID_PARAMETER;
    931952    }
    932     PRTTHREADINT pThread = rtThreadGet(Thread);
     953    pThread = rtThreadGet(Thread);
    933954    if (!pThread)
    934955        return VERR_INVALID_HANDLE;
     
    14621483
    14631484#endif /* IPRT_WITH_GENERIC_TLS */
    1464 
  • trunk/src/VBox/Runtime/common/table/avl_Base.cpp.h

    r28800 r36233  
    295295    KAVLSTACK               AVLStack;
    296296    PPKAVLNODECORE          ppCurNode = ppTree;
     297    register PKAVLNODECORE  pCurNode;
    297298    register KAVLKEY        Key = pNode->Key; NOREF(Key);
    298299#ifdef KAVL_RANGE
    299300    register KAVLKEY        KeyLast = pNode->KeyLast; NOREF(KeyLast);
    300301#endif
    301     register PKAVLNODECORE  pCurNode;
    302302
    303303    AVLStack.cEntries = 0;
  • trunk/src/VBox/Runtime/r0drv/initterm-r0drv.cpp

    r33540 r36233  
    7979    if (RT_SUCCESS(rc))
    8080    {
    81 #if !defined(RT_OS_LINUX) /** @todo implement thread2-r0drv-linux.c */
    8281        rc = rtThreadInit();
    83 #endif
    8482        if (RT_SUCCESS(rc))
    8583        {
     
    9795                return rc;
    9896#endif
    99 #if !defined(RT_OS_LINUX) /** @todo implement thread2-r0drv-linux.c */
    10097            rtThreadTerm();
    101 #endif
    10298        }
    10399        rtR0TermNative();
     
    110106static void rtR0Term(void)
    111107{
    112 #if !defined(RT_OS_LINUX) /** @todo implement thread2-r0drv-linux.c */
    113108    rtThreadTerm();
    114 #endif
    115109#ifndef IN_GUEST /* play safe for now */
    116110    rtR0PowerNotificationTerm();
  • trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

    r35662 r36233  
    119119#include <asm/div64.h>
    120120
     121#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
     122# include <linux/kthread.h>
     123#endif
     124
    121125#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
    122126# ifndef page_to_pfn
     
    364368#endif
    365369
    366 
    367 #endif
    368 
     370#endif
  • trunk/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c

    r28800 r36233  
    3838
    3939
    40 /** @todo Later.
    4140RTDECL(RTTHREAD) RTThreadSelf(void)
    4241{
    4342    return rtThreadGetByNative((RTNATIVETHREAD)current);
    4443}
    45 */
    4644
     45int rtThreadNativeInit(void)
     46{
     47    return VINF_SUCCESS;
     48}
     49
     50int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
     51{
     52    int Priority = 0;
     53    switch (enmType)
     54    {
     55        case RTTHREADTYPE_INFREQUENT_POLLER:    Priority = 9; break;
     56        case RTTHREADTYPE_EMULATION:            Priority = 7; break;
     57        case RTTHREADTYPE_DEFAULT:              Priority = 8; break;
     58        case RTTHREADTYPE_MSG_PUMP:             Priority = 9; break;
     59        case RTTHREADTYPE_IO:                   Priority = 10; break;
     60        case RTTHREADTYPE_TIMER:                Priority = 11; break;
     61
     62        default:
     63            AssertMsgFailed(("enmType=%d\n", enmType));
     64            return VERR_INVALID_PARAMETER;
     65    }
     66    return VINF_SUCCESS;
     67}
     68
     69int rtThreadNativeAdopt(PRTTHREADINT pThread)
     70{
     71    return VERR_NOT_IMPLEMENTED;
     72}
     73
     74
     75void rtThreadNativeDestroy(PRTTHREADINT pThread)
     76{
     77    NOREF(pThread);
     78}
     79
     80/**
     81 * Native kernel thread wrapper function.
     82 *
     83 * This will forward to rtThreadMain and do termination upon return.
     84 *
     85 * @param pvArg         Pointer to the argument package.
     86 */
     87static int rtThreadNativeMain(void *pvArg)
     88{
     89    PRTTHREADINT pThread = (PRTTHREADINT)pvArg;
     90
     91    rtThreadMain(pThread, (RTNATIVETHREAD)current, &pThread->szName[0]);
     92    return 0;
     93}
     94
     95
     96int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
     97{
     98    struct task_struct *NativeThread;
     99
     100    RT_ASSERT_PREEMPTIBLE();
     101
     102    NativeThread = kthread_run(rtThreadNativeMain, pThreadInt, "%s", pThreadInt->szName);
     103
     104    if (IS_ERR(NativeThread))
     105        return VERR_GENERAL_FAILURE;
     106
     107    *pNativeThread = (RTNATIVETHREAD)NativeThread;
     108    return VINF_SUCCESS;
     109}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette