VirtualBox

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

Last change on this file since 28112 was 21337, checked in by vboxsync, 15 years ago

IPRT,HostDrv,AddDrv: Export public IPRT symbols for the linux kernel (pain).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.3 KB
Line 
1/* $Id: spinlock-generic.cpp 21337 2009-07-07 14:58:27Z vboxsync $ */
2/** @file
3 * IPRT - Spinlock, generic implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Defined Constants And Macros *
34*******************************************************************************/
35/** @def RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
36 * Force cpu yields after spinning the number of times indicated by the define.
37 * If 0 we will spin forever. */
38#define RT_CFG_SPINLOCK_GENERIC_DO_SLEEP 100000
39
40
41/*******************************************************************************
42* Header Files *
43*******************************************************************************/
44#include <iprt/spinlock.h>
45#include "internal/iprt.h"
46
47#include <iprt/alloc.h>
48#include <iprt/asm.h>
49#include <iprt/err.h>
50#include <iprt/assert.h>
51#if RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
52# include <iprt/thread.h>
53#endif
54
55#include "internal/magics.h"
56
57
58/*******************************************************************************
59* Structures and Typedefs *
60*******************************************************************************/
61/**
62 * Generic spinlock structure.
63 */
64typedef struct RTSPINLOCKINTERNAL
65{
66 /** Spinlock magic value (RTSPINLOCK_MAGIC). */
67 uint32_t u32Magic;
68 /** The spinlock. */
69 uint32_t volatile fLocked;
70} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
71
72
73RTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock)
74{
75 /*
76 * Allocate.
77 */
78 PRTSPINLOCKINTERNAL pSpinlockInt;
79 pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pSpinlockInt));
80 if (!pSpinlockInt)
81 return VERR_NO_MEMORY;
82
83 /*
84 * Initialize and return.
85 */
86 pSpinlockInt->u32Magic = RTSPINLOCK_MAGIC;
87 ASMAtomicXchgU32(&pSpinlockInt->fLocked, 0);
88
89 *pSpinlock = pSpinlockInt;
90 return VINF_SUCCESS;
91}
92RT_EXPORT_SYMBOL(RTSpinlockCreate);
93
94
95RTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
96{
97 /*
98 * Validate input.
99 */
100 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
101 if (!pSpinlockInt)
102 return VERR_INVALID_PARAMETER;
103 if (pSpinlockInt->u32Magic != RTSPINLOCK_MAGIC)
104 {
105 AssertMsgFailed(("Invalid spinlock %p magic=%#x\n", pSpinlockInt, pSpinlockInt->u32Magic));
106 return VERR_INVALID_PARAMETER;
107 }
108
109 ASMAtomicIncU32(&pSpinlockInt->u32Magic);
110 RTMemFree(pSpinlockInt);
111 return VINF_SUCCESS;
112}
113RT_EXPORT_SYMBOL(RTSpinlockDestroy);
114
115
116RTDECL(void) RTSpinlockAcquireNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
117{
118 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
119 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
120 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
121
122 pTmp->uFlags = ASMGetFlags();
123#if RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
124 for (;;)
125 {
126 ASMIntDisable();
127 for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
128 if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
129 return;
130 RTThreadYield();
131 }
132#else
133 ASMIntDisable();
134 while (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
135 /*nothing */;
136#endif
137}
138RT_EXPORT_SYMBOL(RTSpinlockAcquireNoInts);
139
140
141RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
142{
143 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
144 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
145 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
146 NOREF(pSpinlockInt);
147
148 if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1))
149 AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt));
150 ASMSetFlags(pTmp->uFlags);
151}
152RT_EXPORT_SYMBOL(RTSpinlockReleaseNoInts);
153
154
155RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
156{
157 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
158 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
159 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
160 NOREF(pTmp);
161
162#if RT_CFG_SPINLOCK_GENERIC_DO_SLEEP
163 for (;;)
164 {
165 for (int c = RT_CFG_SPINLOCK_GENERIC_DO_SLEEP; c > 0; c--)
166 if (ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
167 return;
168 RTThreadYield();
169 }
170#else
171 while (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 1, 0))
172 /*nothing */;
173#endif
174}
175RT_EXPORT_SYMBOL(RTSpinlockAcquire);
176
177
178RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock, PRTSPINLOCKTMP pTmp)
179{
180 PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
181 AssertMsg(pSpinlockInt && pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
182 ("pSpinlockInt=%p u32Magic=%08x\n", pSpinlockInt, pSpinlockInt ? (int)pSpinlockInt->u32Magic : 0));
183 NOREF(pTmp);
184
185 if (!ASMAtomicCmpXchgU32(&pSpinlockInt->fLocked, 0, 1))
186 AssertMsgFailed(("Spinlock %p was not locked!\n", pSpinlockInt));
187}
188RT_EXPORT_SYMBOL(RTSpinlockRelease);
189
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