VirtualBox

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

Last change on this file since 25299 was 25168, checked in by vboxsync, 15 years ago

IPRT: documentation

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