VirtualBox

root/trunk/include/iprt/critsect.h

Revision 8245, 9.7 kB (checked in by vboxsync, 7 months ago)

rebranding: IPRT files again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
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
40 __BEGIN_DECLS
41
42 /** @defgroup grp_rt_critsect       RTCritSect - Critical Sections
43  * @ingroup grp_rt
44  * @{
45  */
46
47 /**
48  * Critical section.
49  */
50 typedef 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. */
87 typedef RTCRITSECT *PRTCRITSECT;
88 /** Pointer to a const critical section. */
89 typedef 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  */
102 RTDECL(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  */
111 RTDECL(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  */
121 RTDECL(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  */
134 RTDECL(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  */
150 RTDECL(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  */
164 RTDECL(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  */
186 RTDECL(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  */
205 RTDECL(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  */
218 RTDECL(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  */
227 RTDECL(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  */
235 RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect);
236
237
238 /**
239  * Checks if a critical section is initialized or not.
240  *
241  * @returns true if initialized.
242  * @returns false if not initialized.
243  * @param   pCritSect   The critical section.
244  */
245 DECLINLINE(bool) RTCritSectIsInitialized(PCRTCRITSECT pCritSect)
246 {
247     return pCritSect->u32Magic == RTCRITSECT_MAGIC;
248 }
249
250
251 /**
252  * Checks the caller is the owner of the critical section.
253  *
254  * @returns true if owner.
255  * @returns false if not owner.
256  * @param   pCritSect   The critical section.
257  */
258 DECLINLINE(bool) RTCritSectIsOwner(PCRTCRITSECT pCritSect)
259 {
260     return pCritSect->NativeThreadOwner == RTThreadNativeSelf();
261 }
262
263
264 /**
265  * Checks the section is owned by anyone.
266  *
267  * @returns true if owned.
268  * @returns false if not owned.
269  * @param   pCritSect   The critical section.
270  */
271 DECLINLINE(bool) RTCritSectIsOwned(PCRTCRITSECT pCritSect)
272 {
273     return pCritSect->NativeThreadOwner != NIL_RTNATIVETHREAD;
274 }
275
276
277 /**
278  * Gets the thread id of the critical section owner.
279  *
280  * @returns Thread id of the owner thread if owned.
281  * @returns NIL_RTNATIVETHREAD is not owned.
282  * @param   pCritSect   The critical section.
283  */
284 DECLINLINE(RTNATIVETHREAD) RTCritSectGetOwner(PCRTCRITSECT pCritSect)
285 {
286     return pCritSect->NativeThreadOwner;
287 }
288
289
290 /**
291  * Gets the recursion depth.
292  *
293  * @returns The recursion depth.
294  * @param   pCritSect       The Critical section
295  */
296 DECLINLINE(uint32_t) RTCritSectGetRecursion(PCRTCRITSECT pCritSect)
297 {
298     return pCritSect->cNestings;
299 }
300
301 #endif /* IN_RING3 */
302 /** @} */
303
304 __END_DECLS
305
306 #endif
307
Note: See TracBrowser for help on using the browser.

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy