d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync/* $Id$ */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync/** @file
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * IPRT - Spinlocks, Ring-0 Driver, OS/2.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync/*
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync *
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Permission is hereby granted, free of charge, to any person
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * obtaining a copy of this software and associated documentation
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * files (the "Software"), to deal in the Software without
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * restriction, including without limitation the rights to use,
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * copy, modify, merge, publish, distribute, sublicense, and/or sell
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * copies of the Software, and to permit persons to whom the
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Software is furnished to do so, subject to the following
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * conditions:
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync *
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * The above copyright notice and this permission notice shall be
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * included in all copies or substantial portions of the Software.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync *
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * OTHER DEALINGS IN THE SOFTWARE.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync/*******************************************************************************
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync* Header Files *
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync*******************************************************************************/
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync#include "the-os2-kernel.h"
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync#include <iprt/spinlock.h>
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync#include <iprt/err.h>
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync#include <iprt/alloc.h>
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync#include <iprt/assert.h>
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync#include <iprt/asm.h>
952b7cf61c9fadf84688e753845fc54c20184389vboxsync#ifdef RT_STRICT
952b7cf61c9fadf84688e753845fc54c20184389vboxsync# include <iprt/asm-amd64-x86.h>
952b7cf61c9fadf84688e753845fc54c20184389vboxsync#endif
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync#include "internal/magics.h"
881b5ff6bc55e1fb0f4ef42f9782ccec79c0a138vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync/*******************************************************************************
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync* Structures and Typedefs *
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync*******************************************************************************/
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync/**
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Wrapper for the SpinLock_t type.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsynctypedef struct RTSPINLOCKINTERNAL
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync{
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync /** Spinlock magic value (RTSPINLOCK_MAGIC). */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync uint32_t volatile u32Magic;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync /** Spinlock creation flags. */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync uint32_t fFlags;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync /** The OS/2 spinlock structure. */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync SpinLock_t Spinlock;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsyncRTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName)
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync{
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync AssertReturn(fFlags == RTSPINLOCK_FLAGS_INTERRUPT_SAFE || fFlags == RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, VERR_INVALID_PARAMETER);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync /*
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Allocate.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync AssertCompile(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *));
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pThis));
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync if (!pThis)
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync return VERR_NO_MEMORY;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync /*
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Initialize & return.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync pThis->u32Magic = RTSPINLOCK_MAGIC;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync pThis->fFlags = fFlags;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync KernAllocSpinLock(&pThis->Spinlock);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync *pSpinlock = pThis;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync return VINF_SUCCESS;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync}
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsyncRTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync{
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync /*
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Validate input.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync if (!pThis)
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync return VERR_INVALID_PARAMETER;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync AssertMsgReturn(pThis->u32Magic == RTSPINLOCK_MAGIC,
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync ("Invalid spinlock %p magic=%#x\n", pThis, pThis->u32Magic),
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync VERR_INVALID_PARAMETER);
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync /*
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync * Make the lock invalid and release the memory.
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync ASMAtomicIncU32(&pThis->u32Magic);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync KernFreeSpinLock(&pThis->Spinlock);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync RTMemFree(pThis);
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync return VINF_SUCCESS;
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync}
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsyncRTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync{
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync AssertPtr(pThis);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync Assert(pThis->u32Magic == RTSPINLOCK_MAGIC);
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync KernAcquireSpinLock(&pThis->Spinlock);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync Assert(!ASMIntAreEnabled()); /** @todo verify that interrupts are disabled. */
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync}
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsyncRTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync{
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync AssertPtr(pThis);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync Assert(pThis->u32Magic == RTSPINLOCK_MAGIC);
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync KernReleaseSpinLock(&pThis->Spinlock);
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync}
d1c5a03c19683c719b94496bb998fde2f2e5e622vboxsync