spinlock-generic.cpp revision 549973ce036bba9254be2155c59dc49edda940f5
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * IPRT - Spinlock, generic implementation.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * Copyright (C) 2006-2012 Oracle Corporation
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * available from http://www.virtualbox.org. This file is free software;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * you can redistribute it and/or modify it under the terms of the GNU
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * General Public License (GPL) as published by the Free Software
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * The contents of this file may alternatively be used under the terms
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * of the Common Development and Distribution License Version 1.0
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VirtualBox OSE distribution, in which case the provisions of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * CDDL are applicable instead of those of the GPL.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * You may elect to license modified versions of this file under the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * terms and conditions of either the GPL or the CDDL or both.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Defined Constants And Macros *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/** @def RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Force cpu yields after spinning the number of times indicated by the define.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * If 0 we will spin forever. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Header Files *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync/*******************************************************************************
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync* Structures and Typedefs *
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync*******************************************************************************/
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Generic spinlock structure.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /** Spinlock magic value (RTSPINLOCK_MAGIC). */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** The spinlock creation flags. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** The spinlock. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** The saved CPU interrupt. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsyncRTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName)
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync AssertReturn(fFlags == RTSPINLOCK_FLAGS_INTERRUPT_SAFE || fFlags == RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, VERR_INVALID_PARAMETER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Allocate.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pThis = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pThis));
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * Initialize and return.
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * Validate input.
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertMsgFailed(("Invalid spinlock %p magic=%#x\n", pThis, pThis->u32Magic));
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC,
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync ("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync while (!ASMAtomicCmpXchgU32(&pThis->fLocked, 1, 0))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertMsg(pThis && pThis->u32Magic == RTSPINLOCK_MAGIC,
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync ("pThis=%p u32Magic=%08x\n", pThis, pThis ? (int)pThis->u32Magic : 0));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertMsgFailed(("Spinlock %p was not locked!\n", pThis));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertMsgFailed(("Spinlock %p was not locked!\n", pThis));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsyncRTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (RT_UNLIKELY(!(Spinlock->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync RTAssertMsg2("RTSpinlockReleaseNoInts: %p (magic=%#x)\n", Spinlock, Spinlock->u32Magic);