spinlock-generic.cpp revision c97989161fbe75bc14cea477a5443bbf474dd3ad
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * innotek Portable Runtime - Spinlock, generic implementation.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (C) 2006-2007 innotek GmbH
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This file is part of VirtualBox Open Source Edition (OSE), as
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * available from http://www.virtualbox.org. This file is free software;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * you can redistribute it and/or modify it under the terms of the GNU
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * General Public License as published by the Free Software Foundation,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * distribution. VirtualBox OSE is distributed in the hope that it will
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * be useful, but WITHOUT ANY WARRANTY of any kind.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If you received this file as part of a commercial VirtualBox
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * distribution, then only the terms of your commercial VirtualBox
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * license agreement apply instead of the previous paragraph.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*******************************************************************************
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster* Defined Constants And Macros *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster*******************************************************************************/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/** @def RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
a4544a5a0e622ef69e38641f87ab1b5685e05911Phill Cunnington * Force cpu yields after spinning the number of times indicated by the define.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If 0 we will spin forever. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*******************************************************************************
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster* Header Files *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster*******************************************************************************/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*******************************************************************************
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster* Structures and Typedefs *
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major*******************************************************************************/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Generic spinlock structure.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /** Spinlock magic value (RTSPINLOCK_MAGIC). */
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott /** The spinlock. */
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterRTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pSpinlockInt));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Initialize and return.
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterRTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Validate input.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (pSpinlockInt->u32Magic != RTSPINLOCK_MAGIC)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsgFailed(("Invalid spinlock %p magic=%#x\n", pSpinlockInt, pSpinlockInt->u32Magic));
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterRTDECL(void) RTSpinlockAcquireNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster while (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*nothing */;
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterRTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt));
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterRTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster while (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*nothing */;
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterRTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt));