VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use