VirtualBox

source: vbox/trunk/include/iprt/critsect.h@ 5999

Last change on this file since 5999 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1/** @file
2 * innotek Portable Runtime - Critical Sections.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_critsect_h
27#define ___iprt_critsect_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31#ifdef IN_RING3
32#include <iprt/thread.h>
33#endif
34
35
36__BEGIN_DECLS
37
38/** @defgroup grp_rt_critsect RTCritSect - Critical Sections
39 * @ingroup grp_rt
40 * @{
41 */
42
43/**
44 * Critical section.
45 */
46typedef struct RTCRITSECT
47{
48 /** Magic used to validate the section state.
49 * RTCRITSECT_MAGIC is the value of an initialized & operational section. */
50 volatile uint32_t u32Magic;
51 /** Number of lockers.
52 * -1 if the section is free. */
53 volatile int32_t cLockers;
54 /** The owner thread. */
55 volatile RTNATIVETHREAD NativeThreadOwner;
56 /** Number of nested enter operations performed.
57 * Greater or equal to 1 if owned, 0 when free.
58 */
59 volatile int32_t cNestings;
60 /** Section flags - the RTCRITSECT_FLAGS_* \#defines. */
61 uint32_t fFlags;
62 /** The semaphore to wait for. */
63 RTSEMEVENT EventSem;
64
65 /** Data only used in strict mode for detecting and debugging deadlocks. */
66 struct RTCRITSECTSTRICT
67 {
68 /** Strict: The current owner thread. */
69 RTTHREAD volatile ThreadOwner;
70 /** Strict: Where the section was entered. */
71 R3PTRTYPE(const char * volatile) pszEnterFile;
72 /** Strict: Where the section was entered. */
73 uint32_t volatile u32EnterLine;
74#if HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64
75 /** Padding for correct alignment. */
76 uint32_t u32Padding;
77#endif
78 /** Strict: Where the section was entered. */
79 RTUINTPTR volatile uEnterId;
80 } Strict;
81} RTCRITSECT;
82/** Pointer to a critical section. */
83typedef RTCRITSECT *PRTCRITSECT;
84/** Pointer to a const critical section. */
85typedef const RTCRITSECT *PCRTCRITSECT;
86
87/** RTCRITSECT::u32Magic value. */
88#define RTCRITSECT_MAGIC 0x778899aa
89
90/** If set, nesting(/recursion) is not allowed. */
91#define RTCRITSECT_FLAGS_NO_NESTING 1
92
93#ifdef IN_RING3
94
95/**
96 * Initialize a critical section.
97 */
98RTDECL(int) RTCritSectInit(PRTCRITSECT pCritSect);
99
100/**
101 * Initialize a critical section.
102 *
103 * @returns iprt status code.
104 * @param pCritSect Pointer to the critical section structure.
105 * @param fFlags Flags, any combination of the RTCRITSECT_FLAGS \#defines.
106 */
107RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags);
108
109/**
110 * Enter a critical section.
111 *
112 * @returns VINF_SUCCESS on success.
113 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
114 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
115 * @param pCritSect The critical section.
116 */
117RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect);
118
119/**
120 * Enter a critical section.
121 *
122 * @returns VINF_SUCCESS on success.
123 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
124 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
125 * @param pCritSect The critical section.
126 * @param pszFile Where we're entering the section.
127 * @param uLine Where we're entering the section.
128 * @param uId Where we're entering the section.
129 */
130RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, const char *pszFile, unsigned uLine, RTUINTPTR uId);
131
132/* in debug mode we'll redefine the enter call. */
133#ifdef RT_STRICT
134# define RTCritSectEnter(pCritSect) RTCritSectEnterDebug(pCritSect, __FILE__, __LINE__, 0)
135#endif
136
137/**
138 * Try enter a critical section.
139 *
140 * @returns VINF_SUCCESS on success.
141 * @returns VERR_SEM_BUSY if the critsect was owned.
142 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
143 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
144 * @param pCritSect The critical section.
145 */
146RTDECL(int) RTCritSectTryEnter(PRTCRITSECT pCritSect);
147
148/**
149 * Try enter a critical section.
150 *
151 * @returns VINF_SUCCESS on success.
152 * @returns VERR_SEM_BUSY if the critsect was owned.
153 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
154 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
155 * @param pCritSect The critical section.
156 * @param pszFile Where we're entering the section.
157 * @param uLine Where we're entering the section.
158 * @param uId Where we're entering the section.
159 */
160RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, const char *pszFile, unsigned uLine, RTUINTPTR uId);
161
162/* in debug mode we'll redefine the try-enter call. */
163#ifdef RT_STRICT
164# define RTCritSectTryEnter(pCritSect) RTCritSectTryEnterDebug(pCritSect, __FILE__, __LINE__, 0)
165#endif
166
167/**
168 * Enter multiple critical sections.
169 *
170 * This function will enter ALL the specified critical sections before returning.
171 *
172 * @returns VINF_SUCCESS on success.
173 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
174 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
175 * @param cCritSects Number of critical sections in the array.
176 * @param papCritSects Array of critical section pointers.
177 *
178 * @remark Please note that this function will not necessarily come out favourable in a
179 * fight with other threads which are using the normal RTCritSectEnter() function.
180 * Therefore, avoid having to enter multiple critical sections!
181 */
182RTDECL(int) RTCritSectEnterMultiple(unsigned cCritSects, PRTCRITSECT *papCritSects);
183
184/**
185 * Enter multiple critical sections.
186 *
187 * This function will enter ALL the specified critical sections before returning.
188 *
189 * @returns VINF_SUCCESS on success.
190 * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
191 * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
192 *
193 * @param cCritSects Number of critical sections in the array.
194 * @param papCritSects Array of critical section pointers.
195 * @param pszFile Where we're entering the section.
196 * @param uLine Where we're entering the section.
197 * @param uId Where we're entering the section.
198 *
199 * @remark See RTCritSectEnterMultiple().
200 */
201RTDECL(int) RTCritSectEnterMultipleDebug(unsigned cCritSects, PRTCRITSECT *papCritSects, const char *pszFile, unsigned uLine, RTUINTPTR uId);
202
203/* in debug mode we'll redefine the enter-multiple call. */
204#ifdef RT_STRICT
205# define RTCritSectEnterMultiple(cCritSects, pCritSect) RTCritSectEnterMultipleDebug((cCritSects), (pCritSect), __FILE__, __LINE__, 0)
206#endif
207
208/**
209 * Leave a critical section.
210 *
211 * @returns VINF_SUCCESS.
212 * @param pCritSect The critical section.
213 */
214RTDECL(int) RTCritSectLeave(PRTCRITSECT pCritSect);
215
216/**
217 * Leave multiple critical sections.
218 *
219 * @returns VINF_SUCCESS.
220 * @param cCritSects Number of critical sections in the array.
221 * @param papCritSects Array of critical section pointers.
222 */
223RTDECL(int) RTCritSectLeaveMultiple(unsigned cCritSects, PRTCRITSECT *papCritSects);
224
225/**
226 * Deletes a critical section.
227 *
228 * @returns VINF_SUCCESS.
229 * @param pCritSect The critical section.
230 */
231RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect);
232
233
234/**
235 * Checks if a critical section is initialized or not.
236 *
237 * @returns true if initialized.
238 * @returns false if not initialized.
239 * @param pCritSect The critical section.
240 */
241DECLINLINE(bool) RTCritSectIsInitialized(PCRTCRITSECT pCritSect)
242{
243 return pCritSect->u32Magic == RTCRITSECT_MAGIC;
244}
245
246
247/**
248 * Checks the caller is the owner of the critical section.
249 *
250 * @returns true if owner.
251 * @returns false if not owner.
252 * @param pCritSect The critical section.
253 */
254DECLINLINE(bool) RTCritSectIsOwner(PCRTCRITSECT pCritSect)
255{
256 return pCritSect->NativeThreadOwner == RTThreadNativeSelf();
257}
258
259
260/**
261 * Checks the section is owned by anyone.
262 *
263 * @returns true if owned.
264 * @returns false if not owned.
265 * @param pCritSect The critical section.
266 */
267DECLINLINE(bool) RTCritSectIsOwned(PCRTCRITSECT pCritSect)
268{
269 return pCritSect->NativeThreadOwner != NIL_RTNATIVETHREAD;
270}
271
272
273/**
274 * Gets the thread id of the critical section owner.
275 *
276 * @returns Thread id of the owner thread if owned.
277 * @returns NIL_RTNATIVETHREAD is not owned.
278 * @param pCritSect The critical section.
279 */
280DECLINLINE(RTNATIVETHREAD) RTCritSectGetOwner(PCRTCRITSECT pCritSect)
281{
282 return pCritSect->NativeThreadOwner;
283}
284
285
286/**
287 * Gets the recursion depth.
288 *
289 * @returns The recursion depth.
290 * @param pCritSect The Critical section
291 */
292DECLINLINE(uint32_t) RTCritSectGetRecursion(PCRTCRITSECT pCritSect)
293{
294 return pCritSect->cNestings;
295}
296
297#endif /* IN_RING3 */
298/** @} */
299
300__END_DECLS
301
302#endif
303
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use