VirtualBox

source: vbox/trunk/src/VBox/Runtime/generic/spinlock-generic.cpp@ 29247

Last change on this file since 29247 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.1 KB
Line 
1/* $Id: spinlock-generic.cpp 28800 2010-04-27 08:22:32Z vboxsync $ */
2/** @file
3 * IPRT - Spinlock, generic implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Defined Constants And Macros *
30*******************************************************************************/
31/** @def RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
32 * Force cpu yields after spinning the number of times indicated by the define.
33 * If 0 we will spin forever. */
34#define RT_CFG_SPINLOCK_GENERIC_DO_SLEEP 100000
35
36
37/*******************************************************************************
38* Header Files *
39*******************************************************************************/
40#include <iprt/spinlock.h>
41#include "internal/iprt.h"
42
43#include <iprt/alloc.h>
44#include <iprt/asm.h>
45#include <iprt/err.h>
46#include <iprt/assert.h>
47#if RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
48# include <iprt/thread.h>
49#endif
50
51#include "internal/magics.h"
52
53
54/*******************************************************************************
55* Structures and Typedefs *
56*******************************************************************************/
57/**
58 * Generic spinlock structure.
59 */
60typedef struct RTSPINLOCKINTERNAL
61{
62 /** Spinlock magic value (RTSPINLOCK_MAGIC). */
63 uint32_t u32Magic;
64 /** The spinlock. */
65 uint32_t volatile fLocked;
66} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
67
68
69RTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock)
70{
71 /*
72 * Allocate.
73 */
74 PRTSPINLOCKINTERNAL pSpinlockInt;
75 pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pSpinlockInt));
76 if (!pSpinlockInt)
77 return VERR_NO_MEMORY;
78
79 /*
80 * Initialize and return.
81 */
82 pSpinlockInt->u32Magic = RTSPINLOCK_MAGIC;
83 ASMAtomicXchgU32(&pSpinlockInt->fLocked, 0);
84
85 *pSpinlock = pSpinlockInt;
86 return VINF_SUCCESS;
87}
88RT_EXPORT_SYMBOL(RTSpinlockCreate);
89
90
91RTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
92{
93 /*
94 * Validate input.
95 */
96 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
97 if (!pSpinlockInt)
98 return VERR_INVALID_PARAMETER;
99 if (pSpinlockInt->u32Magic != RTSPINLOCK_MAGIC)
100 {
101 AssertMsgFailed(("Invalid spinlock %p magic=%#x\n", pSpinlockInt, pSpinlockInt->u32Magic));
102 return VERR_INVALID_PARAMETER;
103 }
104
105 ASMAtomicIncU32(&pSpinlockInt->u32Magic);
106 RTMemFree(pSpinlockInt);
107 return VINF_SUCCESS;
108}
109RT_EXPORT_SYMBOL(RTSpinlockDestroy);
110
111
112RTDECL(void) RTSpinlockAcquireNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
113{
114 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
115 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
116 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
117
118 pTmp->uFlags = ASMGetFlags();
119#if RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
120 for (;;)
121 {
122 ASMIntDisable();
123 for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
124 if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
125 return;
126 RTThreadYield();
127 }
128#else
129 ASMIntDisable();
130 while (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
131 /*nothing */;
132#endif
133}
134RT_EXPORT_SYMBOL(RTSpinlockAcquireNoInts);
135
136
137RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
138{
139 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
140 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
141 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
142 NOREF(pSpinlockInt);
143
144 if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1))
145 AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt));
146 ASMSetFlags(pTmp->uFlags);
147}
148RT_EXPORT_SYMBOL(RTSpinlockReleaseNoInts);
149
150
151RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
152{
153 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
154 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
155 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
156 NOREF(pTmp);
157
158#if RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
159 for (;;)
160 {
161 for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
162 if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
163 return;
164 RTThreadYield();
165 }
166#else
167 while (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
168 /*nothing */;
169#endif
170}
171RT_EXPORT_SYMBOL(RTSpinlockAcquire);
172
173
174RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
175{
176 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
177 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
178 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
179 NOREF(pTmp);
180
181 if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1))
182 AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt));
183}
184RT_EXPORT_SYMBOL(RTSpinlockRelease);
185
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette