VirtualBox

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

Last change on this file since 77807 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.2 KB
RevLine 
[25368]1/** @file
2 * IPRT - Lock Validator.
3 */
4
5/*
[76553]6 * Copyright (C) 2009-2019 Oracle Corporation
[25368]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
[76557]26#ifndef IPRT_INCLUDED_lockvalidator_h
27#define IPRT_INCLUDED_lockvalidator_h
[76507]28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
[25368]31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34#include <iprt/assert.h>
[25406]35#include <iprt/thread.h>
[25700]36#include <iprt/stdarg.h>
[25368]37
38
[25645]39/** @defgroup grp_rtlockval RTLockValidator - Lock Validator
[25368]40 * @ingroup grp_rt
41 * @{
42 */
43
44RT_C_DECLS_BEGIN
45
[25602]46/** Pointer to a record union.
47 * @internal */
[25607]48typedef union RTLOCKVALRECUNION *PRTLOCKVALRECUNION;
[25602]49
50/**
51 * Source position.
52 */
[25607]53typedef struct RTLOCKVALSRCPOS
[25478]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
[25607]66} RTLOCKVALSRCPOS;
67AssertCompileSize(RTLOCKVALSRCPOS, HC_ARCH_BITS == 32 ? 16 : 32);
[25478]68/* The pointer types are defined in iprt/types.h. */
69
[25607]70/** @def RTLOCKVALSRCPOS_INIT
71 * Initializer for a RTLOCKVALSRCPOS variable.
[25478]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
[25607]80# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
[25478]81 { (pszFile), (pszFunction), (uId), (uLine), 0 }
82#else
[25607]83# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
[25478]84 { (pszFile), (pszFunction), (uId), (uLine) }
85#endif
86
[25607]87/** @def RTLOCKVALSRCPOS_INIT_DEBUG_API
88 * Initializer for a RTLOCKVALSRCPOS variable in a typicial debug API
[25478]89 * variant. Assumes RT_SRC_POS_DECL and RTHCUINTPTR uId as arguments.
90 */
[25607]91#define RTLOCKVALSRCPOS_INIT_DEBUG_API() \
92 RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, uId)
[25478]93
[25607]94/** @def RTLOCKVALSRCPOS_INIT_NORMAL_API
95 * Initializer for a RTLOCKVALSRCPOS variable in a normal API
[25478]96 * variant. Assumes iprt/asm.h is included.
97 */
[25607]98#define RTLOCKVALSRCPOS_INIT_NORMAL_API() \
99 RTLOCKVALSRCPOS_INIT(__FILE__, __LINE__, __PRETTY_FUNCTION__, (uintptr_t)ASMReturnAddress())
[25478]100
[25682]101/** @def RTLOCKVALSRCPOS_INIT_POS_NO_ID
102 * Initializer for a RTLOCKVALSRCPOS variable when no @c uId is present.
103 * Assumes iprt/asm.h is included.
104 */
105#define RTLOCKVALSRCPOS_INIT_POS_NO_ID() \
106 RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, (uintptr_t)ASMReturnAddress())
107
[25478]108
[25368]109/**
[25602]110 * Lock validator record core.
111 */
[25610]112typedef struct RTLOCKVALRECORE
[25602]113{
114 /** The magic value indicating the record type. */
[25610]115 uint32_t volatile u32Magic;
[25607]116} RTLOCKVALRECCORE;
[25602]117/** Pointer to a lock validator record core. */
[25607]118typedef RTLOCKVALRECCORE *PRTLOCKVALRECCORE;
[25602]119/** Pointer to a const lock validator record core. */
[25607]120typedef RTLOCKVALRECCORE const *PCRTLOCKVALRECCORE;
[25602]121
122
123/**
[25607]124 * Record recording the exclusive ownership of a lock.
[25368]125 *
126 * This is typically part of the per-lock data structure when compiling with
127 * the lock validator.
128 */
[25607]129typedef struct RTLOCKVALRECEXCL
[25368]130{
[25607]131 /** Record core with RTLOCKVALRECEXCL_MAGIC as the magic value. */
132 RTLOCKVALRECCORE Core;
[25519]133 /** Whether it's enabled or not. */
134 bool fEnabled;
[25478]135 /** Reserved. */
[25519]136 bool afReserved[3];
[25478]137 /** Source position where the lock was taken. */
[25607]138 RTLOCKVALSRCPOS SrcPos;
[25368]139 /** The current owner thread. */
140 RTTHREAD volatile hThread;
141 /** Pointer to the lock record below us. Only accessed by the owner. */
[25607]142 R3R0PTRTYPE(PRTLOCKVALRECUNION) pDown;
[25406]143 /** Recursion count */
144 uint32_t cRecursion;
145 /** The lock sub-class. */
146 uint32_t volatile uSubClass;
[25368]147 /** The lock class. */
[25682]148 RTLOCKVALCLASS hClass;
[25368]149 /** Pointer to the lock. */
150 RTHCPTR hLock;
[25602]151 /** Pointer to the next sibling record.
[25570]152 * This is used to find the read side of a read-write lock. */
[25610]153 R3R0PTRTYPE(PRTLOCKVALRECUNION) pSibling;
[25704]154 /** The lock name.
155 * @remarks The bytes beyond 32 are for better size alignment and can be
156 * taken and used for other purposes if it becomes necessary. */
157 char szName[32 + (HC_ARCH_BITS == 32 ? 12 : 8)];
[25607]158} RTLOCKVALRECEXCL;
[25704]159AssertCompileSize(RTLOCKVALRECEXCL, HC_ARCH_BITS == 32 ? 0x60 : 0x80);
[25478]160/* The pointer type is defined in iprt/types.h. */
[25368]161
[25478]162/**
163 * For recording the one ownership share.
164 */
[25607]165typedef struct RTLOCKVALRECSHRDOWN
[25478]166{
[25607]167 /** Record core with RTLOCKVALRECSHRDOWN_MAGIC as the magic value. */
168 RTLOCKVALRECCORE Core;
[25478]169 /** Recursion count */
[25610]170 uint16_t cRecursion;
171 /** Static (true) or dynamic (false) allocated record. */
172 bool fStaticAlloc;
173 /** Reserved. */
174 bool fReserved;
[25478]175 /** The current owner thread. */
[25508]176 RTTHREAD volatile hThread;
[25478]177 /** Pointer to the lock record below us. Only accessed by the owner. */
[25607]178 R3R0PTRTYPE(PRTLOCKVALRECUNION) pDown;
[25478]179 /** Pointer back to the shared record. */
[25607]180 R3R0PTRTYPE(PRTLOCKVALRECSHRD) pSharedRec;
[25478]181#if HC_ARCH_BITS == 32
182 /** Reserved. */
[25508]183 RTHCPTR pvReserved;
[25478]184#endif
185 /** Source position where the lock was taken. */
[25607]186 RTLOCKVALSRCPOS SrcPos;
187} RTLOCKVALRECSHRDOWN;
188AssertCompileSize(RTLOCKVALRECSHRDOWN, HC_ARCH_BITS == 32 ? 24 + 16 : 32 + 32);
189/** Pointer to a RTLOCKVALRECSHRDOWN. */
190typedef RTLOCKVALRECSHRDOWN *PRTLOCKVALRECSHRDOWN;
[25368]191
[25478]192/**
193 * Record recording the shared ownership of a lock.
194 *
195 * This is typically part of the per-lock data structure when compiling with
196 * the lock validator.
197 */
[25607]198typedef struct RTLOCKVALRECSHRD
[25478]199{
[25607]200 /** Record core with RTLOCKVALRECSHRD_MAGIC as the magic value. */
201 RTLOCKVALRECCORE Core;
[25478]202 /** The lock sub-class. */
203 uint32_t volatile uSubClass;
204 /** The lock class. */
[25682]205 RTLOCKVALCLASS hClass;
[25478]206 /** Pointer to the lock. */
207 RTHCPTR hLock;
[25602]208 /** Pointer to the next sibling record.
[25570]209 * This is used to find the write side of a read-write lock. */
[25607]210 R3R0PTRTYPE(PRTLOCKVALRECUNION) pSibling;
[25478]211
212 /** The number of entries in the table.
213 * Updated before inserting and after removal. */
214 uint32_t volatile cEntries;
215 /** The index of the last entry (approximately). */
216 uint32_t volatile iLastEntry;
217 /** The max table size. */
218 uint32_t volatile cAllocated;
219 /** Set if the table is being reallocated, clear if not.
220 * This is used together with rtLockValidatorSerializeDetectionEnter to make
221 * sure there is exactly one thread doing the reallocation and that nobody is
222 * using the table at that point. */
223 bool volatile fReallocating;
[25519]224 /** Whether it's enabled or not. */
225 bool fEnabled;
[25638]226 /** Set if event semaphore signaller, clear if read-write semaphore. */
227 bool fSignaller;
[25478]228 /** Alignment padding. */
[25638]229 bool fPadding;
[25478]230 /** Pointer to a table containing pointers to records of all the owners. */
[25607]231 R3R0PTRTYPE(PRTLOCKVALRECSHRDOWN volatile *) papOwners;
[25704]232
233 /** The lock name.
234 * @remarks The bytes beyond 32 are for better size alignment and can be
235 * taken and used for other purposes if it becomes necessary. */
236 char szName[32 + (HC_ARCH_BITS == 32 ? 8 : 8)];
[25607]237} RTLOCKVALRECSHRD;
[25704]238AssertCompileSize(RTLOCKVALRECSHRD, HC_ARCH_BITS == 32 ? 0x50 : 0x60);
[25478]239
240
[25368]241/**
[25614]242 * Makes the two records siblings.
243 *
244 * @returns VINF_SUCCESS on success, VERR_SEM_LV_INVALID_PARAMETER if either of
245 * the records are invalid.
246 * @param pRec1 Record 1.
247 * @param pRec2 Record 2.
248 */
249RTDECL(int) RTLockValidatorRecMakeSiblings(PRTLOCKVALRECCORE pRec1, PRTLOCKVALRECCORE pRec2);
250
251/**
[25368]252 * Initialize a lock validator record.
253 *
[25607]254 * Use RTLockValidatorRecExclDelete to deinitialize it.
[25368]255 *
256 * @param pRec The record.
[25682]257 * @param hClass The class (no reference consumed). If NIL, the
258 * no lock order validation will be performed on
259 * this lock.
[25368]260 * @param uSubClass The sub-class. This is used to define lock
261 * order inside the same class. If you don't know,
[25682]262 * then pass RTLOCKVAL_SUB_CLASS_NONE.
[25368]263 * @param hLock The lock handle.
[25685]264 * @param fEnabled Pass @c false to explicitly disable lock
265 * validation, otherwise @c true.
[25704]266 * @param pszNameFmt Name format string for the lock validator,
267 * optional (NULL). Max length is 32 bytes.
268 * @param ... Format string arguments.
[25368]269 */
[57004]270RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
271 bool fEnabled, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
[25368]272/**
[25704]273 * Initialize a lock validator record.
274 *
275 * Use RTLockValidatorRecExclDelete to deinitialize it.
276 *
277 * @param pRec The record.
278 * @param hClass The class (no reference consumed). If NIL, the
279 * no lock order validation will be performed on
280 * this lock.
281 * @param uSubClass The sub-class. This is used to define lock
282 * order inside the same class. If you don't know,
283 * then pass RTLOCKVAL_SUB_CLASS_NONE.
284 * @param hLock The lock handle.
285 * @param fEnabled Pass @c false to explicitly disable lock
286 * validation, otherwise @c true.
287 * @param pszNameFmt Name format string for the lock validator,
288 * optional (NULL). Max length is 32 bytes.
289 * @param va Format string arguments.
290 */
[57004]291RTDECL(void) RTLockValidatorRecExclInitV(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
292 bool fEnabled, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 0);
[25704]293/**
[25368]294 * Uninitialize a lock validator record previously initialized by
[25491]295 * RTLockRecValidatorInit.
[25368]296 *
297 * @param pRec The record. Must be valid.
298 */
[25607]299RTDECL(void) RTLockValidatorRecExclDelete(PRTLOCKVALRECEXCL pRec);
[25368]300
301/**
302 * Create and initialize a lock validator record.
303 *
[25607]304 * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
[25491]305 * record.
[25368]306 *
307 * @return VINF_SUCCESS or VERR_NO_MEMORY.
308 * @param ppRec Where to return the record pointer.
[25682]309 * @param hClass The class (no reference consumed). If NIL, the
310 * no lock order validation will be performed on
311 * this lock.
[25368]312 * @param uSubClass The sub-class. This is used to define lock
313 * order inside the same class. If you don't know,
[25682]314 * then pass RTLOCKVAL_SUB_CLASS_NONE.
[25368]315 * @param hLock The lock handle.
[25685]316 * @param fEnabled Pass @c false to explicitly disable lock
317 * validation, otherwise @c true.
[25704]318 * @param pszNameFmt Name format string for the lock validator,
319 * optional (NULL). Max length is 32 bytes.
320 * @param ... Format string arguments.
[25368]321 */
[57004]322RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
323 bool fEnabled, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
[25368]324
325/**
[25704]326 * Create and initialize a lock validator record.
327 *
328 * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
329 * record.
330 *
331 * @return VINF_SUCCESS or VERR_NO_MEMORY.
332 * @param ppRec Where to return the record pointer.
333 * @param hClass The class (no reference consumed). If NIL, the
334 * no lock order validation will be performed on
335 * this lock.
336 * @param uSubClass The sub-class. This is used to define lock
337 * order inside the same class. If you don't know,
338 * then pass RTLOCKVAL_SUB_CLASS_NONE.
339 * @param hLock The lock handle.
340 * @param fEnabled Pass @c false to explicitly disable lock
341 * validation, otherwise @c true.
342 * @param pszNameFmt Name format string for the lock validator,
343 * optional (NULL). Max length is 32 bytes.
344 * @param va Format string arguments.
345 */
[57004]346RTDECL(int) RTLockValidatorRecExclCreateV(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass, void *hLock,
347 bool fEnabled, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 0);
[25704]348
349/**
[25607]350 * Deinitialize and destroy a record created by RTLockValidatorRecExclCreate.
[25368]351 *
352 * @param ppRec Pointer to the record pointer. Will be set to
353 * NULL.
354 */
[25607]355RTDECL(void) RTLockValidatorRecExclDestroy(PRTLOCKVALRECEXCL *ppRec);
[25368]356
357/**
[25704]358 * Sets the sub-class of the record.
359 *
360 * It is recommended to try make sure that nobody is using this class while
361 * changing the value.
362 *
363 * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
364 * lock validator isn't compiled in or either of the parameters are
365 * invalid.
366 * @param pRec The validator record.
367 * @param uSubClass The new sub-class value.
368 */
369RTDECL(uint32_t) RTLockValidatorRecExclSetSubClass(PRTLOCKVALRECEXCL pRec, uint32_t uSubClass);
370
371/**
[25614]372 * Record the specified thread as lock owner and increment the write lock count.
[25491]373 *
[25614]374 * This function is typically called after acquiring the lock. It accounts for
375 * recursions so it can be used instead of RTLockValidatorRecExclRecursion. Use
376 * RTLockValidatorRecExclReleaseOwner to reverse the effect.
[25491]377 *
[25614]378 * @param pRec The validator record.
379 * @param hThreadSelf The handle of the calling thread. If not known,
380 * pass NIL_RTTHREAD and we'll figure it out.
381 * @param pSrcPos The source position of the lock operation.
382 * @param fFirstRecursion Set if it is the first recursion, clear if not
383 * sure.
[25491]384 */
[25614]385RTDECL(void) RTLockValidatorRecExclSetOwner(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
386 PCRTLOCKVALSRCPOS pSrcPos, bool fFirstRecursion);
387
[25491]388/**
[25614]389 * Check the exit order and release (unset) the ownership.
[25491]390 *
[25614]391 * This is called by routines implementing releasing an exclusive lock,
[33540]392 * typically before getting down to the final lock releasing. Can be used for
[25614]393 * recursive releasing instead of RTLockValidatorRecExclUnwind.
394 *
395 * @retval VINF_SUCCESS on success.
396 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have
397 * done all necessary whining and breakpointing before returning.
398 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
399 *
400 * @param pRec The validator record.
401 * @param fFinalRecursion Set if it's the final recursion, clear if not
402 * sure.
[25491]403 */
[25614]404RTDECL(int) RTLockValidatorRecExclReleaseOwner(PRTLOCKVALRECEXCL pRec, bool fFinalRecursion);
[25491]405
406/**
[25614]407 * Clear the lock ownership and decrement the write lock count.
[25570]408 *
[25614]409 * This is only for special cases where we wish to drop lock validation
410 * recording. See RTLockValidatorRecExclCheckAndRelease.
411 *
412 * @param pRec The validator record.
[25570]413 */
[25614]414RTDECL(void) RTLockValidatorRecExclReleaseOwnerUnchecked(PRTLOCKVALRECEXCL pRec);
[25570]415
416/**
[25614]417 * Checks and records a lock recursion.
[25368]418 *
419 * @retval VINF_SUCCESS on success.
[25614]420 * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone
421 * thru the motions.
422 * @retval VERR_SEM_LV_WRONG_ORDER if the locking order is wrong. Gone thru
423 * the motions.
[25467]424 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
[25368]425 *
426 * @param pRec The validator record.
[25478]427 * @param pSrcPos The source position of the lock operation.
[25368]428 */
[25614]429RTDECL(int) RTLockValidatorRecExclRecursion(PRTLOCKVALRECEXCL pRec, PCRTLOCKVALSRCPOS pSrcPos);
[25368]430
[25398]431/**
[25614]432 * Checks and records a lock unwind (releasing one recursion).
[25406]433 *
[25614]434 * This should be coupled with called to RTLockValidatorRecExclRecursion.
435 *
436 * @retval VINF_SUCCESS on success.
437 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong. Gone
438 * thru the motions.
[25467]439 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
440 *
[25614]441 * @param pRec The validator record.
[25406]442 */
[25614]443RTDECL(int) RTLockValidatorRecExclUnwind(PRTLOCKVALRECEXCL pRec);
[25406]444
445/**
[25614]446 * Checks and records a mixed recursion.
[25398]447 *
[25614]448 * An example of a mixed recursion is a writer requesting read access to a
449 * SemRW.
[25498]450 *
[25614]451 * This should be coupled with called to RTLockValidatorRecExclUnwindMixed.
[25498]452 *
[25614]453 * @retval VINF_SUCCESS on success.
454 * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone
455 * thru the motions.
456 * @retval VERR_SEM_LV_WRONG_ORDER if the locking order is wrong. Gone thru
457 * the motions.
[25498]458 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
459 *
[25614]460 * @param pRec The validator record it to accounted it to.
461 * @param pRecMixed The validator record it came in on.
[25498]462 * @param pSrcPos The source position of the lock operation.
463 */
[25614]464RTDECL(int) RTLockValidatorRecExclRecursionMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed, PCRTLOCKVALSRCPOS pSrcPos);
[25498]465
466/**
[25614]467 * Checks and records the unwinding of a mixed recursion.
[25498]468 *
[25614]469 * This should be coupled with called to RTLockValidatorRecExclRecursionMixed.
[25398]470 *
471 * @retval VINF_SUCCESS on success.
[25614]472 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong. Gone
473 * thru the motions.
[25467]474 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
[25398]475 *
[25614]476 * @param pRec The validator record it was accounted to.
477 * @param pRecMixed The validator record it came in on.
[25467]478 */
[25614]479RTDECL(int) RTLockValidatorRecExclUnwindMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed);
[25467]480
481/**
[25614]482 * Check the exclusive locking order.
[25498]483 *
[25614]484 * This is called by routines implementing exclusive lock acquisition.
[25498]485 *
486 * @retval VINF_SUCCESS on success.
[25614]487 * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all
488 * necessary whining and breakpointing before returning.
[25498]489 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
490 *
[25614]491 * @param pRec The validator record.
492 * @param hThreadSelf The handle of the calling thread. If not known,
493 * pass NIL_RTTHREAD and we'll figure it out.
494 * @param pSrcPos The source position of the lock operation.
[25685]495 * @param cMillies The timeout, in milliseconds.
[25498]496 */
[25685]497RTDECL(int) RTLockValidatorRecExclCheckOrder(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
498 PCRTLOCKVALSRCPOS pSrcPos, RTMSINTERVAL cMillies);
[25498]499
500/**
[25618]501 * Do deadlock detection before blocking on exclusive access to a lock and
502 * change the thread state.
[25467]503 *
[25618]504 * @retval VINF_SUCCESS - thread is in the specified sleep state.
[25614]505 * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the
506 * motions.
507 * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
508 * already the owner. Gone thru the motions.
509 * @retval VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
510 * The caller must handle any legal upgrades without invoking this
511 * function (for now).
[25467]512 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
513 *
[25614]514 * @param pRec The validator record we're blocking on.
515 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
[25478]516 * @param pSrcPos The source position of the lock operation.
[25614]517 * @param fRecursiveOk Whether it's ok to recurse.
[25685]518 * @param cMillies The timeout, in milliseconds.
[25618]519 * @param enmSleepState The sleep state to enter on successful return.
[25638]520 * @param fReallySleeping Is it really going to sleep now or not. Use
521 * false before calls to other IPRT synchronization
522 * methods.
[25398]523 */
[25614]524RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
[25685]525 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
[25638]526 RTTHREADSTATE enmSleepState, bool fReallySleeping);
[25368]527
[25467]528/**
[25614]529 * RTLockValidatorRecExclCheckOrder and RTLockValidatorRecExclCheckBlocking
530 * baked into one call.
[25467]531 *
[25614]532 * @returns Any of the statuses returned by the two APIs.
[25467]533 * @param pRec The validator record.
[25614]534 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
535 * @param pSrcPos The source position of the lock operation.
536 * @param fRecursiveOk Whether it's ok to recurse.
[25685]537 * @param cMillies The timeout, in milliseconds.
[25618]538 * @param enmSleepState The sleep state to enter on successful return.
[25638]539 * @param fReallySleeping Is it really going to sleep now or not. Use
540 * false before calls to other IPRT synchronization
541 * methods.
[25467]542 */
[25614]543RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
[25685]544 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
[25638]545 RTTHREADSTATE enmSleepState, bool fReallySleeping);
[25406]546
[25368]547/**
[25614]548 * Initialize a lock validator record for a shared lock.
[25498]549 *
[25614]550 * Use RTLockValidatorRecSharedDelete to deinitialize it.
[25498]551 *
[25614]552 * @param pRec The shared lock record.
[25682]553 * @param hClass The class (no reference consumed). If NIL, the
554 * no lock order validation will be performed on
555 * this lock.
[25614]556 * @param uSubClass The sub-class. This is used to define lock
557 * order inside the same class. If you don't know,
[25682]558 * then pass RTLOCKVAL_SUB_CLASS_NONE.
[25614]559 * @param hLock The lock handle.
[25638]560 * @param fSignaller Set if event semaphore signaller logic should be
561 * applied to this record, clear if read-write
562 * semaphore logic should be used.
[25685]563 * @param fEnabled Pass @c false to explicitly disable lock
564 * validation, otherwise @c true.
[25704]565 * @param pszNameFmt Name format string for the lock validator,
566 * optional (NULL). Max length is 32 bytes.
567 * @param ... Format string arguments.
[25614]568 */
[25682]569RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
[57004]570 void *hLock, bool fSignaller, bool fEnabled,
571 const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 8);
[45110]572
[25614]573/**
[25704]574 * Initialize a lock validator record for a shared lock.
575 *
576 * Use RTLockValidatorRecSharedDelete to deinitialize it.
577 *
578 * @param pRec The shared lock record.
579 * @param hClass The class (no reference consumed). If NIL, the
580 * no lock order validation will be performed on
581 * this lock.
582 * @param uSubClass The sub-class. This is used to define lock
583 * order inside the same class. If you don't know,
584 * then pass RTLOCKVAL_SUB_CLASS_NONE.
585 * @param hLock The lock handle.
586 * @param fSignaller Set if event semaphore signaller logic should be
587 * applied to this record, clear if read-write
588 * semaphore logic should be used.
589 * @param fEnabled Pass @c false to explicitly disable lock
590 * validation, otherwise @c true.
591 * @param pszNameFmt Name format string for the lock validator,
592 * optional (NULL). Max length is 32 bytes.
593 * @param va Format string arguments.
594 */
595RTDECL(void) RTLockValidatorRecSharedInitV(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
[57004]596 void *hLock, bool fSignaller, bool fEnabled,
597 const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 0);
[45110]598
[25704]599/**
[25614]600 * Uninitialize a lock validator record previously initialized by
601 * RTLockValidatorRecSharedInit.
[25498]602 *
[25614]603 * @param pRec The shared lock record. Must be valid.
[25498]604 */
[25614]605RTDECL(void) RTLockValidatorRecSharedDelete(PRTLOCKVALRECSHRD pRec);
[25498]606
607/**
[45110]608 * Create and initialize a lock validator record for a shared lock.
609 *
610 * Use RTLockValidatorRecSharedDestroy to deinitialize and destroy the returned
611 * record.
612 *
613 * @returns IPRT status code.
614 * @param ppRec Where to return the record pointer.
615 * @param hClass The class (no reference consumed). If NIL, the
616 * no lock order validation will be performed on
617 * this lock.
618 * @param uSubClass The sub-class. This is used to define lock
619 * order inside the same class. If you don't know,
620 * then pass RTLOCKVAL_SUB_CLASS_NONE.
621 * @param pvLock The lock handle or address.
622 * @param fSignaller Set if event semaphore signaller logic should be
623 * applied to this record, clear if read-write
624 * semaphore logic should be used.
625 * @param fEnabled Pass @c false to explicitly disable lock
626 * validation, otherwise @c true.
627 * @param pszNameFmt Name format string for the lock validator,
628 * optional (NULL). Max length is 32 bytes.
629 * @param ... Format string arguments.
630 */
631RTDECL(int) RTLockValidatorRecSharedCreate(PRTLOCKVALRECSHRD *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
[57004]632 void *pvLock, bool fSignaller, bool fEnabled,
633 const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 8);
[45110]634
635/**
636 * Create and initialize a lock validator record for a shared lock.
637 *
638 * Use RTLockValidatorRecSharedDestroy to deinitialize and destroy the returned
639 * record.
640 *
641 * @returns IPRT status code.
642 * @param ppRec Where to return the record pointer.
643 * @param hClass The class (no reference consumed). If NIL, the
644 * no lock order validation will be performed on
645 * this lock.
646 * @param uSubClass The sub-class. This is used to define lock
647 * order inside the same class. If you don't know,
648 * then pass RTLOCKVAL_SUB_CLASS_NONE.
649 * @param pvLock The lock handle or address.
650 * @param fSignaller Set if event semaphore signaller logic should be
651 * applied to this record, clear if read-write
652 * semaphore logic should be used.
653 * @param fEnabled Pass @c false to explicitly disable lock
654 * validation, otherwise @c true.
655 * @param pszNameFmt Name format string for the lock validator,
656 * optional (NULL). Max length is 32 bytes.
657 * @param va Format string arguments.
658 */
659RTDECL(int) RTLockValidatorRecSharedCreateV(PRTLOCKVALRECSHRD *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
[57004]660 void *pvLock, bool fSignaller, bool fEnabled,
661 const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(7, 0);
[45110]662
663/**
664 * Deinitialize and destroy a record created by RTLockValidatorRecSharedCreate.
665 *
666 * @param ppRec Pointer to the record pointer. Will be set to
667 * NULL.
668 */
669RTDECL(void) RTLockValidatorRecSharedDestroy(PRTLOCKVALRECSHRD *ppRec);
670
671/**
[25707]672 * Sets the sub-class of the record.
673 *
674 * It is recommended to try make sure that nobody is using this class while
675 * changing the value.
676 *
677 * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
678 * lock validator isn't compiled in or either of the parameters are
679 * invalid.
680 * @param pRec The validator record.
681 * @param uSubClass The new sub-class value.
682 */
683RTDECL(uint32_t) RTLockValidatorRecSharedSetSubClass(PRTLOCKVALRECSHRD pRec, uint32_t uSubClass);
684
685/**
[25614]686 * Check the shared locking order.
[25498]687 *
[25614]688 * This is called by routines implementing shared lock acquisition.
[25498]689 *
690 * @retval VINF_SUCCESS on success.
[25614]691 * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all
692 * necessary whining and breakpointing before returning.
[25498]693 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
694 *
[25614]695 * @param pRec The validator record.
696 * @param hThreadSelf The handle of the calling thread. If not known,
697 * pass NIL_RTTHREAD and we'll figure it out.
698 * @param pSrcPos The source position of the lock operation.
[57926]699 * @param cMillies Intended sleep time in milliseconds.
[25498]700 */
[25685]701RTDECL(int) RTLockValidatorRecSharedCheckOrder(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
702 PCRTLOCKVALSRCPOS pSrcPos, RTMSINTERVAL cMillies);
[25498]703
704/**
[25618]705 * Do deadlock detection before blocking on shared access to a lock and change
706 * the thread state.
[25368]707 *
[25618]708 * @retval VINF_SUCCESS - thread is in the specified sleep state.
[25614]709 * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the
710 * motions.
711 * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
712 * already the owner. Gone thru the motions.
713 * @retval VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
714 * The caller must handle any legal upgrades without invoking this
715 * function (for now).
716 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
[25368]717 *
[25614]718 * @param pRec The validator record we're blocking on.
719 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
[25478]720 * @param pSrcPos The source position of the lock operation.
[25614]721 * @param fRecursiveOk Whether it's ok to recurse.
[57926]722 * @param cMillies Intended sleep time in milliseconds.
[25618]723 * @param enmSleepState The sleep state to enter on successful return.
[25638]724 * @param fReallySleeping Is it really going to sleep now or not. Use
725 * false before calls to other IPRT synchronization
726 * methods.
[25368]727 */
[25614]728RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
[25685]729 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
[25638]730 RTTHREADSTATE enmSleepState, bool fReallySleeping);
[25368]731
732/**
[25614]733 * RTLockValidatorRecSharedCheckOrder and RTLockValidatorRecSharedCheckBlocking
734 * baked into one call.
[25368]735 *
[25614]736 * @returns Any of the statuses returned by the two APIs.
[25368]737 * @param pRec The validator record.
[25614]738 * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
739 * @param pSrcPos The source position of the lock operation.
740 * @param fRecursiveOk Whether it's ok to recurse.
[57926]741 * @param cMillies Intended sleep time in milliseconds.
[25638]742 * @param enmSleepState The sleep state to enter on successful return.
743 * @param fReallySleeping Is it really going to sleep now or not. Use
744 * false before calls to other IPRT synchronization
745 * methods.
[25368]746 */
[25614]747RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
[25685]748 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
[25638]749 RTTHREADSTATE enmSleepState, bool fReallySleeping);
[25368]750
[25569]751/**
[25638]752 * Removes all current owners and makes hThread the only owner.
753 *
[25645]754 * @param pRec The validator record.
[25638]755 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
756 * an alias for the current thread.
757 * @param pSrcPos The source position of the lock operation.
758 */
759RTDECL(void) RTLockValidatorRecSharedResetOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
760
761/**
[25569]762 * Adds an owner to a shared locking record.
763 *
764 * Takes recursion into account. This function is typically called after
[25614]765 * acquiring the lock in shared mode.
[25569]766 *
[25645]767 * @param pRec The validator record.
[25638]768 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
769 * an alias for the current thread.
[25569]770 * @param pSrcPos The source position of the lock operation.
771 */
[25638]772RTDECL(void) RTLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
[25569]773
774/**
775 * Removes an owner from a shared locking record.
776 *
777 * Takes recursion into account. This function is typically called before
[33540]778 * releasing the lock.
[25569]779 *
[25614]780 * @param pRec The validator record.
[25638]781 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
782 * an alias for the current thread.
[25614]783 */
[25638]784RTDECL(void) RTLockValidatorRecSharedRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
[25614]785
786/**
[25908]787 * Checks if the specified thread is one of the owners.
788 *
789 * @returns true if it is, false if not.
790 *
791 * @param pRec The validator record.
792 * @param hThread The thread handle of the owner. NIL_RTTHREAD is
793 * an alias for the current thread.
794 */
795RTDECL(bool) RTLockValidatorRecSharedIsOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
796
797/**
[25614]798 * Check the exit order and release (unset) the shared ownership.
799 *
800 * This is called by routines implementing releasing the read/write lock.
801 *
802 * @retval VINF_SUCCESS on success.
803 * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have
804 * done all necessary whining and breakpointing before returning.
805 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
806 *
[25638]807 * @param pRec The validator record.
808 * @param hThreadSelf The handle of the calling thread. NIL_RTTHREAD
809 * is an alias for the current thread.
[25569]810 */
[25614]811RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
[25498]812
[25409]813/**
[25638]814 * Check the signaller of an event.
815 *
[33540]816 * This is called by routines implementing releasing the event semaphore (both
[25638]817 * kinds).
818 *
819 * @retval VINF_SUCCESS on success.
820 * @retval VERR_SEM_LV_NOT_SIGNALLER if the thread is not in the record. Will
821 * have done all necessary whining and breakpointing before returning.
822 * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
823 *
824 * @param pRec The validator record.
825 * @param hThreadSelf The handle of the calling thread. NIL_RTTHREAD
826 * is an alias for the current thread.
827 */
828RTDECL(int) RTLockValidatorRecSharedCheckSignaller(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
829
830/**
[25409]831 * Gets the number of write locks and critical sections the specified
832 * thread owns.
833 *
834 * This number does not include any nested lock/critect entries.
835 *
836 * Note that it probably will return 0 for non-strict builds since
837 * release builds doesn't do unnecessary diagnostic counting like this.
838 *
839 * @returns Number of locks on success (0+) and VERR_INVALID_HANDLER on failure
840 * @param Thread The thread we're inquiring about.
841 * @remarks Will only work for strict builds.
842 */
843RTDECL(int32_t) RTLockValidatorWriteLockGetCount(RTTHREAD Thread);
[25368]844
[25409]845/**
846 * Works the THREADINT::cWriteLocks member, mostly internal.
847 *
848 * @param Thread The current thread.
849 */
850RTDECL(void) RTLockValidatorWriteLockInc(RTTHREAD Thread);
851
852/**
853 * Works the THREADINT::cWriteLocks member, mostly internal.
854 *
855 * @param Thread The current thread.
856 */
857RTDECL(void) RTLockValidatorWriteLockDec(RTTHREAD Thread);
858
859/**
860 * Gets the number of read locks the specified thread owns.
861 *
862 * Note that nesting read lock entry will be included in the
863 * total sum. And that it probably will return 0 for non-strict
864 * builds since release builds doesn't do unnecessary diagnostic
865 * counting like this.
866 *
867 * @returns Number of read locks on success (0+) and VERR_INVALID_HANDLER on failure
868 * @param Thread The thread we're inquiring about.
869 */
870RTDECL(int32_t) RTLockValidatorReadLockGetCount(RTTHREAD Thread);
871
872/**
873 * Works the THREADINT::cReadLocks member.
874 *
875 * @param Thread The current thread.
876 */
877RTDECL(void) RTLockValidatorReadLockInc(RTTHREAD Thread);
878
879/**
880 * Works the THREADINT::cReadLocks member.
881 *
882 * @param Thread The current thread.
883 */
884RTDECL(void) RTLockValidatorReadLockDec(RTTHREAD Thread);
885
[25617]886/**
887 * Query which lock the specified thread is waiting on.
888 *
889 * @returns The lock handle value or NULL.
890 * @param hThread The thread in question.
891 */
892RTDECL(void *) RTLockValidatorQueryBlocking(RTTHREAD hThread);
[25409]893
[25622]894/**
895 * Checks if the thread is running in the lock validator after it has entered a
896 * block state.
897 *
898 * @returns true if it is, false if it isn't.
899 * @param hThread The thread in question.
900 */
901RTDECL(bool) RTLockValidatorIsBlockedThreadInValidator(RTTHREAD hThread);
[25409]902
[28267]903/**
904 * Checks if the calling thread is holding a lock in the specified class.
905 *
906 * @returns true if it holds a lock in the specific class, false if it
907 * doesn't.
908 *
909 * @param hCurrentThread The current thread. Pass NIL_RTTHREAD if you're
910 * lazy.
911 * @param hClass The class.
912 */
913RTDECL(bool) RTLockValidatorHoldsLocksInClass(RTTHREAD hCurrentThread, RTLOCKVALCLASS hClass);
[25617]914
[28267]915/**
916 * Checks if the calling thread is holding a lock in the specified sub-class.
917 *
918 * @returns true if it holds a lock in the specific sub-class, false if it
919 * doesn't.
920 *
921 * @param hCurrentThread The current thread. Pass NIL_RTTHREAD if you're
922 * lazy.
923 * @param hClass The class.
924 * @param uSubClass The new sub-class value.
925 */
926RTDECL(bool) RTLockValidatorHoldsLocksInSubClass(RTTHREAD hCurrentThread, RTLOCKVALCLASS hClass, uint32_t uSubClass);
[25368]927
[28267]928
929
[25682]930/**
931 * Creates a new lock validator class, all properties specified.
932 *
933 * @returns IPRT status code
934 * @param phClass Where to return the class handle.
935 * @param pSrcPos The source position of the create call.
936 * @param fAutodidact Whether the class should be allowed to teach
937 * itself new locking order rules (true), or if the
938 * user will teach it all it needs to know (false).
[25685]939 * @param fRecursionOk Whether to allow lock recursion or not.
[25692]940 * @param fStrictReleaseOrder Enforce strict lock release order or not.
[25682]941 * @param cMsMinDeadlock Used to raise the sleep interval at which
942 * deadlock detection kicks in. Minimum is 1 ms,
943 * while RT_INDEFINITE_WAIT will disable it.
944 * @param cMsMinOrder Used to raise the sleep interval at which lock
945 * order validation kicks in. Minimum is 1 ms,
946 * while RT_INDEFINITE_WAIT will disable it.
[25700]947 * @param pszNameFmt Class name format string, optional (NULL). Max
948 * length is 32 bytes.
949 * @param ... Format string arguments.
[25685]950 *
951 * @remarks The properties can be modified after creation by the
952 * RTLockValidatorClassSet* methods.
[25682]953 */
954RTDECL(int) RTLockValidatorClassCreateEx(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos,
[25692]955 bool fAutodidact, bool fRecursionOk, bool fStrictReleaseOrder,
[25700]956 RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder,
[57004]957 const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 9);
[25406]958
[25682]959/**
[25700]960 * Creates a new lock validator class, all properties specified.
961 *
962 * @returns IPRT status code
963 * @param phClass Where to return the class handle.
964 * @param pSrcPos The source position of the create call.
965 * @param fAutodidact Whether the class should be allowed to teach
966 * itself new locking order rules (true), or if the
967 * user will teach it all it needs to know (false).
968 * @param fRecursionOk Whether to allow lock recursion or not.
969 * @param fStrictReleaseOrder Enforce strict lock release order or not.
970 * @param cMsMinDeadlock Used to raise the sleep interval at which
971 * deadlock detection kicks in. Minimum is 1 ms,
972 * while RT_INDEFINITE_WAIT will disable it.
973 * @param cMsMinOrder Used to raise the sleep interval at which lock
974 * order validation kicks in. Minimum is 1 ms,
975 * while RT_INDEFINITE_WAIT will disable it.
976 * @param pszNameFmt Class name format string, optional (NULL). Max
977 * length is 32 bytes.
978 * @param va Format string arguments.
979 *
980 * @remarks The properties can be modified after creation by the
981 * RTLockValidatorClassSet* methods.
982 */
983RTDECL(int) RTLockValidatorClassCreateExV(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos,
984 bool fAutodidact, bool fRecursionOk, bool fStrictReleaseOrder,
985 RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder,
[57004]986 const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(8, 0);
[25700]987
988/**
[25682]989 * Creates a new lock validator class.
990 *
991 * @returns IPRT status code
992 * @param phClass Where to return the class handle.
993 * @param fAutodidact Whether the class should be allowed to teach
994 * itself new locking order rules (true), or if the
995 * user will teach it all it needs to know (false).
[57926]996 * @param SRC_POS The source position where call is being made from.
997 * Use RT_SRC_POS when possible. Optional.
[25704]998 * @param pszNameFmt Class name format string, optional (NULL). Max
999 * length is 32 bytes.
1000 * @param ... Format string arguments.
[25682]1001 */
[57004]1002RTDECL(int) RTLockValidatorClassCreate(PRTLOCKVALCLASS phClass, bool fAutodidact, RT_SRC_POS_DECL,
1003 const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
[25519]1004
1005/**
[25748]1006 * Creates a new lock validator class with a reference that is consumed by the
1007 * first call to RTLockValidatorClassRetain.
1008 *
1009 * This is tailored for use in the parameter list of a semaphore constructor.
1010 *
1011 * @returns Class handle with a reference that is automatically consumed by the
1012 * first retainer. NIL_RTLOCKVALCLASS if we run into trouble.
1013 *
[57926]1014 * @param SRC_POS The source position where call is being made from.
1015 * Use RT_SRC_POS when possible. Optional.
[25748]1016 * @param pszNameFmt Class name format string, optional (NULL). Max
1017 * length is 32 bytes.
1018 * @param ... Format string arguments.
1019 */
[57004]1020RTDECL(RTLOCKVALCLASS) RTLockValidatorClassCreateUnique(RT_SRC_POS_DECL,
1021 const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(4, 5);
[25748]1022
1023/**
[25682]1024 * Finds a class for the specified source position.
1025 *
1026 * @returns A handle to the class (not retained!) or NIL_RTLOCKVALCLASS.
1027 * @param pSrcPos The source position.
1028 */
1029RTDECL(RTLOCKVALCLASS) RTLockValidatorClassFindForSrcPos(PRTLOCKVALSRCPOS pSrcPos);
1030
1031/**
1032 * Finds or creates a class given the source position.
1033 *
1034 * @returns Class handle (not retained!) or NIL_RTLOCKVALCLASS.
[57926]1035 * @param SRC_POS The source position where call is being made from.
1036 * Use RT_SRC_POS when possible. Optional.
[25732]1037 * @param pszNameFmt Class name format string, optional (NULL). Max
1038 * length is 32 bytes.
1039 * @param ... Format string arguments.
[25682]1040 */
[57004]1041RTDECL(RTLOCKVALCLASS) RTLockValidatorClassForSrcPos(RT_SRC_POS_DECL,
1042 const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(4, 5);
[25682]1043
1044/**
1045 * Retains a reference to a lock validator class.
1046 *
1047 * @returns New reference count; UINT32_MAX if the handle is invalid.
1048 * @param hClass Handle to the class.
1049 */
1050RTDECL(uint32_t) RTLockValidatorClassRetain(RTLOCKVALCLASS hClass);
1051
1052/**
1053 * Releases a reference to a lock validator class.
1054 *
[25703]1055 * @returns New reference count. 0 if hClass is NIL_RTLOCKVALCLASS. UINT32_MAX
1056 * if the handle is invalid.
[25682]1057 * @param hClass Handle to the class.
1058 */
1059RTDECL(uint32_t) RTLockValidatorClassRelease(RTLOCKVALCLASS hClass);
1060
1061/**
1062 * Teaches the class @a hClass that locks in the class @a hPriorClass can be
[57926]1063 * held when taking a lock of class @a hClass
[25682]1064 *
1065 * @returns IPRT status.
1066 * @param hClass Handle to the pupil class.
1067 * @param hPriorClass Handle to the class that can be held prior to
1068 * taking a lock in the pupil class. (No reference
1069 * is consumed.)
1070 */
1071RTDECL(int) RTLockValidatorClassAddPriorClass(RTLOCKVALCLASS hClass, RTLOCKVALCLASS hPriorClass);
1072
1073/**
[25703]1074 * Enables or disables the strict release order enforcing.
1075 *
1076 * @returns IPRT status.
1077 * @param hClass Handle to the class to change.
[57926]1078 * @param fEnabled Enable it (true) or disable it (false).
[25703]1079 */
1080RTDECL(int) RTLockValidatorClassEnforceStrictReleaseOrder(RTLOCKVALCLASS hClass, bool fEnabled);
1081
1082/**
[25519]1083 * Enables / disables the lock validator for new locks.
1084 *
1085 * @returns The old setting.
1086 * @param fEnabled The new setting.
1087 */
1088RTDECL(bool) RTLockValidatorSetEnabled(bool fEnabled);
1089
1090/**
1091 * Is the lock validator enabled?
1092 *
1093 * @returns True if enabled, false if not.
1094 */
1095RTDECL(bool) RTLockValidatorIsEnabled(void);
1096
[25602]1097/**
1098 * Controls whether the lock validator should be quiet or noisy (default).
1099 *
1100 * @returns The old setting.
1101 * @param fQuiet The new setting.
1102 */
1103RTDECL(bool) RTLockValidatorSetQuiet(bool fQuiet);
[25519]1104
[25602]1105/**
1106 * Is the lock validator quiet or noisy?
1107 *
1108 * @returns True if it is quiet, false if noisy.
1109 */
[25703]1110RTDECL(bool) RTLockValidatorIsQuiet(void);
[25602]1111
1112/**
1113 * Makes the lock validator panic (default) or not.
1114 *
1115 * @returns The old setting.
1116 * @param fPanic The new setting.
1117 */
1118RTDECL(bool) RTLockValidatorSetMayPanic(bool fPanic);
1119
1120/**
1121 * Can the lock validator cause panic.
1122 *
1123 * @returns True if it can, false if not.
1124 */
1125RTDECL(bool) RTLockValidatorMayPanic(void);
1126
1127
[25368]1128RT_C_DECLS_END
1129
1130/** @} */
1131
[76585]1132#endif /* !IPRT_INCLUDED_lockvalidator_h */
[25368]1133
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