VirtualBox

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

Last change on this file since 204 was 1, checked in by vboxsync, 55 years ago

import

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