VirtualBox

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

iprt: Added RTSemEventMultiCreateEx and did some cleanups of the RTSemEventMultiDestroy behavior wrt NIL handles.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/freebsd/semeventmulti-r0drv-freebsd.c

    r22819 r25720  
    6464
    6565
    66 RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
    67 {
    68     Assert(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *));
    69     AssertPtrReturn(pEventMultiSem, VERR_INVALID_POINTER);
    70 
    71     PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)RTMemAllocZ(sizeof(*pEventMultiInt));
    72     if (pEventMultiInt)
    73     {
    74         pEventMultiInt->u32Magic = RTSEMEVENTMULTI_MAGIC;
    75         pEventMultiInt->cWaiters = 0;
    76         pEventMultiInt->cWaking = 0;
    77         pEventMultiInt->fSignaled = 0;
    78         int rc = RTSpinlockCreate(&pEventMultiInt->hSpinLock);
     66RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
     67{
     68    return RTSemEventMultiCreateEx(phEventMultiSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
     69}
     70
     71
     72RTDECL(int)  RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
     73                                     const char *pszNameFmt, ...)
     74{
     75    AssertCompile(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *));
     76    AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
     77    AssertPtrReturn(phEventMultiSem, VERR_INVALID_POINTER);
     78
     79    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAllocZ(sizeof(*pThis));
     80    if (pThis)
     81    {
     82        pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
     83        pThis->cWaiters = 0;
     84        pThis->cWaking = 0;
     85        pThis->fSignaled = 0;
     86        int rc = RTSpinlockCreate(&pThis->hSpinLock);
    7987        if (RT_SUCCESS(rc))
    8088        {
    81             *pEventMultiSem = pEventMultiInt;
     89            *phEventMultiSem = pThis;
    8290            return VINF_SUCCESS;
    8391        }
    8492
    85         RTMemFree(pEventMultiInt);
     93        RTMemFree(pThis);
    8694        return rc;
    8795    }
     
    9098
    9199
    92 RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
    93 {
    94     if (EventMultiSem == NIL_RTSEMEVENTMULTI)     /* don't bitch */
    95         return VERR_INVALID_HANDLE;
    96     PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     100RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
     101{
     102    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
    97103    RTSPINLOCKTMP            Tmp = RTSPINLOCKTMP_INITIALIZER;
    98104
    99     AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
    100     AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
    101                     ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     105    if (pThis == NIL_RTSEMEVENTMULTI)
     106        return VINF_SUCCESS;
     107    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     108    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
     109
     110    RTSpinlockAcquire(pThis->hSpinLock, &Tmp);
     111    ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */
     112    if (pThis->cWaiters > 0)
     113    {
     114        /* abort waiting thread, last man cleans up. */
     115        ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);
     116        sleepq_lock(pThis);
     117        sleepq_broadcast(pThis, SLEEPQ_CONDVAR, 0, 0);
     118        sleepq_release(pThis);
     119        RTSpinlockRelease(pThis->hSpinLock, &Tmp);
     120    }
     121    else if (pThis->cWaking)
     122        /* the last waking thread is gonna do the cleanup */
     123        RTSpinlockRelease(pThis->hSpinLock, &Tmp);
     124    else
     125    {
     126        RTSpinlockRelease(pThis->hSpinLock, &Tmp);
     127        RTSpinlockDestroy(pThis->hSpinLock);
     128        RTMemFree(pThis);
     129    }
     130
     131    return VINF_SUCCESS;
     132}
     133
     134
     135RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
     136{
     137    RTSPINLOCKTMP            Tmp = RTSPINLOCKTMP_INITIALIZER;
     138    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     139    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     140    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
     141                    ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
    102142                    VERR_INVALID_HANDLE);
    103143
    104     RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp);
    105     ASMAtomicIncU32(&pEventMultiInt->u32Magic); /* make the handle invalid */
    106     if (pEventMultiInt->cWaiters > 0)
    107     {
    108         /* abort waiting thread, last man cleans up. */
    109         ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);
    110         sleepq_lock(pEventMultiInt);
    111         sleepq_broadcast(pEventMultiInt, SLEEPQ_CONDVAR, 0, 0);
    112         sleepq_release(pEventMultiInt);
    113         RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
    114     }
    115     else if (pEventMultiInt->cWaking)
    116         /* the last waking thread is gonna do the cleanup */
    117         RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
    118     else
    119     {
    120         RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
    121         RTSpinlockDestroy(pEventMultiInt->hSpinLock);
    122         RTMemFree(pEventMultiInt);
    123     }
    124 
    125     return VINF_SUCCESS;
    126 }
    127 
    128 
    129 RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
    130 {
    131     RTSPINLOCKTMP            Tmp = RTSPINLOCKTMP_INITIALIZER;
    132     PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
    133     AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
    134     AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
    135                     ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
    136                     VERR_INVALID_HANDLE);
    137 
    138     RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp);
    139 
    140     ASMAtomicXchgU8(&pEventMultiInt->fSignaled, true);
    141     if (pEventMultiInt->cWaiters > 0)
    142     {
    143         ASMAtomicXchgU32(&pEventMultiInt->cWaking, pEventMultiInt->cWaking + pEventMultiInt->cWaiters);
    144         ASMAtomicXchgU32(&pEventMultiInt->cWaiters, 0);
    145         sleepq_lock(pEventMultiInt);
    146         int fWakeupSwapProc = sleepq_signal(pEventMultiInt, SLEEPQ_CONDVAR, 0, 0);
    147         sleepq_release(pEventMultiInt);
     144    RTSpinlockAcquire(pThis->hSpinLock, &Tmp);
     145
     146    ASMAtomicXchgU8(&pThis->fSignaled, true);
     147    if (pThis->cWaiters > 0)
     148    {
     149        ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);
     150        ASMAtomicXchgU32(&pThis->cWaiters, 0);
     151        sleepq_lock(pThis);
     152        int fWakeupSwapProc = sleepq_signal(pThis, SLEEPQ_CONDVAR, 0, 0);
     153        sleepq_release(pThis);
    148154        if (fWakeupSwapProc)
    149155            kick_proc0();
    150156    }
    151157
    152     RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
     158    RTSpinlockRelease(pThis->hSpinLock, &Tmp);
    153159    return VINF_SUCCESS;
    154160}
    155161
    156162
    157 RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
     163RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)
    158164{
    159165    RTSPINLOCKTMP            Tmp = RTSPINLOCKTMP_INITIALIZER;
    160     PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
    161     AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
    162     AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
    163                     ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     166    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     167    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     168    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
     169                    ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
    164170                    VERR_INVALID_HANDLE);
    165171
    166     RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp);
    167     ASMAtomicXchgU8(&pEventMultiInt->fSignaled, false);
    168     RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
     172    RTSpinlockAcquire(pThis->hSpinLock, &Tmp);
     173    ASMAtomicXchgU8(&pThis->fSignaled, false);
     174    RTSpinlockRelease(pThis->hSpinLock, &Tmp);
    169175    return VINF_SUCCESS;
    170176}
    171177
    172178
    173 static int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fInterruptible)
     179static int rtSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, unsigned cMillies, bool fInterruptible)
    174180{
    175181    int rc;
    176182    RTSPINLOCKTMP            Tmp = RTSPINLOCKTMP_INITIALIZER;
    177     PRTSEMEVENTMULTIINTERNAL pEventMultiInt = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
    178     AssertPtrReturn(pEventMultiInt, VERR_INVALID_HANDLE);
    179     AssertMsgReturn(pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC,
    180                     ("pEventMultiInt=%p u32Magic=%#x\n", pEventMultiInt, pEventMultiInt->u32Magic),
     183    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
     184    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     185    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
     186                    ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
    181187                    VERR_INVALID_HANDLE);
    182188
    183     RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp);
    184 
    185     if (pEventMultiInt->fSignaled)
     189    RTSpinlockAcquire(pThis->hSpinLock, &Tmp);
     190
     191    if (pThis->fSignaled)
    186192        rc = VINF_SUCCESS;
    187193    else
     
    191197        else
    192198        {
    193             ASMAtomicIncU32(&pEventMultiInt->cWaiters);
     199            ASMAtomicIncU32(&pThis->cWaiters);
    194200
    195201            int fFlags = SLEEPQ_CONDVAR;
     
    198204                fFlags |= SLEEPQ_INTERRUPTIBLE;
    199205
    200             sleepq_lock(pEventMultiInt);
    201             sleepq_add(pEventMultiInt, NULL, "IPRT Event Semaphore", fFlags, 0);
     206            sleepq_lock(pThis);
     207            sleepq_add(pThis, NULL, "IPRT Event Semaphore", fFlags, 0);
    202208
    203209            if (cMillies != RT_INDEFINITE_WAIT)
     
    211217                tv.tv_usec = (cMillies % 1000) * 1000;
    212218
    213                 sleepq_set_timeout(pEventMultiInt, tvtohz(&tv));
    214 
    215                 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
     219                sleepq_set_timeout(pThis, tvtohz(&tv));
     220
     221                RTSpinlockRelease(pThis->hSpinLock, &Tmp);
    216222
    217223                if (fInterruptible)
    218                     rc = SLEEPQ_TIMEDWAIT_SIG(pEventMultiInt);
     224                    rc = SLEEPQ_TIMEDWAIT_SIG(pThis);
    219225                else
    220                     rc = SLEEPQ_TIMEDWAIT(pEventMultiInt);
     226                    rc = SLEEPQ_TIMEDWAIT(pThis);
    221227            }
    222228            else
    223229            {
    224                 RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
     230                RTSpinlockRelease(pThis->hSpinLock, &Tmp);
    225231
    226232                if (fInterruptible)
    227                     rc = SLEEPQ_WAIT_SIG(pEventMultiInt);
     233                    rc = SLEEPQ_WAIT_SIG(pThis);
    228234                else
    229235                {
    230236                    rc = 0;
    231                     SLEEPQ_WAIT(pEventMultiInt);
     237                    SLEEPQ_WAIT(pThis);
    232238                }
    233239            }
    234240
    235             RTSpinlockAcquire(pEventMultiInt->hSpinLock, &Tmp);
     241            RTSpinlockAcquire(pThis->hSpinLock, &Tmp);
    236242
    237243            switch (rc)
    238244            {
    239245                case 0:
    240                     if (pEventMultiInt->u32Magic == RTSEMEVENTMULTI_MAGIC)
     246                    if (pThis->u32Magic == RTSEMEVENTMULTI_MAGIC)
    241247                    {
    242                         ASMAtomicDecU32(&pEventMultiInt->cWaking);
     248                        ASMAtomicDecU32(&pThis->cWaking);
    243249                        rc = VINF_SUCCESS;
    244250                    }
     
    247253                        rc = VERR_SEM_DESTROYED; /** @todo this isn't necessarily correct, we've
    248254                                                  * could've woken up just before destruction... */
    249                         if (!ASMAtomicDecU32(&pEventMultiInt->cWaking))
     255                        if (!ASMAtomicDecU32(&pThis->cWaking))
    250256                        {
    251257                            /* The event was destroyed, as the last thread do the cleanup.
    252258                               we don't actually know whether */
    253                             RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
    254                             RTSpinlockDestroy(pEventMultiInt->hSpinLock);
    255                             RTMemFree(pEventMultiInt);
     259                            RTSpinlockRelease(pThis->hSpinLock, &Tmp);
     260                            RTSpinlockDestroy(pThis->hSpinLock);
     261                            RTMemFree(pThis);
    256262                            return rc;
    257263                        }
     
    261267                case EWOULDBLOCK:
    262268                    Assert(cMillies != RT_INDEFINITE_WAIT);
    263                     if (pEventMultiInt->cWaiters > 0)
    264                         ASMAtomicDecU32(&pEventMultiInt->cWaiters);
     269                    if (pThis->cWaiters > 0)
     270                        ASMAtomicDecU32(&pThis->cWaiters);
    265271                    rc = VERR_TIMEOUT;
    266272                    break;
     
    269275                case ERESTART:
    270276                    Assert(fInterruptible);
    271                     if (pEventMultiInt->cWaiters > 0)
    272                         ASMAtomicDecU32(&pEventMultiInt->cWaiters);
     277                    if (pThis->cWaiters > 0)
     278                        ASMAtomicDecU32(&pThis->cWaiters);
    273279                    rc = VERR_INTERRUPTED;
    274280                    break;
     
    282288    }
    283289
    284     RTSpinlockRelease(pEventMultiInt->hSpinLock, &Tmp);
     290    RTSpinlockRelease(pThis->hSpinLock, &Tmp);
    285291    return rc;
    286292}
    287293
    288294
    289 RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
    290 {
    291     return rtSemEventMultiWait(EventMultiSem, cMillies, false /* not interruptible */);
    292 }
    293 
    294 
    295 RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
    296 {
    297     return rtSemEventMultiWait(EventMultiSem, cMillies, true /* interruptible */);
    298 }
    299 
     295RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, unsigned cMillies)
     296{
     297    return rtSemEventMultiWait(hEventMultiSem, cMillies, false /* not interruptible */);
     298}
     299
     300
     301RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, unsigned cMillies)
     302{
     303    return rtSemEventMultiWait(hEventMultiSem, cMillies, true /* interruptible */);
     304}
     305
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