semevent-r0drv-solaris.c revision 29bdc01040c07a3dd482a94a2cb8f0a90f8587a7
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * innotek Portable Runtime - Semaphores, Ring-0 Driver, Solaris.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * Copyright (C) 2006-2007 innotek GmbH
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * available from http://www.virtualbox.org. This file is free software;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * General Public License as published by the Free Software Foundation,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * If you received this file as part of a commercial VirtualBox
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * distribution, then only the terms of your commercial VirtualBox
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * license agreement apply instead of the previous paragraph.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/*******************************************************************************
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync* Header Files *
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync*******************************************************************************/
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/*******************************************************************************
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync* Structures and Typedefs *
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync*******************************************************************************/
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * Solaris event semaphore.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** Magic value (RTSEMEVENT_MAGIC). */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The number of waiting threads. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** Set if the event object is signaled. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The number of threads in the process of waking up. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The Solaris mutex protecting this structure and pairing up the with the cv. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** The Solaris condition variable. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync mutex_init(&pEventInt->Mtx, "IPRT Event Semaphore", MUTEX_DRIVER, NULL);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cv_init(&pEventInt->Cnd, "IPRT CV", CV_DRIVER, NULL);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicIncU32(&pEventInt->u32Magic); /* make the handle invalid */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* abort waiting thread, last man cleans up. */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ASMAtomicXchgU32(&pEventInt->cWaking, pEventInt->cWaking + pEventInt->cWaiters);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* the last waking thread is gonna do the cleanup */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsyncRTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync AssertMsgReturn(pEventInt->u32Magic == RTSEMEVENT_MAGIC,
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync ("pEventInt=%p u32Magic=%#x\n", pEventInt, pEventInt->u32Magic),
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync unsigned long timeout;
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync * Translate milliseconds into ticks and go to sleep.
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync cTicks = drv_usectohz((clock_t)(cMillies * 1000L));
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** @todo r=bird: Is this interruptible or non-interruptible? */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync rc = cv_timedwait_sig(&pEventInt->Cnd, &pEventInt->Mtx, timeout);
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* Retured due to call to cv_signal() or cv_broadcast() */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /** @todo r=bird: better make sure you're the last guy out before doing the cleanup.... */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* Returned due to timeout being reached */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync /* Returned due to pending signal */
29bdc01040c07a3dd482a94a2cb8f0a90f8587a7vboxsync/** @todo Implement RTSemEventWaitNoResume (interruptible variant of the uninterruptible RTSemEventWait()). */