VirtualBox

source: vbox/trunk/include/iprt/lockvalidator.h@ 25671

Last change on this file since 25671 was 25645, checked in by vboxsync, 15 years ago

IPRT,DoxyFile.Core: Mopped up the errors in the IPRT doxygen run.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.2 KB
Line 
1/** @file
2 * IPRT - Lock Validator.
3 */
4
5/*
6 * Copyright (C) 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_lockvalidator_h
31#define ___iprt_lockvalidator_h
32
33#include <iprt/cdefs.h>
34#include <iprt/types.h>
35#include <iprt/assert.h>
36#include <iprt/thread.h>
37
38
39/** @defgroup grp_rtlockval RTLockValidator - Lock Validator
40 * @ingroup grp_rt
41 * @{
42 */
43
44RT_C_DECLS_BEGIN
45
46/** Pointer to a record union.
47 * @internal */
48typedef union RTLOCKVALRECUNION *PRTLOCKVALRECUNION;
49
50/**
51 * Source position.
52 */
53typedef struct RTLOCKVALSRCPOS
54{
55 /** The file where the lock was taken. */
56 R3R0PTRTYPE(const char * volatile) pszFile;
57 /** The function where the lock was taken. */
58 R3R0PTRTYPE(const char * volatile) pszFunction;
59 /** Some ID indicating where the lock was taken, typically an address. */
60 RTHCUINTPTR volatile uId;
61 /** The line number in the file. */
62 uint32_t volatile uLine;
63#if HC_ARCH_BITS == 64
64 uint32_t u32Padding; /**< Alignment padding. */
65#endif
66} RTLOCKVALSRCPOS;
67AssertCompileSize(RTLOCKVALSRCPOS, HC_ARCH_BITS == 32 ? 16 : 32);
68/* The pointer types are defined in iprt/types.h. */
69
70/** @def RTLOCKVALSRCPOS_INIT
71 * Initializer for a RTLOCKVALSRCPOS variable.
72 *
73 * @param pszFile The file name. Optional (NULL).
74 * @param uLine The line number in that file. Optional (0).
75 * @param pszFunction The function. Optional (NULL).
76 * @param uId Some location ID, normally the return address.
77 * Optional (NULL).
78 */
79#if HC_ARCH_BITS == 64
80# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
81 { (pszFile), (pszFunction), (uId), (uLine), 0 }
82#else
83# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
84 { (pszFile), (pszFunction), (uId), (uLine) }
85#endif
86
87/** @def RTLOCKVALSRCPOS_INIT_DEBUG_API
88 * Initializer for a RTLOCKVALSRCPOS variable in a typicial debug API
89 * variant. Assumes RT_SRC_POS_DECL and RTHCUINTPTR uId as arguments.
90 */
91#define RTLOCKVALSRCPOS_INIT_DEBUG_API() \
92 RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, uId)
93
94/** @def RTLOCKVALSRCPOS_INIT_NORMAL_API
95 * Initializer for a RTLOCKVALSRCPOS variable in a normal API
96 * variant. Assumes iprt/asm.h is included.
97 */
98#define RTLOCKVALSRCPOS_INIT_NORMAL_API() \
99 RTLOCKVALSRCPOS_INIT(__FILE__, __LINE__, __PRETTY_FUNCTION__, (uintptr_t)ASMReturnAddress())
100
101/** Pointer to a record of one ownership share. */
102typedef struct RTLOCKVALRECSHRD *PRTLOCKVALRECSHRD;
103
104
105/**
106 * Lock validator record core.
107 */
108typedef struct RTLOCKVALRECORE
109{
110 /** The magic value indicating the record type. */
111 uint32_t volatile u32Magic;
112} RTLOCKVALRECCORE;
113/** Pointer to a lock validator record core. */
114typedef RTLOCKVALRECCORE *PRTLOCKVALRECCORE;
115/** Pointer to a const lock validator record core. */
116typedef RTLOCKVALRECCORE const *PCRTLOCKVALRECCORE;
117
118
119/**
120 * Record recording the exclusive ownership of a lock.
121 *
122 * This is typically part of the per-lock data structure when compiling with
123 * the lock validator.
124 */
125typedef struct RTLOCKVALRECEXCL
126{
127 /** Record core with RTLOCKVALRECEXCL_MAGIC as the magic value. */
128 RTLOCKVALRECCORE Core;
129 /** Whether it's enabled or not. */
130 bool fEnabled;
131 /** Reserved. */
132 bool afReserved[3];
133 /** Source position where the lock was taken. */
134 RTLOCKVALSRCPOS SrcPos;
135 /** The current owner thread. */
136 RTTHREAD volatile hThread;
137 /** Pointer to the lock record below us. Only accessed by the owner. */
138 R3R0PTRTYPE(PRTLOCKVALRECUNION) pDown;
139 /** Recursion count */
140 uint32_t cRecursion;
141 /** The lock sub-class. */
142 uint32_t volatile uSubClass;
143 /** The lock class. */
144 RTLOCKVALIDATORCLASS hClass;
145 /** Pointer to the lock. */
146 RTHCPTR hLock;
147 /** The lock name. */
148 R3R0PTRTYPE(const char *) pszName;
149 /** Pointer to the next sibling record.
150 * This is used to find the read side of a read-write lock. */
151 R3R0PTRTYPE(PRTLOCKVALRECUNION) pSibling;
152} RTLOCKVALRECEXCL;
153AssertCompileSize(RTLOCKVALRECEXCL, HC_ARCH_BITS == 32 ? 8 + 16 + 32 : 8 + 32 + 56);
154/* The pointer type is defined in iprt/types.h. */
155
156/**
157 * For recording the one ownership share.
158 */
159typedef struct RTLOCKVALRECSHRDOWN
160{
161 /** Record core with RTLOCKVALRECSHRDOWN_MAGIC as the magic value. */
162 RTLOCKVALRECCORE Core;
163 /** Recursion count */
164 uint16_t cRecursion;
165 /** Static (true) or dynamic (false) allocated record. */
166 bool fStaticAlloc;
167 /** Reserved. */
168 bool fReserved;
169 /** The current owner thread. */
170 RTTHREAD volatile hThread;
171 /** Pointer to the lock record below us. Only accessed by the owner. */
172 R3R0PTRTYPE(PRTLOCKVALRECUNION) pDown;
173 /** Pointer back to the shared record. */
174 R3R0PTRTYPE(PRTLOCKVALRECSHRD) pSharedRec;
175#if HC_ARCH_BITS == 32
176 /** Reserved. */
177 RTHCPTR pvReserved;
178#endif
179 /** Source position where the lock was taken. */
180 RTLOCKVALSRCPOS SrcPos;
181} RTLOCKVALRECSHRDOWN;
182AssertCompileSize(RTLOCKVALRECSHRDOWN, HC_ARCH_BITS == 32 ? 24 + 16 : 32 + 32);
183/** Pointer to a RTLOCKVALRECSHRDOWN. */
184typedef RTLOCKVALRECSHRDOWN *PRTLOCKVALRECSHRDOWN;
185
186/**
187 * Record recording the shared ownership of a lock.
188 *
189 * This is typically part of the per-lock data structure when compiling with
190 * the lock validator.
191 */
192typedef struct RTLOCKVALRECSHRD
193{
194 /** Record core with RTLOCKVALRECSHRD_MAGIC as the magic value. */
195 RTLOCKVALRECCORE Core;
196 /** The lock sub-class. */
197 uint32_t volatile uSubClass;
198 /** The lock class. */
199 RTLOCKVALIDATORCLASS hClass;
200 /** Pointer to the lock. */
201 RTHCPTR hLock;
202 /** The lock name. */
203 R3R0PTRTYPE(const char *) pszName;
204 /** Pointer to the next sibling record.
205 * This is used to find the write side of a read-write lock. */
206 R3R0PTRTYPE(PRTLOCKVALRECUNION) pSibling;
207
208 /** The number of entries in the table.
209 * Updated before inserting and after removal. */
210 uint32_t volatile cEntries;
211 /** The index of the last entry (approximately). */
212 uint32_t volatile iLastEntry;
213 /** The max table size. */
214 uint32_t volatile cAllocated;
215 /** Set if the table is being reallocated, clear if not.
216 * This is used together with rtLockValidatorSerializeDetectionEnter to make
217 * sure there is exactly one thread doing the reallocation and that nobody is
218 * using the table at that point. */
219 bool volatile fReallocating;
220 /** Whether it's enabled or not. */
221 bool fEnabled;
222 /** Set if event semaphore signaller, clear if read-write semaphore. */
223 bool fSignaller;
224 /** Alignment padding. */
225 bool fPadding;
226 /** Pointer to a table containing pointers to records of all the owners. */
227 R3R0PTRTYPE(PRTLOCKVALRECSHRDOWN volatile *) papOwners;
228#if HC_ARCH_BITS == 32
229 /** Alignment padding. */
230 uint32_t u32Alignment;
231#endif
232} RTLOCKVALRECSHRD;
233AssertCompileSize(RTLOCKVALRECSHRD, HC_ARCH_BITS == 32 ? 24 + 20 + 4 : 40 + 24);
234
235
236/** @name Special sub-class values.
237 * The range 16..UINT32_MAX is available to the user, the range 0..15 is
238 * reserved for the lock validator.
239 * @{ */
240/** Not allowed to be taken with any other locks in the same class.
241 * This is the recommended value. */
242#define RTLOCKVALIDATOR_SUB_CLASS_NONE UINT32_C(0)
243/** Any order is allowed within the class. */
244#define RTLOCKVALIDATOR_SUB_CLASS_ANY UINT32_C(1)
245/** The first user value. */
246#define RTLOCKVALIDATOR_SUB_CLASS_USER UINT32_C(16)
247/** @} */
248
249/**
250 * Makes the two records siblings.
251 *
252 * @returns VINF_SUCCESS on success, VERR_SEM_LV_INVALID_PARAMETER if either of
253 * the records are invalid.
254 * @param pRec1 Record 1.
255 * @param pRec2 Record 2.
256 */
257RTDECL(int) RTLockValidatorRecMakeSiblings(PRTLOCKVALRECCORE pRec1, PRTLOCKVALRECCORE pRec2);
258
259/**
260 * Initialize a lock validator record.
261 *
262 * Use RTLockValidatorRecExclDelete to deinitialize it.
263 *
264 * @param pRec The record.
265 * @param hClass The class. If NIL, the no lock order
266 * validation will be performed on this lock.
267 * @param uSubClass The sub-class. This is used to define lock
268 * order inside the same class. If you don't know,
269 * then pass RTLOCKVALIDATOR_SUB_CLASS_NONE.
270 * @param pszName The lock name (optional).
271 * @param hLock The lock handle.
272 */
273RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALIDATORCLASS hClass,
274 uint32_t uSubClass, const char *pszName, void *hLock);
275/**
276 * Uninitialize a lock validator record previously initialized by
277 * RTLockRecValidatorInit.
278 *
279 * @param pRec The record. Must be valid.
280 */
281RTDECL(void) RTLockValidatorRecExclDelete(PRTLOCKVALRECEXCL pRec);
282
283/**
284 * Create and initialize a lock validator record.
285 *
286 * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
287 * record.
288 *
289 * @return VINF_SUCCESS or VERR_NO_MEMORY.
290 * @param ppRec Where to return the record pointer.
291 * @param hClass The class. If NIL, the no lock order
292 * validation will be performed on this lock.
293 * @param uSubClass The sub-class. This is used to define lock
294 * order inside the same class. If you don't know,
295 * then pass RTLOCKVALIDATOR_SUB_CLASS_NONE.
296 * @param pszName The lock name (optional).
297 * @param hLock The lock handle.
298 */
299RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALIDATORCLASS hClass,
300 uint32_t uSubClass, const char *pszName, void *hLock);
301
302/**
303 * Deinitialize and destroy a record created by RTLockValidatorRecExclCreate.
304 *
305 * @param ppRec Pointer to the record pointer. Will be set to
306 * NULL.
307 */
308RTDECL(void) RTLockValidatorRecExclDestroy(PRTLOCKVALRECEXCL *ppRec);
309
310/**
311 * Record the specified thread as lock owner and increment the write lock count.
312 *
313 * This function is typically called after acquiring the lock. It accounts for
314 * recursions so it can be used instead of RTLockValidatorRecExclRecursion. Use
315 * RTLockValidatorRecExclReleaseOwner to reverse the effect.
316 *
317 * @param pRec The validator record.
318 * @param hThreadSelf The handle of the calling thread. If not known,
319 * pass NIL_RTTHREAD and we'll figure it out.
320 * @param pSrcPos The source position of the lock operation.
321 * @param fFirstRecursion Set if it is the first recursion, clear if not
322 * sure.
323 */
324RTDECL(void) RTLockValidatorRecExclSetOwner(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
325 PCRTLOCKVALSRCPOS pSrcPos, bool fFirstRecursion);
326
327/**
328 * Check the exit order and release (unset) the ownership.
329 *
330 * This is called by routines implementing releasing an exclusive lock,
331 * typically before getting down to the final lock releaseing. Can be used for
332 * recursive releasing instead of RTLockValidatorRecExclUnwind.
333 *
334 * @retval VINF_SUCCESS on success.
335 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have
336 * done all necessary whining and breakpointing before returning.
337 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
338 *
339 * @param pRec The validator record.
340 * @param fFinalRecursion Set if it's the final recursion, clear if not
341 * sure.
342 */
343RTDECL(int) RTLockValidatorRecExclReleaseOwner(PRTLOCKVALRECEXCL pRec, bool fFinalRecursion);
344
345/**
346 * Clear the lock ownership and decrement the write lock count.
347 *
348 * This is only for special cases where we wish to drop lock validation
349 * recording. See RTLockValidatorRecExclCheckAndRelease.
350 *
351 * @param pRec The validator record.
352 */
353RTDECL(void) RTLockValidatorRecExclReleaseOwnerUnchecked(PRTLOCKVALRECEXCL pRec);
354
355/**
356 * Checks and records a lock recursion.
357 *
358 * @retval VINF_SUCCESS on success.
359 * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone
360 * thru the motions.
361 * @retval VERR_SEM_LV_WRONG_ORDER if the locking order is wrong. Gone thru
362 * the motions.
363 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
364 *
365 * @param pRec The validator record.
366 * @param pSrcPos The source position of the lock operation.
367 */
368RTDECL(int) RTLockValidatorRecExclRecursion(PRTLOCKVALRECEXCL pRec, PCRTLOCKVALSRCPOS pSrcPos);
369
370/**
371 * Checks and records a lock unwind (releasing one recursion).
372 *
373 * This should be coupled with called to RTLockValidatorRecExclRecursion.
374 *
375 * @retval VINF_SUCCESS on success.
376 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong. Gone
377 * thru the motions.
378 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
379 *
380 * @param pRec The validator record.
381 */
382RTDECL(int) RTLockValidatorRecExclUnwind(PRTLOCKVALRECEXCL pRec);
383
384/**
385 * Checks and records a mixed recursion.
386 *
387 * An example of a mixed recursion is a writer requesting read access to a
388 * SemRW.
389 *
390 * This should be coupled with called to RTLockValidatorRecExclUnwindMixed.
391 *
392 * @retval VINF_SUCCESS on success.
393 * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone
394 * thru the motions.
395 * @retval VERR_SEM_LV_WRONG_ORDER if the locking order is wrong. Gone thru
396 * the motions.
397 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
398 *
399 * @param pRec The validator record it to accounted it to.
400 * @param pRecMixed The validator record it came in on.
401 * @param pSrcPos The source position of the lock operation.
402 */
403RTDECL(int) RTLockValidatorRecExclRecursionMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed, PCRTLOCKVALSRCPOS pSrcPos);
404
405/**
406 * Checks and records the unwinding of a mixed recursion.
407 *
408 * This should be coupled with called to RTLockValidatorRecExclRecursionMixed.
409 *
410 * @retval VINF_SUCCESS on success.
411 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong. Gone
412 * thru the motions.
413 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
414 *
415 * @param pRec The validator record it was accounted to.
416 * @param pRecMixed The validator record it came in on.
417 */
418RTDECL(int) RTLockValidatorRecExclUnwindMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed);
419
420/**
421 * Check the exclusive locking order.
422 *
423 * This is called by routines implementing exclusive lock acquisition.
424 *
425 * @retval VINF_SUCCESS on success.
426 * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all
427 * necessary whining and breakpointing before returning.
428 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
429 *
430 * @param pRec The validator record.
431 * @param hThreadSelf The handle of the calling thread. If not known,
432 * pass NIL_RTTHREAD and we'll figure it out.
433 * @param pSrcPos The source position of the lock operation.
434 */
435RTDECL(int) RTLockValidatorRecExclCheckOrder(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf, PCRTLOCKVALSRCPOS pSrcPos);
436
437/**
438 * Do deadlock detection before blocking on exclusive access to a lock and
439 * change the thread state.
440 *
441 * @retval VINF_SUCCESS - thread is in the specified sleep state.
442 * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the
443 * motions.
444 * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
445 * already the owner. Gone thru the motions.
446 * @retval VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
447 * The caller must handle any legal upgrades without invoking this
448 * function (for now).
449 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
450 *
451 * @param pRec The validator record we're blocking on.
452 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
453 * @param pSrcPos The source position of the lock operation.
454 * @param fRecursiveOk Whether it's ok to recurse.
455 * @param enmSleepState The sleep state to enter on successful return.
456 * @param fReallySleeping Is it really going to sleep now or not. Use
457 * false before calls to other IPRT synchronization
458 * methods.
459 */
460RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
461 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
462 RTTHREADSTATE enmSleepState, bool fReallySleeping);
463
464/**
465 * RTLockValidatorRecExclCheckOrder and RTLockValidatorRecExclCheckBlocking
466 * baked into one call.
467 *
468 * @returns Any of the statuses returned by the two APIs.
469 * @param pRec The validator record.
470 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
471 * @param pSrcPos The source position of the lock operation.
472 * @param fRecursiveOk Whether it's ok to recurse.
473 * @param enmSleepState The sleep state to enter on successful return.
474 * @param fReallySleeping Is it really going to sleep now or not. Use
475 * false before calls to other IPRT synchronization
476 * methods.
477 */
478RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
479 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
480 RTTHREADSTATE enmSleepState, bool fReallySleeping);
481
482/**
483 * Initialize a lock validator record for a shared lock.
484 *
485 * Use RTLockValidatorRecSharedDelete to deinitialize it.
486 *
487 * @param pRec The shared lock record.
488 * @param hClass The class. If NIL, the no lock order
489 * validation will be performed on this lock.
490 * @param uSubClass The sub-class. This is used to define lock
491 * order inside the same class. If you don't know,
492 * then pass RTLOCKVALIDATOR_SUB_CLASS_NONE.
493 * @param pszName The lock name (optional).
494 * @param hLock The lock handle.
495 * @param fSignaller Set if event semaphore signaller logic should be
496 * applied to this record, clear if read-write
497 * semaphore logic should be used.
498 */
499RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALIDATORCLASS hClass, uint32_t uSubClass,
500 const char *pszName, void *hLock, bool fSignaller);
501/**
502 * Uninitialize a lock validator record previously initialized by
503 * RTLockValidatorRecSharedInit.
504 *
505 * @param pRec The shared lock record. Must be valid.
506 */
507RTDECL(void) RTLockValidatorRecSharedDelete(PRTLOCKVALRECSHRD pRec);
508
509/**
510 * Check the shared locking order.
511 *
512 * This is called by routines implementing shared lock acquisition.
513 *
514 * @retval VINF_SUCCESS on success.
515 * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all
516 * necessary whining and breakpointing before returning.
517 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
518 *
519 * @param pRec The validator record.
520 * @param hThreadSelf The handle of the calling thread. If not known,
521 * pass NIL_RTTHREAD and we'll figure it out.
522 * @param pSrcPos The source position of the lock operation.
523 */
524RTDECL(int) RTLockValidatorRecSharedCheckOrder(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf, PCRTLOCKVALSRCPOS pSrcPos);
525
526/**
527 * Do deadlock detection before blocking on shared access to a lock and change
528 * the thread state.
529 *
530 * @retval VINF_SUCCESS - thread is in the specified sleep state.
531 * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the
532 * motions.
533 * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
534 * already the owner. Gone thru the motions.
535 * @retval VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
536 * The caller must handle any legal upgrades without invoking this
537 * function (for now).
538 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
539 *
540 * @param pRec The validator record we're blocking on.
541 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
542 * @param pSrcPos The source position of the lock operation.
543 * @param fRecursiveOk Whether it's ok to recurse.
544 * @param enmSleepState The sleep state to enter on successful return.
545 * @param fReallySleeping Is it really going to sleep now or not. Use
546 * false before calls to other IPRT synchronization
547 * methods.
548 */
549RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
550 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
551 RTTHREADSTATE enmSleepState, bool fReallySleeping);
552
553/**
554 * RTLockValidatorRecSharedCheckOrder and RTLockValidatorRecSharedCheckBlocking
555 * baked into one call.
556 *
557 * @returns Any of the statuses returned by the two APIs.
558 * @param pRec The validator record.
559 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
560 * @param pSrcPos The source position of the lock operation.
561 * @param fRecursiveOk Whether it's ok to recurse.
562 * @param enmSleepState The sleep state to enter on successful return.
563 * @param fReallySleeping Is it really going to sleep now or not. Use
564 * false before calls to other IPRT synchronization
565 * methods.
566 */
567RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
568 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
569 RTTHREADSTATE enmSleepState, bool fReallySleeping);
570
571/**
572 * Removes all current owners and makes hThread the only owner.
573 *
574 * @param pRec The validator record.
575 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
576 * an alias for the current thread.
577 * @param pSrcPos The source position of the lock operation.
578 */
579RTDECL(void) RTLockValidatorRecSharedResetOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
580
581/**
582 * Adds an owner to a shared locking record.
583 *
584 * Takes recursion into account. This function is typically called after
585 * acquiring the lock in shared mode.
586 *
587 * @param pRec The validator record.
588 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
589 * an alias for the current thread.
590 * @param pSrcPos The source position of the lock operation.
591 */
592RTDECL(void) RTLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
593
594/**
595 * Removes an owner from a shared locking record.
596 *
597 * Takes recursion into account. This function is typically called before
598 * releaseing the lock.
599 *
600 * @param pRec The validator record.
601 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
602 * an alias for the current thread.
603 */
604RTDECL(void) RTLockValidatorRecSharedRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
605
606/**
607 * Check the exit order and release (unset) the shared ownership.
608 *
609 * This is called by routines implementing releasing the read/write lock.
610 *
611 * @retval VINF_SUCCESS on success.
612 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have
613 * done all necessary whining and breakpointing before returning.
614 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
615 *
616 * @param pRec The validator record.
617 * @param hThreadSelf The handle of the calling thread. NIL_RTTHREAD
618 * is an alias for the current thread.
619 */
620RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
621
622/**
623 * Check the signaller of an event.
624 *
625 * This is called by routines implementing releasing the event sempahore (both
626 * kinds).
627 *
628 * @retval VINF_SUCCESS on success.
629 * @retval VERR_SEM_LV_NOT_SIGNALLER if the thread is not in the record. Will
630 * have done all necessary whining and breakpointing before returning.
631 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
632 *
633 * @param pRec The validator record.
634 * @param hThreadSelf The handle of the calling thread. NIL_RTTHREAD
635 * is an alias for the current thread.
636 */
637RTDECL(int) RTLockValidatorRecSharedCheckSignaller(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
638
639/**
640 * Gets the number of write locks and critical sections the specified
641 * thread owns.
642 *
643 * This number does not include any nested lock/critect entries.
644 *
645 * Note that it probably will return 0 for non-strict builds since
646 * release builds doesn't do unnecessary diagnostic counting like this.
647 *
648 * @returns Number of locks on success (0+) and VERR_INVALID_HANDLER on failure
649 * @param Thread The thread we're inquiring about.
650 * @remarks Will only work for strict builds.
651 */
652RTDECL(int32_t) RTLockValidatorWriteLockGetCount(RTTHREAD Thread);
653
654/**
655 * Works the THREADINT::cWriteLocks member, mostly internal.
656 *
657 * @param Thread The current thread.
658 */
659RTDECL(void) RTLockValidatorWriteLockInc(RTTHREAD Thread);
660
661/**
662 * Works the THREADINT::cWriteLocks member, mostly internal.
663 *
664 * @param Thread The current thread.
665 */
666RTDECL(void) RTLockValidatorWriteLockDec(RTTHREAD Thread);
667
668/**
669 * Gets the number of read locks the specified thread owns.
670 *
671 * Note that nesting read lock entry will be included in the
672 * total sum. And that it probably will return 0 for non-strict
673 * builds since release builds doesn't do unnecessary diagnostic
674 * counting like this.
675 *
676 * @returns Number of read locks on success (0+) and VERR_INVALID_HANDLER on failure
677 * @param Thread The thread we're inquiring about.
678 */
679RTDECL(int32_t) RTLockValidatorReadLockGetCount(RTTHREAD Thread);
680
681/**
682 * Works the THREADINT::cReadLocks member.
683 *
684 * @param Thread The current thread.
685 */
686RTDECL(void) RTLockValidatorReadLockInc(RTTHREAD Thread);
687
688/**
689 * Works the THREADINT::cReadLocks member.
690 *
691 * @param Thread The current thread.
692 */
693RTDECL(void) RTLockValidatorReadLockDec(RTTHREAD Thread);
694
695/**
696 * Query which lock the specified thread is waiting on.
697 *
698 * @returns The lock handle value or NULL.
699 * @param hThread The thread in question.
700 */
701RTDECL(void *) RTLockValidatorQueryBlocking(RTTHREAD hThread);
702
703/**
704 * Checks if the thread is running in the lock validator after it has entered a
705 * block state.
706 *
707 * @returns true if it is, false if it isn't.
708 * @param hThread The thread in question.
709 */
710RTDECL(bool) RTLockValidatorIsBlockedThreadInValidator(RTTHREAD hThread);
711
712
713/*RTDECL(int) RTLockValidatorClassCreate();*/
714
715
716
717/**
718 * Enables / disables the lock validator for new locks.
719 *
720 * @returns The old setting.
721 * @param fEnabled The new setting.
722 */
723RTDECL(bool) RTLockValidatorSetEnabled(bool fEnabled);
724
725/**
726 * Is the lock validator enabled?
727 *
728 * @returns True if enabled, false if not.
729 */
730RTDECL(bool) RTLockValidatorIsEnabled(void);
731
732/**
733 * Controls whether the lock validator should be quiet or noisy (default).
734 *
735 * @returns The old setting.
736 * @param fQuiet The new setting.
737 */
738RTDECL(bool) RTLockValidatorSetQuiet(bool fQuiet);
739
740/**
741 * Is the lock validator quiet or noisy?
742 *
743 * @returns True if it is quiet, false if noisy.
744 */
745RTDECL(bool) RTLockValidatorAreQuiet(void);
746
747/**
748 * Makes the lock validator panic (default) or not.
749 *
750 * @returns The old setting.
751 * @param fPanic The new setting.
752 */
753RTDECL(bool) RTLockValidatorSetMayPanic(bool fPanic);
754
755/**
756 * Can the lock validator cause panic.
757 *
758 * @returns True if it can, false if not.
759 */
760RTDECL(bool) RTLockValidatorMayPanic(void);
761
762
763RT_C_DECLS_END
764
765/** @} */
766
767#endif
768
769
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette