VirtualBox

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

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

Eliminated HCPTRTYPE and replaced with R3R0PTRTYPE where necessary.

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