spinlock-r0drv-solaris.c revision f85630691753e2acd5099c3079b3e6d40c049a62
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/* $Id$ */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @file
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * IPRT - Spinlocks, Ring-0 Driver, Solaris.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * available from http://www.virtualbox.org. This file is free software;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * General Public License (GPL) as published by the Free Software
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * The contents of this file may alternatively be used under the terms
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * of the Common Development and Distribution License Version 1.0
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * CDDL are applicable instead of those of the GPL.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * You may elect to license modified versions of this file under the
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync * terms and conditions of either the GPL or the CDDL or both.
7b9f0c34e9ea328981c99e97054bdf8684d9d620vboxsync *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * additional information or have any questions.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync/*******************************************************************************
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync* Header Files *
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync*******************************************************************************/
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#include "the-solaris-kernel.h"
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#include "internal/iprt.h"
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync#include <iprt/spinlock.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <iprt/asm.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <iprt/assert.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <iprt/err.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <iprt/mem.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include <iprt/mp.h>
13f1ce3859ee77d9b9f4d2ca9f93e1633cb133bcvboxsync#include <iprt/thread.h>
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#include "internal/magics.h"
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/*******************************************************************************
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync* Structures and Typedefs *
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync*******************************************************************************/
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/**
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Wrapper for the struct mutex type.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsynctypedef struct RTSPINLOCKINTERNAL
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync{
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Spinlock magic value (RTSPINLOCK_MAGIC). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync uint32_t volatile u32Magic;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** A Solaris spinlock. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync kmutex_t Mtx;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsyncRTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock)
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync{
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync /*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Allocate.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RT_ASSERT_PREEMPTIBLE();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertCompile(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *));
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pSpinlockInt));
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync if (!pSpinlockInt)
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync return VERR_NO_MEMORY;
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync /*
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync * Initialize & return.
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync */
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync pSpinlockInt->u32Magic = RTSPINLOCK_MAGIC;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync mutex_init(&pSpinlockInt->Mtx, "IPRT Spinlock", MUTEX_SPIN, (void *)ipltospl(DISP_LEVEL));
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync *pSpinlock = pSpinlockInt;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync return VINF_SUCCESS;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync}
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsyncRTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync{
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync /*
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync * Validate input.
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync */
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync RT_ASSERT_INTS_ON();
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync if (!pSpinlockInt)
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync return VERR_INVALID_PARAMETER;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync AssertMsgReturn(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync ("Invalid spinlock %p magic=%#x\n", pSpinlockInt, pSpinlockInt->u32Magic),
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync VERR_INVALID_PARAMETER);
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync /*
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync * Make the lock invalid and release the memory.
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync */
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync ASMAtomicIncU32(&pSpinlockInt->u32Magic);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync mutex_destroy(&pSpinlockInt->Mtx);
35e6d303696e46d969aaf9a59cc381333a483b0bvboxsync RTMemFree(pSpinlockInt);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync return VINF_SUCCESS;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync}
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsyncRTDECL(void) RTSpinlockAcquireNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync{
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync AssertPtr(pSpinlockInt);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync pTmp->uFlags = ASMIntDisableFlags();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync {
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RT_ASSERT_PREEMPT_CPUID_VAR();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync mutex_enter(&pSpinlockInt->Mtx);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RT_ASSERT_PREEMPT_CPUID();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync }
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync}
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync{
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtr(pSpinlockInt);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync mutex_exit(&pSpinlockInt->Mtx);
c10a6f0c7041e4d1ee50ad38425aab9d43c55522vboxsync ASMSetFlags(pTmp->uFlags);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync}
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync{
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RT_ASSERT_PREEMPT_CPUID_VAR();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertPtr(pSpinlockInt);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync NOREF(pTmp);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync mutex_enter(&pSpinlockInt->Mtx);
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync RT_ASSERT_PREEMPT_CPUID();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#ifdef RT_MORE_STRICT
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /* Spinlocks are not preemptible, so we cannot be rescheduled. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pTmp->uFlags = idAssertCpu != NIL_RTCPUID ? idAssertCpu : RTMpCpuId();
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#endif
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync}
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync
2f3883b126a405f92b19e829472f614c7352b4f9vboxsyncRTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync{
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync#ifdef RT_MORE_STRICT
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync RTCPUID const idAssertCpu = pTmp->uFlags;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync pTmp->uFlags = 0;
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync#endif
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync AssertPtr(pSpinlockInt);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync RT_ASSERT_PREEMPT_CPUID();
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync NOREF(pTmp);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync mutex_exit(&pSpinlockInt->Mtx);
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync}
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync
8bc8d66f188d5357155b8340e2d489573be2b607vboxsync