lockvalidator.h revision f0dd841cb99154da8ec0a31cae2f89044895a23f
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * IPRT - Lock Validator.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Copyright (C) 2009 Sun Microsystems, Inc.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * available from http://www.virtualbox.org. This file is free software;
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * General Public License (GPL) as published by the Free Software
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * The contents of this file may alternatively be used under the terms
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * of the Common Development and Distribution License Version 1.0
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * VirtualBox OSE distribution, in which case the provisions of the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * CDDL are applicable instead of those of the GPL.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * You may elect to license modified versions of this file under the
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * terms and conditions of either the GPL or the CDDL or both.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * additional information or have any questions.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/** @defgroup grp_ldr RTLockValidator - Lock Validator
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @ingroup grp_rt
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Record recording the ownership of a lock.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This is typically part of the per-lock data structure when compiling with
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * the lock validator.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** Magic value (RTLOCKVALIDATORREC_MAGIC). */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** The line number in the file. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** The file where the lock was taken. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** The function where the lock was taken. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** Some ID indicating where the lock was taken, typically an address. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** The current owner thread. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** Pointer to the lock record below us. Only accessed by the owner. */
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync /** Recursion count */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** The lock sub-class. */
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync /** The lock class. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** Pointer to the lock. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync /** The lock name. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncAssertCompileSize(RTLOCKVALIDATORREC, HC_ARCH_BITS == 32 ? 48 : 80);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/* The pointer is defined in iprt/types.h */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/** @name Special sub-class values.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * The range 16..UINT32_MAX is available to the user, the range 0..15 is
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * reserved for the lock validator.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/** Not allowed to be taken with any other locks in the same class.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This is the recommended value. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/** Any order is allowed within the class. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/** The first user value. */
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Initialize a lock validator record.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Use RTLockValidatorDelete to deinitialize it.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pRec The record.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param hClass The class. If NIL, the no lock order
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * validation will be performed on this lock.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param uSubClass The sub-class. This is used to define lock
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * order inside the same class. If you don't know,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * then pass RTLOCKVALIDATOR_SUB_CLASS_NONE.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pszName The lock name (optional).
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param hLock The lock handle.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncRTDECL(void) RTLockValidatorInit(PRTLOCKVALIDATORREC pRec, RTLOCKVALIDATORCLASS hClass,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync uint32_t uSubClass, const char *pszName, void *hLock);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Uninitialize a lock validator record previously initialized by
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * RTLockValidatorInit.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pRec The record. Must be valid.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncRTDECL(void) RTLockValidatorDelete(PRTLOCKVALIDATORREC pRec);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Create and initialize a lock validator record.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Use RTLockValidatorDestroy to deinitialize and destroy the returned record.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @return VINF_SUCCESS or VERR_NO_MEMORY.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param ppRec Where to return the record pointer.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param hClass The class. If NIL, the no lock order
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * validation will be performed on this lock.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param uSubClass The sub-class. This is used to define lock
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * order inside the same class. If you don't know,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * then pass RTLOCKVALIDATOR_SUB_CLASS_NONE.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pszName The lock name (optional).
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param hLock The lock handle.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncRTDECL(int) RTLockValidatorCreate(PRTLOCKVALIDATORREC *ppRec, RTLOCKVALIDATORCLASS hClass,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync uint32_t uSubClass, const char *pszName, void *hLock);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Deinitialize and destroy a record created by RTLockValidatorCreate.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param ppRec Pointer to the record pointer. Will be set to
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncRTDECL(void) RTLockValidatorDestroy(PRTLOCKVALIDATORREC *ppRec);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Check the locking order.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This is called by routines implementing lock acquisition.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @retval VINF_SUCCESS on success.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @retval VERR_DEADLOCK if the order is wrong, after having whined and
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * asserted.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pRec The validator record.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param hThread The handle of the calling thread. If not known,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * pass NIL_RTTHREAD and this method will figure it
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param uId Some kind of locking location ID. Typically a
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * return address up the stack. Optional (0).
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pszFile The file where the lock is being acquired from.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Optional.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param iLine The line number in that file. Optional (0).
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pszFunction The functionn where the lock is being acquired
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * from. Optional.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsyncRTDECL(int) RTLockValidatorCheckOrder(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL);
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * Change the thread state to blocking and do deadlock detection.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param pRec The validator record we're blocing on.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param hThread The current thread. Shall not be NIL_RTTHREAD!
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param enmState The sleep state.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param pvBlock Pointer to a RTLOCKVALIDATORREC structure.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param fRecursiveOk Whether it's ok to recurse.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param uId Where we are blocking.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsync * @param RT_SRC_POS_DECL Where we are blocking.
a2b66e2b8b92cf2d0706078798036035cb9fa94dvboxsyncRTDECL(void) RTLockValidatorCheckBlocking(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread,
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * Check the exit order.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * This is called by routines implementing lock acquisition.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @retval VINF_SUCCESS on success.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @retval VERR_DEADLOCK if the order is wrong, after having whined and
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * asserted.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @param pRec The validator record.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @param hThread The handle of the calling thread. If not known,
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * pass NIL_RTTHREAD and this method will figure it
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @param uId Some kind of locking location ID. Typically a
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * return address up the stack. Optional (0).
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @param pszFile The file where the lock is being acquired from.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * Optional.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @param iLine The line number in that file. Optional (0).
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * @param pszFunction The functionn where the lock is being acquired
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsync * from. Optional.
c68a3984216eaa85ae7144b3b0d9b168276dbcf3vboxsyncRTDECL(int) RTLockValidatorCheckReleaseOrder(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Record the specified thread as lock owner.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This is typically called after acquiring the lock.
04e639b004793691f051abcd5b3c811c6b6b6f86vboxsync * @returns hThread resolved. Can return NIL_RTHREAD iff we fail to adopt the
04e639b004793691f051abcd5b3c811c6b6b6f86vboxsync * alien thread or if pRec is invalid.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pRec The validator record.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param hThread The handle of the calling thread. If not known,
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * pass NIL_RTTHREAD and this method will figure it
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param uId Some kind of locking location ID. Typically a
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * return address up the stack. Optional (0).
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pszFile The file where the lock is being acquired from.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Optional.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param iLine The line number in that file. Optional (0).
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pszFunction The functionn where the lock is being acquired
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * from. Optional.
04e639b004793691f051abcd5b3c811c6b6b6f86vboxsyncRTDECL(RTTHREAD) RTLockValidatorSetOwner(PRTLOCKVALIDATORREC pRec, RTTHREAD hThread, RTHCUINTPTR uId, RT_SRC_POS_DECL);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * Clear the lock ownership.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * This is typically called before release the lock.
04e639b004793691f051abcd5b3c811c6b6b6f86vboxsync * @returns The thread handle of the previous owner. NIL_RTTHREAD if the record
04e639b004793691f051abcd5b3c811c6b6b6f86vboxsync * is invalid or didn't have any owner.
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync * @param pRec The validator record.
04e639b004793691f051abcd5b3c811c6b6b6f86vboxsyncRTDECL(RTTHREAD) RTLockValidatorUnsetOwner(PRTLOCKVALIDATORREC pRec);
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Gets the number of write locks and critical sections the specified
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * thread owns.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * This number does not include any nested lock/critect entries.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Note that it probably will return 0 for non-strict builds since
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * release builds doesn't do unnecessary diagnostic counting like this.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @returns Number of locks on success (0+) and VERR_INVALID_HANDLER on failure
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @param Thread The thread we're inquiring about.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @remarks Will only work for strict builds.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsyncRTDECL(int32_t) RTLockValidatorWriteLockGetCount(RTTHREAD Thread);
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Works the THREADINT::cWriteLocks member, mostly internal.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @param Thread The current thread.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsyncRTDECL(void) RTLockValidatorWriteLockInc(RTTHREAD Thread);
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Works the THREADINT::cWriteLocks member, mostly internal.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @param Thread The current thread.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsyncRTDECL(void) RTLockValidatorWriteLockDec(RTTHREAD Thread);
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Gets the number of read locks the specified thread owns.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Note that nesting read lock entry will be included in the
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * total sum. And that it probably will return 0 for non-strict
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * builds since release builds doesn't do unnecessary diagnostic
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * counting like this.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @returns Number of read locks on success (0+) and VERR_INVALID_HANDLER on failure
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @param Thread The thread we're inquiring about.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsyncRTDECL(int32_t) RTLockValidatorReadLockGetCount(RTTHREAD Thread);
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Works the THREADINT::cReadLocks member.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @param Thread The current thread.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsyncRTDECL(void) RTLockValidatorReadLockInc(RTTHREAD Thread);
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * Works the THREADINT::cReadLocks member.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsync * @param Thread The current thread.
f0dd841cb99154da8ec0a31cae2f89044895a23fvboxsyncRTDECL(void) RTLockValidatorReadLockDec(RTTHREAD Thread);
5d1fc7f6c660e826d7f81c580fbf4278dd44c6bdvboxsync/*RTDECL(int) RTLockValidatorClassCreate();*/