a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync/* $Id$ */
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync/** @file
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * IPRT - Fast Mutex Semaphores, Ring-0 Driver, Linux.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync/*
e205d4c80367d15b2a8240be8a5e676764f34d70vboxsync * Copyright (C) 2006-2011 Oracle Corporation
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync *
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * available from http://www.virtualbox.org. This file is free software;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * The contents of this file may alternatively be used under the terms
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * of the Common Development and Distribution License Version 1.0
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution, in which case the provisions of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * CDDL are applicable instead of those of the GPL.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * You may elect to license modified versions of this file under the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * terms and conditions of either the GPL or the CDDL or both.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync/*******************************************************************************
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync* Header Files *
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync*******************************************************************************/
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include "the-linux-kernel.h"
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#include "internal/iprt.h"
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include <iprt/semaphore.h>
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include <iprt/alloc.h>
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include <iprt/assert.h>
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include <iprt/asm.h>
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include <iprt/err.h>
e205d4c80367d15b2a8240be8a5e676764f34d70vboxsync#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync# include <iprt/thread.h>
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync#endif
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync#include "internal/magics.h"
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync/*******************************************************************************
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync* Structures and Typedefs *
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync*******************************************************************************/
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync/**
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * Wrapper for the linux semaphore structure.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsynctypedef struct RTSEMFASTMUTEXINTERNAL
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync{
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /** Magic value (RTSEMFASTMUTEX_MAGIC). */
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync uint32_t u32Magic;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /** the linux semaphore. */
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync struct semaphore Semaphore;
e205d4c80367d15b2a8240be8a5e676764f34d70vboxsync#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync /** For check. */
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync RTNATIVETHREAD volatile Owner;
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync#endif
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync} RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsyncRTDECL(int) RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx)
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync{
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /*
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * Allocate.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync PRTSEMFASTMUTEXINTERNAL pThis;
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync pThis = (PRTSEMFASTMUTEXINTERNAL)RTMemAlloc(sizeof(*pThis));
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync if (!pThis)
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync return VERR_NO_MEMORY;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /*
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * Initialize.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync pThis->u32Magic = RTSEMFASTMUTEX_MAGIC;
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync sema_init(&pThis->Semaphore, 1);
e205d4c80367d15b2a8240be8a5e676764f34d70vboxsync#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync pThis->Owner = NIL_RTNATIVETHREAD;
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync#endif
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync *phFastMtx = pThis;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync return VINF_SUCCESS;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTSemFastMutexCreate);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsyncRTDECL(int) RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx)
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync{
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /*
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * Validate.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync if (pThis == NIL_RTSEMFASTMUTEX)
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync return VINF_SUCCESS;
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync ASMAtomicWriteU32(&pThis->u32Magic, RTSEMFASTMUTEX_MAGIC_DEAD);
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync RTMemFree(pThis);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync return VINF_SUCCESS;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTSemFastMutexDestroy);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsyncRTDECL(int) RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx)
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync{
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /*
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * Validate.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
522c1c08030ede17ea463e2ee2391d3ba65f4f60vboxsync IPRT_DEBUG_SEMS_STATE(pThis, 'd');
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync down(&pThis->Semaphore);
e205d4c80367d15b2a8240be8a5e676764f34d70vboxsync#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
522c1c08030ede17ea463e2ee2391d3ba65f4f60vboxsync IPRT_DEBUG_SEMS_STATE(pThis, 'o');
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertRelease(pThis->Owner == NIL_RTNATIVETHREAD);
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync ASMAtomicUoWriteSize(&pThis->Owner, RTThreadNativeSelf());
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync#endif
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync return VINF_SUCCESS;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTSemFastMutexRequest);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsyncRTDECL(int) RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync{
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync /*
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync * Validate.
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync */
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync
e205d4c80367d15b2a8240be8a5e676764f34d70vboxsync#if defined(RT_STRICT) || defined(IPRT_DEBUG_SEMS)
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync AssertRelease(pThis->Owner == RTThreadNativeSelf());
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync ASMAtomicUoWriteSize(&pThis->Owner, NIL_RTNATIVETHREAD);
fe4be2b043180249b7f7d5b22aced0bfe75764c4vboxsync#endif
47c238f82281a3771c8bfb66858da823ecf03dbcvboxsync up(&pThis->Semaphore);
522c1c08030ede17ea463e2ee2391d3ba65f4f60vboxsync IPRT_DEBUG_SEMS_STATE(pThis, 'u');
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync return VINF_SUCCESS;
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTSemFastMutexRelease);
a8e0cb7ddfd05bcabf5e18959cf09e723f254663vboxsync