semeventmulti-r0drv-solaris.c revision aaafb754e64fa5946d30a0fa9c1c0ffaa483ee43
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * innotek Portable Runtime - Multiple Release Event Semaphores, Ring-0 Driver, Solaris.
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * Copyright (C) 2006-2007 innotek GmbH
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * available from http://www.virtualbox.org. This file is free software;
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * you can redistribute it and/or modify it under the terms of the GNU
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * General Public License as published by the Free Software Foundation,
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
089c21a647af46044cad04a78cfdcfae814d2105vboxsync/*******************************************************************************
089c21a647af46044cad04a78cfdcfae814d2105vboxsync* Header Files *
089c21a647af46044cad04a78cfdcfae814d2105vboxsync*******************************************************************************/
089c21a647af46044cad04a78cfdcfae814d2105vboxsync/*******************************************************************************
089c21a647af46044cad04a78cfdcfae814d2105vboxsync* Structures and Typedefs *
089c21a647af46044cad04a78cfdcfae814d2105vboxsync*******************************************************************************/
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * FreeBSD multiple release event semaphore.
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /** Magic value (RTSEMEVENTMULTI_MAGIC). */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /** The number of waiting threads. */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /** Set if the event object is signaled. */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /** The number of threads in the process of waking up. */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /** The Solaris mutex protecting this structure and pairing up the with the cv. */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /** The Solaris condition variable. */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncRTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
089c21a647af46044cad04a78cfdcfae814d2105vboxsync Assert(sizeof(RTSEMEVENTMULTIINTERNAL) > sizeof(void *));
089c21a647af46044cad04a78cfdcfae814d2105vboxsync AssertPtrReturn(pEventMultiSem, VERR_INVALID_POINTER);
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync mutex_init(&pThis->Mtx, "IPRT Multiple Release Event Semaphore", MUTEX_DRIVER, NULL);
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncRTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
089c21a647af46044cad04a78cfdcfae814d2105vboxsync if (EventMultiSem == NIL_RTSEMEVENTMULTI) /* don't bitch */
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ASMAtomicIncU32(&pThis->u32Magic); /* make the handle invalid */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /* abort waiting thread, last man cleans up. */
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /* the last waking thread is gonna do the cleanup */
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncRTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ASMAtomicXchgU32(&pThis->cWaking, pThis->cWaking + pThis->cWaiters);
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncRTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncstatic int rtSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies, bool fInterruptible)
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync ("pThis=%p u32Magic=%#x\n", pThis, pThis->u32Magic),
089c21a647af46044cad04a78cfdcfae814d2105vboxsync * Translate milliseconds into ticks and go to sleep.
aaafb754e64fa5946d30a0fa9c1c0ffaa483ee43vboxsync int cTicks = drv_usectohz((clock_t)(cMillies * 1000L));
aaafb754e64fa5946d30a0fa9c1c0ffaa483ee43vboxsync rc = cv_timedwait_sig(&pEventMultiInt->Cnd, &pEventMultiInt->Mtx, timeout);
aaafb754e64fa5946d30a0fa9c1c0ffaa483ee43vboxsync rc = cv_timedwait(&pEventMultiInt->Cnd, &pEventMultiInt->Mtx, timeout);
aaafb754e64fa5946d30a0fa9c1c0ffaa483ee43vboxsync rc = cv_wait_sig(&pEventMultiInt->Cnd, &pEventMultiInt->Mtx);
aaafb754e64fa5946d30a0fa9c1c0ffaa483ee43vboxsync cv_wait(&pEventMultiInt->Cnd, &pEventMultiInt->Mtx);
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /* Retured due to call to cv_signal() or cv_broadcast() */
a68835e2c9d5426d501f1bc78ff30e8ec5bb12cevboxsync if (RT_LIKELY(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC))
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /* Returned due to timeout being reached */
089c21a647af46044cad04a78cfdcfae814d2105vboxsync /* Returned due to pending signal */
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncRTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
089c21a647af46044cad04a78cfdcfae814d2105vboxsync return rtSemEventMultiWait(EventMultiSem, cMillies, false /* not interruptible */);
089c21a647af46044cad04a78cfdcfae814d2105vboxsyncRTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
089c21a647af46044cad04a78cfdcfae814d2105vboxsync return rtSemEventMultiWait(EventMultiSem, cMillies, true /* interruptible */);