VirtualBox

Ignore:
Timestamp:
Jan 11, 2010 1:24:09 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
56457
Message:

iprt: Added RTSemEventCreateEx and did some cleanups of the RTSemEventDestroy behavior wrt NIL handles.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/solaris/semevent-r0drv-solaris.c

    r25183 r25717  
    7070
    7171
    72 RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
    73 {
    74     Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
    75     AssertPtrReturn(pEventSem, VERR_INVALID_POINTER);
     72RTDECL(int)  RTSemEventCreate(PRTSEMEVENT phEventSem)
     73{
     74    return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
     75}
     76
     77
     78RTDECL(int)  RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)
     79{
     80    AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
     81    AssertReturn(!(fFlags & ~RTSEMEVENT_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
     82    AssertPtrReturn(phEventSem, VERR_INVALID_POINTER);
    7683    RT_ASSERT_PREEMPTIBLE();
    7784
    78     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
    79     if (pEventInt)
    80     {
    81         pEventInt->u32Magic = RTSEMEVENT_MAGIC;
    82         pEventInt->cWaiters = 0;
    83         pEventInt->cWaking = 0;
    84         pEventInt->fSignaled = 0;
    85         mutex_init(&pEventInt->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL));
    86         cv_init(&pEventInt->Cnd, "IPRT CV", CV_DRIVER, NULL);
    87         *pEventSem = pEventInt;
     85    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pThis));
     86    if (!pThis)
     87        return VERR_NO_MEMORY;
     88
     89    pThis->u32Magic = RTSEMEVENT_MAGIC;
     90    pThis->cWaiters = 0;
     91    pThis->cWaking = 0;
     92    pThis->fSignaled = 0;
     93    mutex_init(&pThis->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, (void *)ipltospl(DISP_LEVEL));
     94    cv_init(&pThis->Cnd, "IPRT CV", CV_DRIVER, NULL);
     95
     96    *phEventSem = pThis;
     97    return VINF_SUCCESS;
     98}
     99
     100
     101RTDECL(int)  RTSemEventDestroy(RTSEMEVENT hEventSem)
     102{
     103    PRTSEMEVENTINTERNAL pThis = hEventSem;
     104    if (pThis == NIL_RTSEMEVENT)
    88105        return VINF_SUCCESS;
    89     }
    90     return VERR_NO_MEMORY;
    91 }
    92 
    93 
    94 RTDECL(int)  RTSemEventDestroy(RTSEMEVENT EventSem)
    95 {
    96     if (EventSem == NIL_RTSEMEVENT)
    97         return VERR_INVALID_HANDLE;
    98     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    99     AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
    100     AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
    101                     ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
    102                     VERR_INVALID_HANDLE);
     106    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     107    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
    103108    RT_ASSERT_INTS_ON();
    104109
    105     mutex_enter(&pEventInt->Mtx);
    106     ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */
    107     if (pEventInt->cWaiters > 0)
     110    mutex_enter(&pThis->Mtx);
     111    ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */
     112    if (pThis->cWaiters > 0)
    108113    {
    109114        /* abort waiting thread, last man cleans up. */
    110         ASMAtomicXchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);
    111         cv_broadcast(&pEventInt->Cnd);
    112         mutex_exit(&pEventInt->Mtx);
    113     }
    114     else if (pEventInt->cWaking)
     115        ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);
     116        cv_broadcast(&pThis->Cnd);
     117        mutex_exit(&pThis->Mtx);
     118    }
     119    else if (pThis->cWaking)
    115120    {
    116121        /* the last waking thread is gonna do the cleanup */
    117         mutex_exit(&pEventInt->Mtx);
     122        mutex_exit(&pThis->Mtx);
    118123    }
    119124    else
    120125    {
    121         mutex_exit(&pEventInt->Mtx);
    122         cv_destroy(&pEventInt->Cnd);
    123         mutex_destroy(&pEventInt->Mtx);
    124         RTMemFree(pEventInt);
     126        mutex_exit(&pThis->Mtx);
     127        cv_destroy(&pThis->Cnd);
     128        mutex_destroy(&pThis->Mtx);
     129        RTMemFree(pThis);
    125130    }
    126131
     
    129134
    130135
    131 RTDECL(int)  RTSemEventSignal(RTSEMEVENT EventSem)
    132 {
    133     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
     136RTDECL(int)  RTSemEventSignal(RTSEMEVENT hEventSem)
     137{
     138    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
    134139    RT_ASSERT_PREEMPT_CPUID_VAR();
    135     AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
    136     AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
    137                     ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
    138                     VERR_INVALID_HANDLE);
     140    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     141    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
    139142    RT_ASSERT_INTS_ON();
    140143
     
    151154     *       or not and only call swtch if RTThreadPreemptDisable wasn't called.
    152155     */
    153     int fAcquired = mutex_tryenter(&pEventInt->Mtx);
     156    int fAcquired = mutex_tryenter(&pThis->Mtx);
    154157    if (!fAcquired)
    155158    {
     
    161164            RTThreadPreemptRestore(&PreemptState);
    162165        }
    163         mutex_enter(&pEventInt->Mtx);
    164     }
    165 
    166     if (pEventInt->cWaiters > 0)
    167     {
    168         ASMAtomicDecU32(&pEventInt->cWaiters);
    169         ASMAtomicIncU32(&pEventInt->cWaking);
    170         cv_signal(&pEventInt->Cnd);
     166        mutex_enter(&pThis->Mtx);
     167    }
     168
     169    if (pThis->cWaiters > 0)
     170    {
     171        ASMAtomicDecU32(&pThis->cWaiters);
     172        ASMAtomicIncU32(&pThis->cWaking);
     173        cv_signal(&pThis->Cnd);
    171174    }
    172175    else
    173         ASMAtomicXchgU8(&pEventInt->fSignaled, true);
    174 
    175     mutex_exit(&pEventInt->Mtx);
     176        ASMAtomicXchgU8(&pThis->fSignaled, true);
     177
     178    mutex_exit(&pThis->Mtx);
    176179
    177180    RT_ASSERT_PREEMPT_CPUID();
     
    180183
    181184
    182 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fInterruptible)
     185static int rtSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies, bool fInterruptible)
    183186{
    184187    int rc;
    185     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    186     AssertPtrReturn(pEventInt, VERR_INVALID_HANDLE);
    187     AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
    188                     ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
    189                     VERR_INVALID_HANDLE);
     188    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
     189    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     190    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
    190191    if (cMillies)
    191192        RT_ASSERT_PREEMPTIBLE();
    192193
    193     mutex_enter(&pEventInt->Mtx);
    194 
    195     if (pEventInt->fSignaled)
    196     {
    197         Assert(!pEventInt->cWaiters);
    198         ASMAtomicXchgU8(&pEventInt->fSignaled, false);
     194    mutex_enter(&pThis->Mtx);
     195
     196    if (pThis->fSignaled)
     197    {
     198        Assert(!pThis->cWaiters);
     199        ASMAtomicXchgU8(&pThis->fSignaled, false);
    199200        rc = VINF_SUCCESS;
    200201    }
     
    203204    else
    204205    {
    205         ASMAtomicIncU32(&pEventInt->cWaiters);
     206        ASMAtomicIncU32(&pThis->cWaiters);
    206207
    207208        /*
     
    214215            cTimeout += cTicks;
    215216            if (fInterruptible)
    216                 rc = cv_timedwait_sig(&pEventInt->Cnd, &pEventInt->Mtx, cTimeout);
     217                rc = cv_timedwait_sig(&pThis->Cnd, &pThis->Mtx, cTimeout);
    217218            else
    218                 rc = cv_timedwait(&pEventInt->Cnd, &pEventInt->Mtx, cTimeout);
     219                rc = cv_timedwait(&pThis->Cnd, &pThis->Mtx, cTimeout);
    219220        }
    220221        else
    221222        {
    222223            if (fInterruptible)
    223                 rc = cv_wait_sig(&pEventInt->Cnd, &pEventInt->Mtx);
     224                rc = cv_wait_sig(&pThis->Cnd, &pThis->Mtx);
    224225            else
    225226            {
    226                 cv_wait(&pEventInt->Cnd, &pEventInt->Mtx);
     227                cv_wait(&pThis->Cnd, &pThis->Mtx);
    227228                rc = 1;
    228229            }
     
    232233        {
    233234            /* Retured due to call to cv_signal() or cv_broadcast() */
    234             if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
     235            if (pThis->u32Magic != RTSEMEVENT_MAGIC)
    235236            {
    236237                rc = VERR_SEM_DESTROYED;
    237                 if (!ASMAtomicDecU32(&pEventInt->cWaking))
     238                if (!ASMAtomicDecU32(&pThis->cWaking))
    238239                {
    239                     mutex_exit(&pEventInt->Mtx);
    240                     cv_destroy(&pEventInt->Cnd);
    241                     mutex_destroy(&pEventInt->Mtx);
    242                     RTMemFree(pEventInt);
     240                    mutex_exit(&pThis->Mtx);
     241                    cv_destroy(&pThis->Cnd);
     242                    mutex_destroy(&pThis->Mtx);
     243                    RTMemFree(pThis);
    243244                    return rc;
    244245                }
    245246            }
    246247
    247             ASMAtomicDecU32(&pEventInt->cWaking);
     248            ASMAtomicDecU32(&pThis->cWaking);
    248249            rc = VINF_SUCCESS;
    249250        }
     
    251252        {
    252253            /* Returned due to timeout being reached */
    253             if (pEventInt->cWaiters > 0)
    254                 ASMAtomicDecU32(&pEventInt->cWaiters);
     254            if (pThis->cWaiters > 0)
     255                ASMAtomicDecU32(&pThis->cWaiters);
    255256            rc = VERR_TIMEOUT;
    256257        }
     
    258259        {
    259260            /* Returned due to pending signal */
    260             if (pEventInt->cWaiters > 0)
    261                 ASMAtomicDecU32(&pEventInt->cWaiters);
     261            if (pThis->cWaiters > 0)
     262                ASMAtomicDecU32(&pThis->cWaiters);
    262263            rc = VERR_INTERRUPTED;
    263264        }
    264265    }
    265266
    266     mutex_exit(&pEventInt->Mtx);
     267    mutex_exit(&pThis->Mtx);
    267268    return rc;
    268269}
    269270
    270271
    271 RTDECL(int)  RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
    272 {
    273     return rtSemEventWait(EventSem, cMillies, false /* not interruptible */);
    274 }
    275 
    276 
    277 RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
    278 {
    279     return rtSemEventWait(EventSem, cMillies, true /* interruptible */);
    280 }
     272RTDECL(int)  RTSemEventWait(RTSEMEVENT hEventSem, unsigned cMillies)
     273{
     274    return rtSemEventWait(hEventSem, cMillies, false /* not interruptible */);
     275}
     276
     277
     278RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT hEventSem, unsigned cMillies)
     279{
     280    return rtSemEventWait(hEventSem, cMillies, true /* interruptible */);
     281}
Note: See TracChangeset for help on using the changeset viewer.

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