VirtualBox

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

Last change on this file since 22892 was 20374, checked in by vboxsync, 16 years ago

*: s/RT_\(BEGIN|END\)_DECLS/RT_C_DECLS_\1/g

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