semaphore-r0drv-nt.cpp revision 881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/* $Id$ */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/** @file
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync * InnoTek Portable Runtime - Semaphores, Ring-0 Driver, NT.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/*
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync *
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * available from http://www.virtualbox.org. This file is free software;
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * you can redistribute it and/or modify it under the terms of the GNU
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * General Public License as published by the Free Software Foundation,
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
fcae7923a3c756b333f1e33eba002edf4448fb54vboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync *
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * If you received this file as part of a commercial VirtualBox
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * distribution, then only the terms of your commercial VirtualBox
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync * license agreement apply instead of the previous paragraph.
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync */
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync
f001425d2b0a661d4cd1f7ea07b4e7454538c829vboxsync/*******************************************************************************
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync* Header Files *
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync*******************************************************************************/
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include "the-nt-kernel.h"
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include <iprt/semaphore.h>
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include <iprt/alloc.h>
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include <iprt/assert.h>
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include <iprt/asm.h>
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include <iprt/err.h>
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#include "internal/magics.h"
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/*******************************************************************************
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync* Structures and Typedefs *
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync*******************************************************************************/
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/**
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * NT event semaphore.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsynctypedef struct RTSEMEVENTINTERNAL
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** Magic value (RTSEMEVENT_MAGIC). */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync uint32_t volatile u32Magic;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** The NT Event object. */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync KEVENT Event;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync} RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/**
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * NT mutex semaphore.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsynctypedef struct RTSEMMUTEXINTERNAL
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** Magic value (RTSEMMUTEX_MAGIC). */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync uint32_t volatile u32Magic;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#ifdef RT_USE_FAST_MUTEX
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** The fast mutex object. */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync FAST_MUTEX Mutex;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#else
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** The NT Mutex object. */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync KMUTEX Mutex;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#endif
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync/**
f65dabff4474710524235022d328b737f174fc1dvboxsync * Wrapper for the linux semaphore structure.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsynctypedef struct RTSEMFASTMUTEXINTERNAL
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** Magic value (RTSEMFASTMUTEX_MAGIC). */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync uint32_t u32Magic;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /** the NT fast mutex. */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync FAST_MUTEX Mutex;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync} RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
561b8d2b46fb10887829b7e4d7d29447817adbddvboxsyncRTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem)
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync{
fb4eaa62a6bbeb82a89703d833d39339783feb4avboxsync Assert(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (pEventInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pEventInt->u32Magic = RTSEMEVENT_MAGIC;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync KeInitializeEvent(&pEventInt->Event, SynchronizationEvent, FALSE);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync *pEventSem = pEventInt;
6479169ec893c18a646cec595e4e214492d180f0vboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_NO_MEMORY;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemEventDestroy(RTSEMEVENT EventSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate input.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pEventInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt->u32Magic, pEventInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Invalidate it and signal the object just in case.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ASMAtomicIncU32(&pEventInt->u32Magic);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync KeSetEvent(&pEventInt->Event, 0xfff, FALSE);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync RTMemFree(pEventInt);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemEventSignal(RTSEMEVENT EventSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate input.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pEventInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if ( !pEventInt
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || pEventInt->u32Magic != RTSEMEVENT_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Signal the event object.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync KeSetEvent(&pEventInt->Event, 1, FALSE);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate input.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pEventInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if ( !pEventInt
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || pEventInt->u32Magic != RTSEMEVENT_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync return VERR_INVALID_PARAMETER;
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync }
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync /*
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync * Wait for it.
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync */
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync NTSTATUS rcNt;
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync if (cMillies == RT_INDEFINITE_WAIT)
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync rcNt = KeWaitForSingleObject(&pEventInt->Event, Executive, KernelMode, TRUE, NULL);
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync else
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync {
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync LARGE_INTEGER Timeout;
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync Timeout.QuadPart = -(int64_t)cMillies * 10000;
6479169ec893c18a646cec595e4e214492d180f0vboxsync rcNt = KeWaitForSingleObject(&pEventInt->Event, Executive, KernelMode, TRUE, &Timeout);
6479169ec893c18a646cec595e4e214492d180f0vboxsync }
6479169ec893c18a646cec595e4e214492d180f0vboxsync switch (rcNt)
6479169ec893c18a646cec595e4e214492d180f0vboxsync {
6479169ec893c18a646cec595e4e214492d180f0vboxsync case STATUS_SUCCESS:
6479169ec893c18a646cec595e4e214492d180f0vboxsync if (pEventInt->u32Magic == RTSEMEVENT_MAGIC)
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync return VINF_SUCCESS;
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync return VERR_SEM_DESTROYED;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_ALERTED:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_USER_APC:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_TIMEOUT:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_TIMEOUT;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync default:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p: wait returned %lx!\n",
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pEventInt->u32Magic, pEventInt, (long)rcNt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INTERNAL_ERROR;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync Assert(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (pMutexInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pMutexInt->u32Magic = RTSEMMUTEX_MAGIC;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#ifdef RT_USE_FAST_MUTEX
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ExInitializeFastMutex(&pMutexInt->Mutex);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#else
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync KeInitializeMutex(&pMutexInt->Mutex, 0);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#endif
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync *pMutexSem = pMutexInt;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_NO_MEMORY;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate input.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pMutexInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt->u32Magic, pMutexInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Invalidate it and signal the object just in case.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ASMAtomicIncU32(&pMutexInt->u32Magic);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync RTMemFree(pMutexInt);
6479169ec893c18a646cec595e4e214492d180f0vboxsync return VINF_SUCCESS;
6479169ec893c18a646cec595e4e214492d180f0vboxsync}
6479169ec893c18a646cec595e4e214492d180f0vboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate input.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pMutexInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if ( !pMutexInt
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Get the mutex.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#ifdef RT_USE_FAST_MUTEX
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsg(cMillies == RT_INDEFINITE_WAIT, ("timeouts are not supported when using fast mutexes!\n"));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ExAcquireFastMutex(&pMutexInt->Mutex);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#else
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync NTSTATUS rcNt;
6479169ec893c18a646cec595e4e214492d180f0vboxsync if (cMillies == RT_INDEFINITE_WAIT)
6479169ec893c18a646cec595e4e214492d180f0vboxsync rcNt = KeWaitForSingleObject(&pMutexInt->Mutex, Executive, KernelMode, TRUE, NULL);
6479169ec893c18a646cec595e4e214492d180f0vboxsync else
6479169ec893c18a646cec595e4e214492d180f0vboxsync {
6479169ec893c18a646cec595e4e214492d180f0vboxsync LARGE_INTEGER Timeout;
6479169ec893c18a646cec595e4e214492d180f0vboxsync Timeout.QuadPart = -(int64_t)cMillies * 10000;
6479169ec893c18a646cec595e4e214492d180f0vboxsync rcNt = KeWaitForSingleObject(&pMutexInt->Mutex, Executive, KernelMode, TRUE, &Timeout);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync switch (rcNt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_SUCCESS:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (pMutexInt->u32Magic == RTSEMMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_SEM_DESTROYED;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_ALERTED:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_USER_APC:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync case STATUS_TIMEOUT:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_TIMEOUT;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync default:
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p: wait returned %lx!\n",
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pMutexInt->u32Magic, pMutexInt, (long)rcNt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INTERNAL_ERROR;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#endif
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate input.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pMutexInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if ( !pMutexInt
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Release the mutex.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#ifdef RT_USE_FAST_MUTEX
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync ExReleaseFastMutex(&pMutexInt->Mutex);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#else
35473cad6d5d5b57348c66f0cfdd7d51d6071ee7vboxsync KeReleaseMutex(&pMutexInt->Mutex, FALSE);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync#endif
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemFastMutexCreate(PRTSEMFASTMUTEX pMutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Allocate.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMFASTMUTEXINTERNAL pFastInt;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync Assert(sizeof(*pFastInt) > sizeof(void *));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pFastInt = (PRTSEMFASTMUTEXINTERNAL)RTMemAlloc(sizeof(*pFastInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pFastInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_NO_MEMORY;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Initialize.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync pFastInt->u32Magic = RTSEMFASTMUTEX_MAGIC;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ExInitializeFastMutex(&pFastInt->Mutex);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync *pMutexSem = pFastInt;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemFastMutexDestroy(RTSEMFASTMUTEX MutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
2084a447d1acb619df7c393fac41b79d517e4b3dvboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (!pFastInt)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if (pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt->u32Magic, pFastInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ASMAtomicIncU32(&pFastInt->u32Magic);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync RTMemFree(pFastInt);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemFastMutexRequest(RTSEMFASTMUTEX MutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync if ( !pFastInt
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync || pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt ? pFastInt->u32Magic : 0, pFastInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ExAcquireFastMutex(&pFastInt->Mutex);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsyncRTDECL(int) RTSemFastMutexRelease(RTSEMFASTMUTEX MutexSem)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync{
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync /*
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync * Validate.
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync */
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync if ( !pFastInt
f48c3167a0f99da174686b66dc4e666f38ecae46vboxsync || pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync {
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt ? pFastInt->u32Magic : 0, pFastInt));
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VERR_INVALID_PARAMETER;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync }
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync ExReleaseFastMutex(&pFastInt->Mutex);
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync return VINF_SUCCESS;
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync}
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync
1403063c7e0c0a072d59e323b66068b06278fb9avboxsync