VirtualBox

Changeset 403 in vbox


Ignore:
Timestamp:
Jan 28, 2007 8:45:05 AM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
17974
Message:

Need RTThreadWait in ring-0 too when using the generic timers, so thread.cpp was ported to ring-0. Fixed a bug in RTTimerStart() (the generic code). (hope this doesn't break the other platforms...)

Location:
trunk
Files:
1 deleted
17 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/thread.h

    r249 r403  
    165165    RTTHREADTYPE_TIMER,
    166166    /** Only used for validation. */
    167     RTTHREADTYPE_LAST
     167    RTTHREADTYPE_END
    168168} RTTHREADTYPE;
    169169
     
    234234RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType);
    235235
    236 #ifdef IN_RING3
     236/**
     237 * Wait for the thread to terminate, resume on interruption.
     238 *
     239 * @returns     iprt status code.
     240 *              Will not return VERR_INTERRUPTED.
     241 * @param       Thread          The thread to wait for.
     242 * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
     243 *                              an indefinite wait.
     244 * @param       prc             Where to store the return code of the thread. Optional.
     245 */
     246RTDECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc);
     247
     248/**
     249 * Wait for the thread to terminate, return on interruption.
     250 *
     251 * @returns     iprt status code.
     252 * @param       Thread          The thread to wait for.
     253 * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
     254 *                              an indefinite wait.
     255 * @param       prc             Where to store the return code of the thread. Optional.
     256 */
     257RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, unsigned cMillies, int *prc);
     258
     259/**
     260 * Gets the name of the current thread thread.
     261 *
     262 * @returns Pointer to readonly name string.
     263 * @returns NULL on failure.
     264 */
     265RTDECL(const char *) RTThreadSelfName(void);
     266
     267/**
     268 * Gets the name of a thread.
     269 *
     270 * @returns Pointer to readonly name string.
     271 * @returns NULL on failure.
     272 * @param   Thread      Thread handle of the thread to query the name of.
     273 */
     274RTDECL(const char *) RTThreadGetName(RTTHREAD Thread);
     275
    237276/**
    238277 * Gets the type of the specified thread.
     
    242281 * @param   Thread      The thread in question.
    243282 */
    244 RTR3DECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
     283RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
     284
     285/**
     286 * Sets the name of a thread.
     287 *
     288 * @returns iprt status code.
     289 * @param   Thread      Thread handle of the thread to query the name of.
     290 * @param   pszName     The thread name.
     291 */
     292RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
     293
     294/**
     295 * Signal the user event.
     296 *
     297 * @returns     iprt status code.
     298 */
     299RTDECL(int) RTThreadUserSignal(RTTHREAD Thread);
     300
     301/**
     302 * Wait for the user event.
     303 *
     304 * @returns     iprt status code.
     305 * @param       Thread          The thread to wait for.
     306 * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
     307 *                              an indefinite wait.
     308 */
     309RTDECL(int) RTThreadUserWait(RTTHREAD Thread, unsigned cMillies);
     310
     311/**
     312 * Wait for the user event, return on interruption.
     313 *
     314 * @returns     iprt status code.
     315 * @param       Thread          The thread to wait for.
     316 * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
     317 *                              an indefinite wait.
     318 */
     319RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, unsigned cMillies);
     320
     321/**
     322 * Reset the user event.
     323 *
     324 * @returns     iprt status code.
     325 * @param       Thread          The thread to reset.
     326 */
     327RTDECL(int) RTThreadUserReset(RTTHREAD Thread);
     328
     329
     330#ifdef IN_RING3
    245331
    246332/**
     
    256342
    257343/**
    258  * Gets the name of the current thread thread.
    259  *
    260  * @returns Pointer to readonly name string.
    261  * @returns NULL on failure.
    262  */
    263 RTR3DECL(const char *) RTThreadSelfName(void);
    264 
    265 /**
    266  * Gets the name of a thread.
    267  *
    268  * @returns Pointer to readonly name string.
    269  * @returns NULL on failure.
    270  * @param   Thread      Thread handle of the thread to query the name of.
    271  */
    272 RTR3DECL(const char *) RTThreadGetName(RTTHREAD Thread);
    273 
    274 /**
    275  * Sets the name of a thread.
    276  *
    277  * @returns iprt status code.
    278  * @param   Thread      Thread handle of the thread to query the name of.
    279  * @param   pszName     The thread name.
    280  */
    281 RTR3DECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
    282 
    283 /**
    284  * Signal the user event.
    285  *
    286  * @returns     iprt status code.
    287  */
    288 RTR3DECL(int) RTThreadUserSignal(RTTHREAD Thread);
    289 
    290 /**
    291  * Wait for the user event.
    292  *
    293  * @returns     iprt status code.
    294  * @param       Thread          The thread to wait for.
    295  * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
    296  *                              an indefinite wait.
    297  */
    298 RTR3DECL(int) RTThreadUserWait(RTTHREAD Thread, unsigned cMillies);
    299 
    300 /**
    301  * Wait for the user event, return on interruption.
    302  *
    303  * @returns     iprt status code.
    304  * @param       Thread          The thread to wait for.
    305  * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
    306  *                              an indefinite wait.
    307  */
    308 RTR3DECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, unsigned cMillies);
    309 
    310 /**
    311  * Reset the user event.
    312  *
    313  * @returns     iprt status code.
    314  * @param       Thread          The thread to reset.
    315  */
    316 RTR3DECL(int) RTThreadUserReset(RTTHREAD Thread);
    317 
    318 /**
    319  * Wait for the thread to terminate, resume on interruption.
    320  *
    321  * @returns     iprt status code.
    322  *              Will not return VERR_INTERRUPTED.
    323  * @param       Thread          The thread to wait for.
    324  * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
    325  *                              an indefinite wait.
    326  * @param       prc             Where to store the return code of the thread. Optional.
    327  */
    328 RTR3DECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc);
    329 
    330 /**
    331  * Wait for the thread to terminate, return on interruption.
    332  *
    333  * @returns     iprt status code.
    334  * @param       Thread          The thread to wait for.
    335  * @param       cMillies        The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
    336  *                              an indefinite wait.
    337  * @param       prc             Where to store the return code of the thread. Optional.
    338  */
    339 RTR3DECL(int) RTThreadWaitNoResume(RTTHREAD Thread, unsigned cMillies, int *prc);
    340 
    341 /**
    342344 * Gets the affinity mask of the current thread.
    343345 *
  • trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c

    r397 r403  
    113113    { "RTSpinlockAcquireNoInts",                (void *)RTSpinlockAcquireNoInts },
    114114    { "RTSpinlockReleaseNoInts",                (void *)RTSpinlockReleaseNoInts },
    115     { "RTThreadSelf",                           (void *)RTThreadSelf },
     115    { "RTThreadNativeSelf",                     (void *)RTThreadNativeSelf },
    116116    { "RTThreadSleep",                          (void *)RTThreadSleep },
    117117    { "RTThreadYield",                          (void *)RTThreadYield },
     118#if 0 /* Thread APIs, Part 2. */
     119    { "RTThreadSelf",                           (void *)RTThreadSelf },
     120    { "RTThreadCreate",                         (void *)RTThreadCreate },
     121    { "RTThreadGetNative",                      (void *)RTThreadGetNative },
     122    { "RTThreadWait",                           (void *)RTThreadWait },
     123    { "RTThreadWaitNoResume",                   (void *)RTThreadWaitNoResume },
     124    { "RTThreadGetName",                        (void *)RTThreadGetName },
     125    { "RTThreadSelfName",                       (void *)RTThreadSelfName },
     126    { "RTThreadGetType",                        (void *)RTThreadGetType },
     127    { "RTThreadUserSignal",                     (void *)RTThreadUserSignal },
     128    { "RTThreadUserReset",                      (void *)RTThreadUserReset },
     129    { "RTThreadUserWait",                       (void *)RTThreadUserWait },
     130    { "RTThreadUserWaitNoResume",               (void *)RTThreadUserWaitNoResume },
     131#endif
    118132    { "RTLogDefaultInstance",                   (void *)RTLogDefaultInstance },
    119133    { "RTLogRelDefaultInstance",                (void *)RTLogRelDefaultInstance },
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r397 r403  
    284284
    285285    memset(&g_DevExt, 0, sizeof(g_DevExt));
     286    dprintf(("VBoxSupDrvStop - done\n"));
    286287    return KMOD_RETURN_SUCCESS;
    287288}
  • trunk/src/VBox/Runtime/Makefile

    r391 r403  
    532532        strformatrt.cpp \
    533533        strtonum.cpp \
     534        strprintf.cpp \
    534535        VBox/strformat-vbox.cpp \
    535536        r0drv/alloc-r0drv.cpp \
     
    539540        generic/RTLogWriteUser-generic.cpp \
    540541        VBox/log-vbox.cpp \
     542        table/avlpv.cpp \
    541543        crc32.cpp \
    542544        crc64.cpp
     
    570572        string/memchr.asm \
    571573        r0drv/memobj-r0drv.cpp \
    572         r0drv/thread-r0drv.cpp \
    573574        r0drv/darwin/alloc-r0drv-darwin.cpp \
    574575        r0drv/darwin/memobj-r0drv-darwin.cpp \
     
    579580        r0drv/darwin/spinlock-r0drv-darwin.cpp \
    580581        r0drv/darwin/thread-r0drv-darwin.cpp \
     582        r0drv/darwin/thread2-r0drv-darwin.cpp \
    581583        r0drv/darwin/time-r0drv-darwin.cpp \
     584        thread.cpp \
    582585        generic/timer-generic.cpp \
    583586
  • trunk/src/VBox/Runtime/generic/sched-generic.cpp

    r1 r403  
    4141int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
    4242{
    43     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     43    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    4444    return VINF_SUCCESS;
    4545}
     
    7676int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
    7777{
    78     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     78    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    7979    return VINF_SUCCESS;
    8080}
  • trunk/src/VBox/Runtime/generic/semsrw-generic.cpp

    r1 r403  
    101101
    102102
    103 RTR3DECL(int)   RTSemRWCreate(PRTSEMRW pRWSem)
     103RTDECL(int)   RTSemRWCreate(PRTSEMRW pRWSem)
    104104{
    105105    int rc;
     
    160160
    161161
    162 RTR3DECL(int)   RTSemRWDestroy(RTSEMRW RWSem)
     162RTDECL(int)   RTSemRWDestroy(RTSEMRW RWSem)
    163163{
    164164    /*
     
    235235
    236236
    237 RTR3DECL(int)   RTSemRWRequestRead(RTSEMRW RWSem, unsigned cMillies)
     237RTDECL(int)   RTSemRWRequestRead(RTSEMRW RWSem, unsigned cMillies)
    238238{
    239239    /*
     
    366366
    367367
    368 RTR3DECL(int)   RTSemRWRequestReadNoResume(RTSEMRW RWSem, unsigned cMillies)
     368RTDECL(int)   RTSemRWRequestReadNoResume(RTSEMRW RWSem, unsigned cMillies)
    369369{
    370370    return RTSemRWRequestRead(RWSem, cMillies);
     
    372372
    373373
    374 RTR3DECL(int)   RTSemRWReleaseRead(RTSEMRW RWSem)
     374RTDECL(int)   RTSemRWReleaseRead(RTSEMRW RWSem)
    375375{
    376376    /*
     
    438438
    439439
    440 RTR3DECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies)
     440RTDECL(int) RTSemRWRequestWrite(RTSEMRW RWSem, unsigned cMillies)
    441441{
    442442    /*
     
    582582
    583583
    584 RTR3DECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies)
     584RTDECL(int) RTSemRWRequestWriteNoResume(RTSEMRW RWSem, unsigned cMillies)
    585585{
    586586    return RTSemRWRequestWrite(RWSem, cMillies);
     
    589589
    590590
    591 RTR3DECL(int)   RTSemRWReleaseWrite(RTSEMRW RWSem)
     591RTDECL(int)   RTSemRWReleaseWrite(RTSEMRW RWSem)
    592592{
    593593    /*
  • trunk/src/VBox/Runtime/generic/timer-generic.cpp

    r198 r403  
    3232#include <iprt/time.h>
    3333#include <iprt/log.h>
     34
    3435
    3536
     
    153154     * If it's suspended we can safely set the destroy flag and signal it.
    154155     */
    155 #ifdef IN_RING3
    156156    RTTHREAD Thread = pTimer->Thread;
    157 #endif
    158157    if (!pTimer->fSuspended)
    159158    {
     
    170169    }
    171170
    172 #ifdef IN_RING3
    173171    RTThreadWait(Thread, 250, NULL);
    174 #endif
    175172    return VINF_SUCCESS;
    176173}
     
    189186    u64First += RTTimeNanoTS();
    190187    ASMAtomicXchgU64(&pTimer->iTick, 0);
    191     ASMAtomicXchgU64(&pTimer->iTick, u64First);
    192188    ASMAtomicXchgU64(&pTimer->u64StartTS, u64First);
     189    ASMAtomicXchgU64(&pTimer->u64NextTS, u64First);
    193190    ASMAtomicXchgU8(&pTimer->fSuspended, false);
    194191    int rc = RTSemEventSignal(pTimer->Event);
     
    216213    AssertRC(rc);
    217214    return rc;
    218 
    219215}
    220216
  • trunk/src/VBox/Runtime/include/internal/thread.h

    r197 r403  
    2525#include <iprt/types.h>
    2626#include <iprt/thread.h>
     27#include <iprt/avl.h>
    2728#ifdef IN_RING3
    2829# include <iprt/process.h>
    2930# include <iprt/critsect.h>
    30 # include <iprt/avl.h>
    3131#endif
    3232
    3333__BEGIN_DECLS
    3434
    35 
    36 #ifdef IN_RING3
    3735
    3836
     
    8987    /** The current thread state. */
    9088    RTTHREADSTATE volatile  enmState;
    91 #ifdef __WIN__
     89#if defined(__WIN__) && defined(IN_RING3)
    9290    /** The thread handle.
    9391     * This is not valid until the create function has returned! */
     
    112110    /** Actual stack size. */
    113111    size_t                  cbStack;
     112#ifdef IN_RING3
    114113    /** What we're blocking on. */
    115114    union RTTHREADINTBLOCKID
     
    127126    /** Where we're blocking. */
    128127    RTUINTPTR volatile      uBlockId;
     128#endif /* IN_RING3 */
    129129    /** Thread name. */
    130130    char                    szName[RTTHREAD_NAME_LEN];
     
    154154 * Initialize the native part of the thread management.
    155155 *
    156  * Generally a TLS entry will be allocated at this point.
     156 * Generally a TLS entry will be allocated at this point (Ring-3).
    157157 *
    158158 * @returns iprt status code.
    159159 */
    160160int rtThreadNativeInit(void);
     161
     162/**
     163 * Create a native thread.
     164 * This creates the thread as described in pThreadInt and stores the thread id in *pThread.
     165 *
     166 * @returns iprt status code.
     167 * @param   pThreadInt      The thread data structure for the thread.
     168 * @param   pNativeThread   Where to store the native thread identifier.
     169 */
     170int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
     171
     172/**
     173 * Adopts a thread, this is called immediately after allocating the
     174 * thread structure.
     175 *
     176 * @param   pThread     Pointer to the thread structure.
     177 */
     178int rtThreadNativeAdopt(PRTTHREADINT pThread);
    161179
    162180/**
     
    174192int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType);
    175193
    176 /**
    177  * Create a native thread.
    178  * This creates the thread as described in pThreadInt and stores the thread id in *pThread.
    179  *
    180  * @returns iprt status code.
    181  * @param   pThreadInt      The thread data structure for the thread.
    182  * @param   pNativeThread   Where to store the native thread identifier.
    183  */
    184 int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread);
    185 
    186 /**
    187  * Adopts a thread, this is called immediately after allocating the
    188  * thread structure.
    189  *
    190  * @param   pThread     Pointer to the thread structure.
    191  */
    192 int rtThreadNativeAdopt(PRTTHREADINT pThread);
    193 
    194 #ifdef __WIN__
     194#ifdef IN_RING3
     195# ifdef __WIN__
    195196/**
    196197 * Callback for when a native thread is detaching.
     
    200201 */
    201202void rtThreadNativeDetach(void);
    202 #endif
    203 
    204 int rtThreadInit(void);
     203# endif
     204#endif /* !IN_RING0 */
     205
     206
     207/* thread.cpp */
    205208int rtThreadMain(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
    206 void rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
    207 PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread);
    208 PRTTHREADINT rtThreadGet(RTTHREAD Thread);
    209 uint32_t rtThreadRelease(PRTTHREADINT pThread);
    210 int rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
    211 void rtThreadTerminate(PRTTHREADINT pThread, int rc);
    212209void rtThreadBlocking(PRTTHREADINT pThread, RTTHREADSTATE enmState, uint64_t u64Block,
    213210                      const char *pszFile, unsigned uLine, RTUINTPTR uId);
    214211void rtThreadUnblocked(PRTTHREADINT pThread, RTTHREADSTATE enmCurState);
    215 
    216 
    217 #elif defined(IN_RING0)
    218 
    219 /**
    220  * Argument package for a ring-0 thread.
    221  */
    222 typedef struct RTR0THREADARGS
    223 {
    224     /** The thread function. */
    225     PFNRTTHREAD     pfnThread;
    226     /** The thread function argument. */
    227     void           *pvUser;
    228     /** The thread type. */
    229     RTTHREADTYPE    enmType;
    230 } RTR0THREADARGS, *PRTR0THREADARGS;
    231 
    232 
    233 
    234 int rtThreadMain(PRTR0THREADARGS pArgs, RTNATIVETHREAD NativeThread);
    235 
    236 /**
    237  * Do the actual thread creation.
    238  *
    239  * @returns IPRT status code.
    240  *          On failure, no thread has been created.
    241  * @param   pArgs           The argument package.
    242  * @param   pNativeThread   Where to return the native thread handle.
    243  */
    244 int rtThreadNativeCreate(PRTR0THREADARGS pArgs, PRTNATIVETHREAD pNativeThread);
    245 
    246 /**
    247  * Do the actual thread priority change.
    248  *
    249  * @returns IPRT status code.
    250  * @param   Thread      The thread which priority should be changed.
    251  *                      This is currently restricted to the current thread.
    252  * @param   enmType     The new thread priority type (valid).
    253  */
    254 int rtThreadNativeSetPriority(RTTHREAD Thread, RTTHREADTYPE enmType);
    255 
     212uint32_t rtThreadRelease(PRTTHREADINT pThread);
     213void rtThreadTerminate(PRTTHREADINT pThread, int rc);
     214PRTTHREADINT rtThreadGetByNative(RTNATIVETHREAD NativeThread);
     215PRTTHREADINT rtThreadGet(RTTHREAD Thread);
     216int rtThreadInit(void);
     217void rtThreadTerm(void);
     218void rtThreadInsert(PRTTHREADINT pThread, RTNATIVETHREAD NativeThread);
     219#ifdef IN_RING3
     220int rtThreadDoSetProcPriority(RTPROCPRIORITY enmPriority);
    256221#endif /* !IN_RING0 */
    257222
  • trunk/src/VBox/Runtime/r0drv/darwin/semaphore-r0drv-darwin.cpp

    r205 r403  
    5656#define RTSEMEVENT_MAGIC 0x19601110
    5757
     58
     59/**
     60 * Darwin multiple release event semaphore.
     61 */
     62typedef struct RTSEMEVENTMULTIINTERNAL
     63{
     64    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
     65    uint32_t volatile   u32Magic;
     66    /** The number of waiting threads. */
     67    uint32_t volatile   cWaiters;
     68    /** Set if the event object is signaled. */
     69    uint8_t volatile    fSignaled;
     70    /** The number of threads in the process of waking up. */
     71    uint32_t volatile   cWaking;
     72    /** The spinlock protecting us. */
     73    lck_spin_t         *pSpinlock;
     74} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
     75
     76/** Magic for the Darwin multiple release event semaphore structure. (Isaac Asimov) */
     77#define RTSEMEVENTMULTI_MAGIC 0x19200102
     78
     79
    5880#if 0 /** @todo */
    5981/**
     
    187209        Assert(!pEventInt->cWaiters);
    188210        ASMAtomicXchgU8(&pEventInt->fSignaled, false);
    189         rc = 0;
     211        rc = VINF_SUCCESS;
    190212    }
    191213    else
     
    270292    return rtSemEventWait(EventSem, cMillies, TRUE /* interruptable */);
    271293}
     294
     295
     296
     297RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
     298{
     299    Assert(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *));
     300    AssertPtrReturn(pEventMultiSem, VERR_INVALID_POINTER);
     301
     302    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pEventMultiInt));
     303    if (pEventMultiInt)
     304    {
     305        pEventMultiInt->u32Magic = RTSEMEVENTMULTI_MAGIC;
     306        pEventMultiInt->cWaiters = 0;
     307        pEventMultiInt->cWaking = 0;
     308        pEventMultiInt->fSignaled = 0;
     309        Assert(g_pDarwinLockGroup);
     310        pEventMultiInt->pSpinlock = lck_spin_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL);
     311        if (pEventMultiInt->pSpinlock)
     312        {
     313            *pEventMultiSem = pEventMultiInt;
     314            return VINF_SUCCESS;
     315        }
     316
     317        pEventMultiInt->u32Magic = 0;
     318        RTMemFree(pEventMultiInt);
     319    }
     320    return VERR_NO_MEMORY;
     321}
     322
     323
     324RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
     325{
     326    if (EventMultiSem == NIL_RTSEMEVENTMULTI)     /* don't bitch */
     327        return VERR_INVALID_HANDLE;
     328    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     329    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
     330    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
     331                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     332                    VERR_INVALID_HANDLE);
     333
     334    lck_spin_lock(pEventMultiInt->pSpinlock);
     335    ASMAtomicIncU32(&pEventMultiInt->u32Magic); /* make the handle invalid */
     336    if (pEventMultiInt->cWaiters > 0)
     337    {
     338        /* abort waiting thread, last man cleans up. */
     339        ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);
     340        thread_wakeup_prim((event_t)pEventMultiInt, FALSE /* all threads */, THREAD_RESTART);
     341        lck_spin_unlock(pEventMultiInt->pSpinlock);
     342    }
     343    else if (pEventMultiInt->cWaking)
     344        /* the last waking thread is gonna do the cleanup */
     345        lck_spin_unlock(pEventMultiInt->pSpinlock);
     346    else
     347    {
     348        lck_spin_unlock(pEventMultiInt->pSpinlock);
     349        lck_spin_destroy(pEventMultiInt->pSpinlock, g_pDarwinLockGroup);
     350        RTMemFree(pEventMultiInt);
     351    }
     352
     353    return VINF_SUCCESS;
     354}
     355
     356
     357RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
     358{
     359    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     360    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
     361    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
     362                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     363                    VERR_INVALID_HANDLE);
     364
     365    lck_spin_lock(pEventMultiInt->pSpinlock);
     366
     367    ASMAtomicXchgU8(&pEventMultiInt->fSignaled, true);
     368    if (pEventMultiInt->cWaiters > 0)
     369    {
     370        ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);
     371        ASMAtomicXchgU32(&pEventMultiInt->cWaiters, 0);
     372        thread_wakeup_prim((event_t)pEventMultiInt, FALSE /* all threads */, THREAD_AWAKENED);
     373    }
     374
     375    lck_spin_unlock(pEventMultiInt->pSpinlock);
     376    return VINF_SUCCESS;
     377}
     378
     379
     380RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
     381{
     382    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     383    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
     384    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
     385                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     386                    VERR_INVALID_HANDLE);
     387
     388    lck_spin_lock(pEventMultiInt->pSpinlock);
     389    ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false);
     390    lck_spin_unlock(pEventMultiInt->pSpinlock);
     391    return VINF_SUCCESS;
     392}
     393
     394
     395static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, wait_interrupt_t fInterruptible)
     396{
     397    PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     398    AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
     399    AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
     400                    ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     401                    VERR_INVALID_HANDLE);
     402
     403    lck_spin_lock(pEventMultiInt->pSpinlock);
     404
     405    int rc;
     406    if (pEventMultiInt->fSignaled)
     407    {
     408        ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false);
     409        rc = VINF_SUCCESS;
     410    }
     411    else
     412    {
     413        ASMAtomicIncU32(&pEventMultiInt->cWaiters);
     414
     415        wait_result_t rcWait;
     416        if (cMillies == RT_INDEFINITE_WAIT)
     417            rcWait = lck_spin_sleep(pEventMultiInt->pSpinlock, LCK_SLEEP_DEFAULT, (event_t)pEventMultiInt, fInterruptible);
     418        else
     419        {
     420            uint64_t u64AbsTime;
     421            nanoseconds_to_absolutetime(cMillies * UINT64_C(1000000), &u64AbsTime);
     422            u64AbsTime += mach_absolute_time();
     423
     424            rcWait = lck_spin_sleep_deadline(pEventMultiInt->pSpinlock, LCK_SLEEP_DEFAULT,
     425                                             (event_t)pEventMultiInt, fInterruptible, u64AbsTime);
     426        }
     427        switch (rcWait)
     428        {
     429            case THREAD_AWAKENED:
     430                Assert(pEventMultiInt->cWaking > 0);
     431                if (    !ASMAtomicDecU32(&pEventMultiInt->cWaking)
     432                    &&  pEventMultiInt->u32Magic != RTSEMEVENTMULTI_MAGIC)
     433                {
     434                    /* the event was destroyed after we woke up, as the last thread do the cleanup. */
     435                    lck_spin_unlock(pEventMultiInt->pSpinlock);
     436                    Assert(g_pDarwinLockGroup);
     437                    lck_spin_destroy(pEventMultiInt->pSpinlock, g_pDarwinLockGroup);
     438                    RTMemFree(pEventMultiInt);
     439                    return VINF_SUCCESS;
     440                }
     441                rc = VINF_SUCCESS;
     442                break;
     443
     444            case THREAD_TIMED_OUT:
     445                Assert(cMillies != RT_INDEFINITE_WAIT);
     446                ASMAtomicDecU32(&pEventMultiInt->cWaiters);
     447                rc = VERR_TIMEOUT;
     448                break;
     449
     450            case THREAD_INTERRUPTED:
     451                Assert(fInterruptible);
     452                ASMAtomicDecU32(&pEventMultiInt->cWaiters);
     453                rc = VERR_INTERRUPTED;
     454                break;
     455
     456            case THREAD_RESTART:
     457                /* Last one out does the cleanup. */
     458                if (!ASMAtomicDecU32(&pEventMultiInt->cWaking))
     459                {
     460                    lck_spin_unlock(pEventMultiInt->pSpinlock);
     461                    Assert(g_pDarwinLockGroup);
     462                    lck_spin_destroy(pEventMultiInt->pSpinlock, g_pDarwinLockGroup);
     463                    RTMemFree(pEventMultiInt);
     464                    return VERR_SEM_DESTROYED;
     465                }
     466
     467                rc = VERR_SEM_DESTROYED;
     468                break;
     469
     470            default:
     471                AssertMsgFailed(("rcWait=%d\n", rcWait));
     472                rc = VERR_GENERAL_FAILURE;
     473                break;
     474        }
     475    }
     476
     477    lck_spin_unlock(pEventMultiInt->pSpinlock);
     478    return rc;
     479}
     480
     481
     482RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
     483{
     484    return rtSemEventMultiWait(EventMultiSem, cMillies, FALSE /* not interruptable */);
     485}
     486
     487
     488RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
     489{
     490    return rtSemEventMultiWait(EventMultiSem, cMillies, TRUE /* interruptable */);
     491}
     492
    272493
    273494
  • trunk/src/VBox/Runtime/r0drv/darwin/thread-r0drv-darwin.cpp

    r197 r403  
    2626#include <iprt/thread.h>
    2727#include <iprt/err.h>
    28 #include <iprt/assert.h>
    29 #include "internal/thread.h"
    3028
    3129
    32 RTDECL(RTTHREAD) RTThreadSelf(void)
     30
     31RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
    3332{
    34     return (RTTHREAD)current_thread();
     33    return (RTNATIVETHREAD)current_thread();
    3534}
    3635
    3736
    38 RTDECL(int)   RTThreadSleep(unsigned cMillies)
     37RTDECL(int) RTThreadSleep(unsigned cMillies)
    3938{
    4039    uint64_t u64Deadline;
     
    5150}
    5251
    53 
    54 int rtThreadNativeSetPriority(RTTHREAD Thread, RTTHREADTYPE enmType)
    55 {
    56     /*
    57      * Convert the priority type to scheduling policies.
    58      */
    59     bool                            fSetExtended = false;
    60     thread_extended_policy          Extended = { true };
    61     bool                            fSetTimeContstraint = false;
    62     thread_time_constraint_policy   TimeConstraint = { 0, 0, 0, true };
    63     thread_precedence_policy        Precedence = { 0 };
    64     switch (enmType)
    65     {
    66         case RTTHREADTYPE_INFREQUENT_POLLER:
    67             Precedence.importance = 1;
    68             break;
    69 
    70         case RTTHREADTYPE_EMULATION:
    71             Precedence.importance = 30;
    72             break;
    73 
    74         case RTTHREADTYPE_DEFAULT:
    75             Precedence.importance = 31;
    76             break;
    77 
    78         case RTTHREADTYPE_MSG_PUMP:
    79             Precedence.importance = 34;
    80             break;
    81 
    82         case RTTHREADTYPE_IO:
    83             Precedence.importance = 98;
    84             break;
    85 
    86         case RTTHREADTYPE_TIMER:
    87             Precedence.importance = 0x7fffffff;
    88 
    89             fSetExtended = true;
    90             Extended.timeshare = FALSE;
    91 
    92             fSetTimeContstraint = true;
    93             TimeConstraint.period = 0; /* not really true for a real timer thread, but we've really no idea. */
    94             TimeConstraint.computation = rtDarwinAbsTimeFromNano(100000); /* 100 us*/
    95             TimeConstraint.constraint = rtDarwinAbsTimeFromNano(500000);  /* 500 us */
    96             TimeConstraint.preemptible = FALSE;
    97             break;
    98 
    99         default:
    100             AssertMsgFailed(("enmType=%d\n", enmType));
    101             return VERR_INVALID_PARAMETER;
    102     }
    103 
    104     /*
    105      * Do the actual modification.
    106      */
    107     kern_return_t rc = thread_policy_set((thread_t)Thread, THREAD_PRECEDENCE_POLICY,
    108                                          (thread_policy_t)&Precedence, THREAD_PRECEDENCE_POLICY_COUNT);
    109     AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc)); NOREF(rc);
    110 
    111     if (fSetExtended)
    112     {
    113         rc = thread_policy_set((thread_t)Thread, THREAD_EXTENDED_POLICY,
    114                                (thread_policy_t)&Extended, THREAD_EXTENDED_POLICY_COUNT);
    115         AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc));
    116     }
    117 
    118     if (fSetTimeContstraint)
    119     {
    120         rc = thread_policy_set((thread_t)Thread, THREAD_TIME_CONSTRAINT_POLICY,
    121                                (thread_policy_t)&TimeConstraint, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
    122         AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc));
    123     }
    124 
    125     return VINF_SUCCESS; /* ignore any errors for now */
    126 }
    127 
    128 
    129 /**
    130  * Native kernel thread wrapper function.
    131  *
    132  * This will forward to rtThreadMain and do termination upon return.
    133  *
    134  * @param pvArg         Pointer to the argument package.
    135  * @param Ignored       Wait result, which we ignore.
    136  */
    137 static void rtThreadNativeMain(void *pvArg, wait_result_t Ignored)
    138 {
    139     const thread_t Self = current_thread();
    140 
    141     rtThreadMain((PRTR0THREADARGS)pvArg, (RTNATIVETHREAD)Self);
    142 
    143     kern_return_t rc = thread_terminate(Self);
    144     AssertFatalMsgFailed(("rc=%d\n", rc));
    145 }
    146 
    147 
    148 int rtThreadNativeCreate(PRTR0THREADARGS pArgs, PRTNATIVETHREAD pNativeThread)
    149 {
    150     thread_t NativeThread;
    151     kern_return_t rc = kernel_thread_start(rtThreadNativeMain, pArgs, &NativeThread);
    152     if (rc == KERN_SUCCESS)
    153     {
    154         *pNativeThread = (RTNATIVETHREAD)NativeThread;
    155         thread_deallocate(NativeThread);
    156         return VINF_SUCCESS;
    157     }
    158     return RTErrConvertFromMachKernReturn(rc);
    159 }
    160 
  • trunk/src/VBox/Runtime/r0drv/darwin/thread2-r0drv-darwin.cpp

    r375 r403  
    11/* $Id$ */
    22/** @file
    3  * InnoTek Portable Runtime - Threads, Ring-0 Driver, Darwin.
     3 * InnoTek Portable Runtime - Threads (Part 2), Ring-0 Driver, Darwin.
    44 */
    55
     
    3030
    3131
    32 RTDECL(RTTHREAD) RTThreadSelf(void)
     32int rtThreadNativeInit(void)
    3333{
    34     return (RTTHREAD)current_thread();
    35 }
    36 
    37 
    38 RTDECL(int)   RTThreadSleep(unsigned cMillies)
    39 {
    40     uint64_t u64Deadline;
    41     clock_interval_to_deadline(cMillies, kMillisecondScale, &u64Deadline);
    42     clock_delay_until(u64Deadline);
     34    /* No TLS in Ring-0. :-/ */
    4335    return VINF_SUCCESS;
    4436}
    4537
    4638
    47 RTDECL(bool) RTThreadYield(void)
     39RTDECL(RTTHREAD) RTThreadSelf(void)
    4840{
    49     thread_block(THREAD_CONTINUE_NULL);
    50     return true; /* this is fishy */
     41    return rtThreadGetByNative((RTNATIVETHREAD)current_thread());
    5142}
    5243
    5344
    54 int rtThreadNativeSetPriority(RTTHREAD Thread, RTTHREADTYPE enmType)
     45int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
    5546{
    5647    /*
    5748     * Convert the priority type to scheduling policies.
     49     * (This is really just guess work.)
    5850     */
    5951    bool                            fSetExtended = false;
     
    10597     * Do the actual modification.
    10698     */
    107     kern_return_t rc = thread_policy_set((thread_t)Thread, THREAD_PRECEDENCE_POLICY,
     99    kern_return_t kr = thread_policy_set((thread_t)pThread->Core.Key, THREAD_PRECEDENCE_POLICY,
    108100                                         (thread_policy_t)&Precedence, THREAD_PRECEDENCE_POLICY_COUNT);
    109     AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc)); NOREF(rc);
     101    AssertMsg(kr == KERN_SUCCESS, ("%rc\n", kr)); NOREF(kr);
    110102
    111103    if (fSetExtended)
    112104    {
    113         rc = thread_policy_set((thread_t)Thread, THREAD_EXTENDED_POLICY,
     105        kr = thread_policy_set((thread_t)pThread->Core.Key, THREAD_EXTENDED_POLICY,
    114106                               (thread_policy_t)&Extended, THREAD_EXTENDED_POLICY_COUNT);
    115         AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc));
     107        AssertMsg(kr == KERN_SUCCESS, ("%rc\n", kr));
    116108    }
    117109
    118110    if (fSetTimeContstraint)
    119111    {
    120         rc = thread_policy_set((thread_t)Thread, THREAD_TIME_CONSTRAINT_POLICY,
     112        kr = thread_policy_set((thread_t)pThread->Core.Key, THREAD_TIME_CONSTRAINT_POLICY,
    121113                               (thread_policy_t)&TimeConstraint, THREAD_TIME_CONSTRAINT_POLICY_COUNT);
    122         AssertMsg(rc == KERN_SUCCESS, ("%rc\n", rc));
     114        AssertMsg(kr == KERN_SUCCESS, ("%rc\n", kr));
    123115    }
    124116
    125117    return VINF_SUCCESS; /* ignore any errors for now */
     118}
     119
     120
     121int rtThreadNativeAdopt(PRTTHREADINT pThread)
     122{
     123    return VERR_NOT_IMPLEMENTED;
    126124}
    127125
     
    139137    const thread_t Self = current_thread();
    140138
    141     rtThreadMain((PRTR0THREADARGS)pvArg, (RTNATIVETHREAD)Self);
     139    rtThreadMain((PRTTHREADINT)pvArg, (RTNATIVETHREAD)Self);
    142140
    143     kern_return_t rc = thread_terminate(Self);
    144     AssertFatalMsgFailed(("rc=%d\n", rc));
     141    kern_return_t kr = thread_terminate(Self);
     142    AssertFatalMsgFailed(("kr=%d\n", kr));
    145143}
    146144
    147145
    148 int rtThreadNativeCreate(PRTR0THREADARGS pArgs, PRTNATIVETHREAD pNativeThread)
     146int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
    149147{
    150148    thread_t NativeThread;
    151     kern_return_t rc = kernel_thread_start(rtThreadNativeMain, pArgs, &NativeThread);
    152     if (rc == KERN_SUCCESS)
     149    kern_return_t kr = kernel_thread_start(rtThreadNativeMain, pThreadInt, &NativeThread);
     150    if (kr == KERN_SUCCESS)
    153151    {
    154152        *pNativeThread = (RTNATIVETHREAD)NativeThread;
     
    156154        return VINF_SUCCESS;
    157155    }
    158     return RTErrConvertFromMachKernReturn(rc);
     156    return RTErrConvertFromMachKernReturn(kr);
    159157}
    160158
  • trunk/src/VBox/Runtime/r0drv/initterm-r0drv.cpp

    r207 r403  
    2626#include <iprt/initterm.h>
    2727#include <iprt/assert.h>
     28#include <iprt/err.h>
     29
    2830#include "internal/initterm.h"
     31#include "internal/thread.h"
    2932
    3033
     
    3740RTR0DECL(int) RTR0Init(unsigned fReserved)
    3841{
     42    int rc;
    3943    Assert(fReserved == 0);
    40     return rtR0InitNative();
     44    rc = rtR0InitNative();
     45    if (RT_SUCCESS(rc))
     46    {
     47#if !defined(__LINUX__) && !defined(__WIN__)
     48        rc = rtThreadInit();
     49#endif
     50        if (RT_SUCCESS(rc))
     51            return rc;
     52
     53        rtR0TermNative();
     54    }
     55    return rc;
    4156}
    4257
     
    4762RTR0DECL(void) RTR0Term(void)
    4863{
    49     return rtR0TermNative();
     64#if !defined(__LINUX__) && !defined(__WIN__)
     65    rtThreadTerm();
     66#endif
     67    rtR0TermNative();
    5068}
    5169
  • trunk/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c

    r1 r403  
    2929
    3030
    31 RTDECL(RTTHREAD) RTThreadSelf(void)
     31RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
    3232{
    33     return (RTTHREAD)current;
     33    return (RTNATIVETHREAD)current;
    3434}
    3535
  • trunk/src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c

    r375 r403  
    11/* $Id$ */
    22/** @file
    3  * InnoTek Portable Runtime - Threads, Ring-0 Driver, Linux.
     3 * InnoTek Portable Runtime - Threads (Part 2), Ring-0 Driver, Linux.
    44 */
    55
     
    2727#include <iprt/thread.h>
    2828#include <iprt/err.h>
     29#include "internal/thread.h"
    2930
    3031
    3132RTDECL(RTTHREAD) RTThreadSelf(void)
    3233{
    33     return (RTTHREAD)current;
     34    return rtThreadGetByNative(((RTNATIVETHREAD)current);
    3435}
    3536
    36 
    37 RTDECL(int)   RTThreadSleep(unsigned cMillies)
    38 {
    39     long cJiffies = msecs_to_jiffies(cMillies);
    40     set_current_state(TASK_INTERRUPTIBLE);
    41     cJiffies = schedule_timeout(cJiffies);
    42     if (!cJiffies)
    43         return VINF_SUCCESS;
    44     return VERR_INTERRUPTED;
    45 }
    46 
    47 
    48 RTDECL(bool) RTThreadYield(void)
    49 {
    50 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20)
    51     yield();
    52 #else
    53     set_current_state(TASK_RUNNING);
    54     sys_sched_yield();
    55     schedule();
    56 #endif
    57     return true;
    58 }
    59 
  • trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp

    r1 r403  
    3333
    3434
    35 RTDECL(RTTHREAD) RTThreadSelf(void)
     35RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
    3636{
    37     return (RTTHREAD)PsGetCurrentThread();
     37    return (RTNATIVETHREAD)PsGetCurrentThread();
    3838}
    3939
     
    6262}
    6363
     64
  • trunk/src/VBox/Runtime/r0drv/nt/thread2-r0drv-nt.cpp

    r375 r403  
    11/* $Id$ */
    22/** @file
    3  * InnoTek Portable Runtime - Threads, Ring-0 Driver, NT.
     3 * InnoTek Portable Runtime - Threads (Part 2), Ring-0 Driver, NT.
    44 */
    55
     
    2828#include <iprt/err.h>
    2929
    30 __BEGIN_DECLS
    31 NTSTATUS NTAPI ZwYieldExecution(void);
    32 __END_DECLS
     30#include "internal/thread.h"
    3331
    3432
    3533RTDECL(RTTHREAD) RTThreadSelf(void)
    3634{
    37     return (RTTHREAD)PsGetCurrentThread();
     35    return rtThreadGetByNative((RTNATIVETHREAD)PsGetCurrentThread());
    3836}
    3937
    40 
    41 RTDECL(int)   RTThreadSleep(unsigned cMillies)
    42 {
    43     LARGE_INTEGER Interval;
    44     Interval.QuadPart = -(int64_t)cMillies * 10000;
    45     NTSTATUS rcNt = KeDelayExecutionThread(KernelMode, TRUE, &Interval);
    46     switch (rcNt)
    47     {
    48         case STATUS_SUCCESS:
    49             return VINF_SUCCESS;
    50         case STATUS_ALERTED:
    51         case STATUS_USER_APC:
    52             return VERR_INTERRUPTED;
    53         default:
    54             return RTErrConvertFromNtStatus(rcNt);
    55     }
    56 }
    57 
    58 
    59 RTDECL(bool) RTThreadYield(void)
    60 {
    61     return ZwYieldExecution() != STATUS_NO_YIELD_PERFORMED;
    62 }
    63 
  • trunk/src/VBox/Runtime/r3/linux/sched-linux.cpp

    r1 r403  
    124124 * to only be lowering the priority.
    125125 */
    126 static const PROCPRIORITYTYPE g_aTypesLinuxFree[RTTHREADTYPE_LAST] =
     126static const PROCPRIORITYTYPE g_aTypesLinuxFree[RTTHREADTYPE_END] =
    127127{
    128128    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    143143 * Deltas for a process in which we are restricted and can only lower the priority.
    144144 */
    145 static const PROCPRIORITYTYPE g_aTypesLinuxRestricted[RTTHREADTYPE_LAST] =
     145static const PROCPRIORITYTYPE g_aTypesLinuxRestricted[RTTHREADTYPE_END] =
    146146{
    147147    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    165165 * to the process default of a thread created by a low priority thread.
    166166 */
    167 static const PROCPRIORITYTYPE g_aTypesLinuxFlat[RTTHREADTYPE_LAST] =
     167static const PROCPRIORITYTYPE g_aTypesLinuxFlat[RTTHREADTYPE_END] =
    168168{
    169169    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    465465int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
    466466{
    467     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     467    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    468468
    469469    /*
     
    518518     */
    519519    int rc = VINF_SUCCESS;
    520     int i = RTTHREADTYPE_LAST;
     520    int i = RTTHREADTYPE_END;
    521521    while (--i > RTTHREADTYPE_INVALID)
    522522    {
     
    598598{
    599599    /* sanity */
    600     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     600    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    601601    Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
    602602    Assert((pthread_t)pThread->Core.Key == pthread_self());
  • trunk/src/VBox/Runtime/r3/posix/sched-posix.cpp

    r1 r403  
    122122 * certain).
    123123 */
    124 static const PROCPRIORITYTYPE g_aTypesThread[RTTHREADTYPE_LAST] =
     124static const PROCPRIORITYTYPE g_aTypesThread[RTTHREADTYPE_END] =
    125125{
    126126    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    138138};
    139139
    140 static const PROCPRIORITYTYPE g_aTypesThreadFlat[RTTHREADTYPE_LAST] =
     140static const PROCPRIORITYTYPE g_aTypesThreadFlat[RTTHREADTYPE_END] =
    141141{
    142142    { RTTHREADTYPE_INVALID,                 ~0 },
     
    184184 * to only be lowering the priority.
    185185 */
    186 static const PROCPRIORITYTYPE g_aTypesUnixFree[RTTHREADTYPE_LAST] =
     186static const PROCPRIORITYTYPE g_aTypesUnixFree[RTTHREADTYPE_END] =
    187187{
    188188    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    204204 * to only be lowering the priority.
    205205 */
    206 static const PROCPRIORITYTYPE g_aTypesUnixRestricted[RTTHREADTYPE_LAST] =
     206static const PROCPRIORITYTYPE g_aTypesUnixRestricted[RTTHREADTYPE_END] =
    207207{
    208208    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    224224 * to only be lowering the priority.
    225225 */
    226 static const PROCPRIORITYTYPE g_aTypesUnixFlat[RTTHREADTYPE_LAST] =
     226static const PROCPRIORITYTYPE g_aTypesUnixFlat[RTTHREADTYPE_END] =
    227227{
    228228    { RTTHREADTYPE_INVALID,                 -999999999 },
     
    506506int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
    507507{
    508     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     508    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    509509
    510510    /*
     
    584584                int iMin = sched_get_priority_min(SavedPriority.iPolicy);
    585585                pthread_t Self = pthread_self();
    586                 for (int i = RTTHREADTYPE_INVALID + 1; i < RTTHREADTYPE_LAST; i++)
     586                for (int i = RTTHREADTYPE_INVALID + 1; i < RTTHREADTYPE_END; i++)
    587587                {
    588588                    struct sched_param SchedParam = SavedPriority.PthreadSchedParam;
     
    607607        case OSPRIOSUP_THREAD_LEVEL:
    608608        {
    609             int i = RTTHREADTYPE_LAST;
     609            int i = RTTHREADTYPE_END;
    610610            while (--i > RTTHREADTYPE_INVALID)
    611611            {
     
    737737int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
    738738{
    739     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     739    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    740740    Assert(enmType == g_pProcessPriority->paTypes[enmType].enmType);
    741741    Assert((pthread_t)pThread->Core.Key == pthread_self());
  • trunk/src/VBox/Runtime/r3/win32/sched-win32.cpp

    r1 r403  
    6161        /** The Win32 thread priority. */
    6262        DWORD           dwThreadPriority;
    63     } aTypes[RTTHREADTYPE_LAST];
     63    } aTypes[RTTHREADTYPE_END];
    6464} PROCPRIORITY;
    6565
     
    254254int rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType)
    255255{
    256     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     256    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    257257    return VINF_SUCCESS;
    258258}
     
    303303int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
    304304{
    305     Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_LAST);
     305    Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END);
    306306    AssertMsg(g_pProcessPriority && g_pProcessPriority->aTypes[enmType].enmType == enmType,
    307307              ("enmType=%d entry=%d\n", enmType, g_pProcessPriority->aTypes[enmType].enmType));
  • trunk/src/VBox/Runtime/thread.cpp

    r1 r403  
    3232#include <iprt/assert.h>
    3333#include <iprt/semaphore.h>
     34#ifdef IN_RING0
     35# include <iprt/spinlock.h>
     36#endif
    3437#include <iprt/asm.h>
    3538#include <iprt/err.h>
     
    4346*   Defined Constants And Macros                                               *
    4447*******************************************************************************/
    45 #define RT_THREAD_LOCK_RW()     rtThreadLockRW()
    46 #define RT_THREAD_UNLOCK_RW()   rtThreadUnLockRW()
    47 #define RT_THREAD_LOCK_RD()     rtThreadLockRD()
    48 #define RT_THREAD_UNLOCK_RD()   rtThreadUnLockRD()
     48#ifdef IN_RING0
     49# define RT_THREAD_LOCK_TMP(Tmp)    RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER
     50# define RT_THREAD_LOCK_RW(Tmp)     RTSpinlockAcquireNoInts(g_ThreadSpinlock, &(Tmp))
     51# define RT_THREAD_UNLOCK_RW(Tmp)   RTSpinlockReleaseNoInts(g_ThreadSpinlock, &(Tmp))
     52# define RT_THREAD_LOCK_RD(Tmp)     RTSpinlockAcquireNoInts(g_ThreadSpinlock, &(Tmp))
     53# define RT_THREAD_UNLOCK_RD(Tmp)   RTSpinlockReleaseNoInts(g_ThreadSpinlock, &(Tmp))
     54#else
     55# define RT_THREAD_LOCK_TMP(Tmp)
     56# define RT_THREAD_LOCK_RW(Tmp)     rtThreadLockRW()
     57# define RT_THREAD_UNLOCK_RW(Tmp)   rtThreadUnLockRW()
     58# define RT_THREAD_LOCK_RD(Tmp)     rtThreadLockRD()
     59# define RT_THREAD_UNLOCK_RD(Tmp)   rtThreadUnLockRD()
     60#endif
    4961
    5062
     
    5466/** The AVL thread containing the threads. */
    5567static PAVLPVNODECORE   g_ThreadTree;
     68#ifdef IN_RING3
    5669/** The RW lock protecting the tree. */
    5770static RTSEMRW          g_ThreadRWSem = NIL_RTSEMRW;
     71#else
     72/** The spinlocks protecting the tree. */
     73static RTSPINLOCK       g_ThreadSpinlock = NIL_RTSPINLOCK;
     74#endif
    5875
    5976
     
    87104 * thread id. RTThreadSelf() then have to be implemented using a pointer stored
    88105 * in thread local storage (TLS).
    89  */
    90 
    91 
    92 /**
    93  * Initializes the thread data base.
     106 *
     107 * In Ring-0 we only try keep track of kernel threads created by RTCreateThread
     108 * at the moment. There we really only need the 'join' feature, but doing things
     109 * the same way allow us to name threads and similar stuff.
     110 */
     111
     112
     113/**
     114 * Initializes the thread database.
    94115 *
    95116 * @returns iprt status code.
     
    97118int rtThreadInit(void)
    98119{
     120#ifdef IN_RING3
    99121    int rc = VINF_ALREADY_INITIALIZED;
    100122    if (g_ThreadRWSem == NIL_RTSEMRW)
     
    108130        {
    109131            rc = rtThreadNativeInit();
     132#ifdef IN_RING3
    110133            if (RT_SUCCESS(rc))
    111134                rc = rtThreadAdopt(RTTHREADTYPE_DEFAULT, 0, "main");
    112135            if (RT_SUCCESS(rc))
    113136                rc = rtSchedNativeCalcDefaultPriority(RTTHREADTYPE_DEFAULT);
     137#endif
    114138            if (RT_SUCCESS(rc))
    115139                return VINF_SUCCESS;
     
    120144        }
    121145    }
    122     return rc;
    123 }
     146
     147#elif defined(IN_RING0)
     148
     149    /*
     150     * Create the spinlock and to native init.
     151     */
     152    Assert(g_ThreadSpinlock == NIL_RTSPINLOCK);
     153    int rc = RTSpinlockCreate(&g_ThreadSpinlock);
     154    if (RT_SUCCESS(rc))
     155    {
     156        rc = rtThreadNativeInit();
     157        if (RT_SUCCESS(rc))
     158            return VINF_SUCCESS;
     159
     160        /* failed, clear out */
     161        RTSpinlockDestroy(g_ThreadSpinlock);
     162        g_ThreadSpinlock = NIL_RTSPINLOCK;
     163    }
     164#else
     165# error "!IN_RING0 && !IN_RING3"
     166#endif
     167    return rc;
     168}
     169
     170
     171/**
     172 * Terminates the thread database.
     173 */
     174void rtThreadTerm(void)
     175{
     176#ifdef IN_RING3
     177    /* we don't cleanup here yet */
     178
     179#elif defined(IN_RING0)
     180    /* just destroy the spinlock and assume the thread is fine... */
     181    RTSpinlockDestroy(g_ThreadSpinlock);
     182    g_ThreadSpinlock = NIL_RTSPINLOCK;
     183    if (g_ThreadTree != NULL)
     184        AssertMsg2("WARNING: g_ThreadTree=%p\n", g_ThreadTree);
     185#endif
     186}
     187
     188
     189
     190#ifdef IN_RING3
     191
     192inline void rtThreadLockRW(void)
     193{
     194    if (g_ThreadRWSem == NIL_RTSEMRW)
     195        rtThreadInit();
     196    int rc = RTSemRWRequestWrite(g_ThreadRWSem, RT_INDEFINITE_WAIT);
     197    AssertReleaseRC(rc);
     198}
     199
     200
     201inline void rtThreadLockRD(void)
     202{
     203    if (g_ThreadRWSem == NIL_RTSEMRW)
     204        rtThreadInit();
     205    int rc = RTSemRWRequestRead(g_ThreadRWSem, RT_INDEFINITE_WAIT);
     206    AssertReleaseRC(rc);
     207}
     208
     209
     210inline void rtThreadUnLockRW(void)
     211{
     212    int rc = RTSemRWReleaseWrite(g_ThreadRWSem);
     213    AssertReleaseRC(rc);
     214}
     215
     216
     217inline void rtThreadUnLockRD(void)
     218{
     219    int rc = RTSemRWReleaseRead(g_ThreadRWSem);
     220    AssertReleaseRC(rc);
     221}
     222
     223#endif /* IN_RING3 */
    124224
    125225
     
    193293        *pThread = Thread;
    194294    return rc;
    195 }
    196 
    197 
    198 inline void rtThreadLockRW(void)
    199 {
    200     if (!g_ThreadRWSem)
    201         rtThreadInit();
    202     int rc = RTSemRWRequestWrite(g_ThreadRWSem, RT_INDEFINITE_WAIT);
    203     AssertReleaseRC(rc);
    204 }
    205 
    206 
    207 inline void rtThreadLockRD(void)
    208 {
    209     if (!g_ThreadRWSem)
    210         rtThreadInit();
    211     int rc = RTSemRWRequestRead(g_ThreadRWSem, RT_INDEFINITE_WAIT);
    212     AssertReleaseRC(rc);
    213 }
    214 
    215 
    216 inline void rtThreadUnLockRW(void)
    217 {
    218     int rc = RTSemRWReleaseWrite(g_ThreadRWSem);
    219     AssertReleaseRC(rc);
    220 }
    221 
    222 
    223 inline void rtThreadUnLockRD(void)
    224 {
    225     int rc = RTSemRWReleaseRead(g_ThreadRWSem);
    226     AssertReleaseRC(rc);
    227295}
    228296
     
    285353    Assert(pThread->u32Magic == RTTHREADINT_MAGIC);
    286354
    287     RT_THREAD_LOCK_RW();
     355    RT_THREAD_LOCK_TMP(Tmp);
     356    RT_THREAD_LOCK_RW(Tmp);
    288357
    289358    /*
     
    317386    }
    318387
    319     RT_THREAD_UNLOCK_RW();
     388    RT_THREAD_UNLOCK_RW(Tmp);
    320389}
    321390
     
    343412static void rtThreadRemove(PRTTHREADINT pThread)
    344413{
    345     RT_THREAD_LOCK_RW();
     414    RT_THREAD_LOCK_TMP(Tmp);
     415    RT_THREAD_LOCK_RW(Tmp);
    346416    if (ASMAtomicBitTestAndClear(&pThread->fIntFlags, RTTHREADINT_FLAG_IN_TREE_BIT))
    347417        rtThreadRemoveLocked(pThread);
    348     RT_THREAD_UNLOCK_RW();
     418    RT_THREAD_UNLOCK_RW(Tmp);
    349419}
    350420
     
    374444     * Simple tree lookup.
    375445     */
    376     RT_THREAD_LOCK_RD();
     446    RT_THREAD_LOCK_TMP(Tmp);
     447    RT_THREAD_LOCK_RD(Tmp);
    377448    PRTTHREADINT pThread = (PRTTHREADINT)RTAvlPVGet(&g_ThreadTree, (void *)NativeThread);
    378     RT_THREAD_UNLOCK_RD();
     449    RT_THREAD_UNLOCK_RD(Tmp);
    379450    return pThread;
    380451}
     
    507578     */
    508579    int rc = rtThreadNativeSetPriority(pThread, pThread->enmType);
     580#ifdef IN_RING3
    509581    AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d enmPriority=%d rc=%Vrc\n",
    510582                     pThread, NativeThread, pThread->szName, pThread->enmType, g_enmProcessPriority, rc));
     583#else
     584    AssertMsgRC(rc, ("Failed to set priority of thread %p (%RTnthrd / %s) to enmType=%d rc=%Vrc\n",
     585                     pThread, NativeThread, pThread->szName, pThread->enmType, rc));
     586#endif
    511587
    512588    /*
     
    848924 * @param       prc             Where to store the return code of the thread. Optional.
    849925 */
    850 RTR3DECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc)
     926RTDECL(int) RTThreadWait(RTTHREAD Thread, unsigned cMillies, int *prc)
    851927{
    852928    int rc = rtThreadWait(Thread, cMillies, prc, true);
     
    885961    int     rc;
    886962    if (    enmType > RTTHREADTYPE_INVALID
    887         &&  enmType < RTTHREADTYPE_LAST)
     963        &&  enmType < RTTHREADTYPE_END)
    888964    {
    889965        PRTTHREADINT pThread = rtThreadGet(Thread);
     
    895971                 * Do the job.
    896972                 */
    897                 RT_THREAD_UNLOCK_RW();
     973                RT_THREAD_LOCK_TMP(Tmp);
     974                RT_THREAD_LOCK_RW(Tmp);
    898975                rc = rtThreadNativeSetPriority(pThread, enmType);
    899976                if (RT_SUCCESS(rc))
    900977                    ASMAtomicXchgSize(&pThread->enmType, enmType);
    901                 else
     978                RT_THREAD_UNLOCK_RW(Tmp);
     979                if (RT_FAILURE(rc))
    902980                    Log(("RTThreadSetType: failed on thread %p (%s), rc=%Vrc!!!\n", Thread, pThread->szName, rc));
    903                 RT_THREAD_LOCK_RW();
    904981            }
    905982            else
     
    9391016
    9401017
     1018#ifdef IN_RING3
     1019
    9411020/**
    9421021 * Recalculates scheduling attributes for the the default process
     
    9511030int rtThreadDoCalcDefaultPriority(RTTHREADTYPE enmType)
    9521031{
    953     RT_THREAD_LOCK_RW();
     1032    RT_THREAD_LOCK_TMP(Tmp);
     1033    RT_THREAD_LOCK_RW(Tmp);
    9541034    int rc = rtSchedNativeCalcDefaultPriority(enmType);
    955     RT_THREAD_UNLOCK_RW();
     1035    RT_THREAD_UNLOCK_RW(Tmp);
    9561036    return rc;
    9571037}
     
    9971077     * scheduling attributes defined by the specified process priority.
    9981078     */
    999     RT_THREAD_LOCK_RW();
     1079    RT_THREAD_LOCK_TMP(Tmp);
     1080    RT_THREAD_LOCK_RW(Tmp);
    10001081    int rc = rtProcNativeSetPriority(enmPriority);
    10011082    if (RT_SUCCESS(rc))
     
    10161097        }
    10171098    }
    1018     RT_THREAD_UNLOCK_RW();
     1099    RT_THREAD_UNLOCK_RW(Tmp);
    10191100    LogFlow(("rtThreadDoSetProcPriority: returns %Vrc\n", rc));
    10201101    return rc;
     
    12151296}
    12161297
     1298#endif /* IN_RING3 */
     1299
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