Files @ d0a14f973771
Branch filter:

Location: vmkdrivers/BLD/build/HEADERS/vmkapi-current-all-public/vmkernel64/release/core/vmkapi_spinlock.h

unknown
ESXi-5.0-U1
/* **********************************************************
 * Copyright 2010 VMware, Inc.  All rights reserved.
 * **********************************************************/

/*
 * @VMKAPIMOD_LICENSE@
 */

/*
 ******************************************************************************
 * Spin Locks                                                            */ /**
 *
 * \addtogroup Core
 * @{
 * \defgroup SpinLocks Spin Locks
 * @{
 *
 ******************************************************************************
 */

#ifndef _VMKAPI_SPINLOCKS_H_
#define _VMKAPI_SPINLOCKS_H_

/** \cond never */
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
#error This vmkapi file should never be included directly but only via vmkapi.h
#endif
/** \endcond never */


/** Invalid lock handle */
#define VMK_LOCK_INVALID  ((vmk_Lock)-1)

/** Invalid lock rank */
#define VMK_SPINLOCK_RANK_INVALID   (0)

/** Lock rank for unranked locks */
#define VMK_SPINLOCK_UNRANKED   (0xFFFF)


/**
 * \brief Lock Handle
 */
typedef struct vmk_LockInt *vmk_Lock;


/**
 * Spinlock Types
 */
typedef enum vmk_SpinlockType {
   /** Spinlock usable from a world context */
   VMK_SPINLOCK         = 1,
   /** Spinlock usable from a world and interrupt handler context */
   VMK_SPINLOCK_IRQ     = 2,
   /** RW Spinlock usable from a world context */
   VMK_SPINLOCK_RW      = 3,
} vmk_SpinlockType;


/**
 * \brief Rank for locks
 */
typedef vmk_uint16 vmk_LockRank;


/**
 * Spinlock Creation Properties
 */
typedef struct vmk_SpinlockCreateProps {
   /** Module ID for which the spinlock is created */
   vmk_ModuleID     moduleID;
   /** Heap from which the spinlock will be allocated */
   vmk_HeapID       heapID;
   /** Name of the spinlock */
   vmk_Name         name;
   /** Type of the lock */
   vmk_SpinlockType type;
   /**
    * Domain in which the spinlock will be rank checked in. If domain is set to
    * invalid then the rank also has to be set to invalid and vice versa.
    */
   vmk_LockDomainID domain;
   /** Rank of the spinlock. May only be set if domain is set to a valid value. */
   vmk_LockRank rank;
} vmk_SpinlockCreateProps;


/*
 ******************************************************************************
 * vmk_SpinlockCreate --                                                 */ /**
 *
 * \brief Allocate and initialize a spinlock
 *
 * Creates a new spinlock initializes it.
 *
 * \param[in]  props    Pointer to a valid vmk_SpinlockCreateProps struct
 * \param[out] lock     Pointer to the initialized spinlock
 *
 * \retval VMK_OK on success, error code otherwise
 *
 * \note Spinlocks can only be created from a world context
 * \note This function will not block
 *
 ******************************************************************************
 */

VMK_ReturnStatus
vmk_SpinlockCreate(vmk_SpinlockCreateProps *props,
                   vmk_Lock *lock);


/*
 ******************************************************************************
 * vmk_SpinlockDestroy --                                                */ /**
 *
 * \brief Destroy a spinlock previously created with vmk_SpinlockCreate
 *
 * Destroy the given lock and free the allocated memory
 *
 * \param[in] lock        Pointer to the spinlock
 *
 * \note This function will not block
 *
 ******************************************************************************
 */

void
vmk_SpinlockDestroy(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockAllocSize                                                 */ /**
 *
 * \brief Size of an allocated spinlock of the specified type
 *
 * \result Allocation size
 *
 * \note This function will not block
 *
 ******************************************************************************
 */

vmk_ByteCountSmall
vmk_SpinlockAllocSize(vmk_SpinlockType type);


/*
 ******************************************************************************
 * vmk_SpinlockLock --                                                   */ /**
 *
 * Acquire a spinlock of type VMK_SPINLOCK
 *
 * \param[in,out] lock  Spinlock to be acquired
 *
 * \return VMK_OK on success, error code otherwise
 *
 * \note Lock checks are only executed when enabled for a given build. They
 *       are always enabled for debug builds.
 * \note A caller has to release the spinlock with a subsequent call to
 *       vmk_SpinlockUnlock
 * \note Callers are required to minimize the time and code that is executed
 *       while any type of spinlock is held.
 * \note This function will not block
 *
 ******************************************************************************
 */

VMK_ReturnStatus
vmk_SpinlockLock(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockLockIRQ --                                                */ /**
 *
 * Acquire a spinlock of type VMK_SPINLOCK_IRQ
 *
 * \param[in,out] lock  IRQ Spinlock to be acquired
 *
 * \return VMK_OK on success, error code otherwise
 *
 * \note Lock checks are only executed when enabled for a given build. They
 *       are always enabled for debug builds.
 * \note A caller has to release the spinlock with a subsequent call to
 *       vmk_SpinlockUnlockIRQ
 * \note Callers are required to minimize the time and code that is executed
 *       while any type of spinlock is held.
 * \note This function will not block
 *
 ******************************************************************************
 */

VMK_ReturnStatus
vmk_SpinlockLockIRQ(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockReadLock --                                               */ /**
 *
 * Acquire a spinlock of type VMK_SPINLOCK_RW for reading
 *
 * \param[in,out] lock  R/W Spinlock to be acquired
 *
 * \return VMK_OK on success, error code otherwise
 *
 * \note Lock checks are only executed when enabled for a given build. They
 *       are always enabled for debug builds.
 * \note A caller has to release the spinlock with a subsequent call to
 *       vmk_SpinlockReadUnlock
 * \note Callers are required to minimize the time and code that is executed
 *       while any type of spinlock is held.
 * \note This function will not block
 *
 ******************************************************************************
 */

VMK_ReturnStatus
vmk_SpinlockReadLock(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockWriteLock --                                              */ /**
 *
 * Acquire a spinlock of type VMK_SPINLOCK_RW for an exclusive write operation
 *
 * \param[in,out] lock  R/W Spinlock to be acquired
 *
 * \return VMK_OK on success, error code otherwise
 *
 * \note Lock checks are only executed when enabled for a given build. They
 *       are always enabled for debug builds.
 * \note A caller has to release the spinlock with a subsequent call to
 *       vmk_SpinlockUnlock
 * \note Callers are required to minimize the time and code that is executed
 *       while any type of spinlock is held.
 * \note This function will not block
 *
 ******************************************************************************
 */

VMK_ReturnStatus
vmk_SpinlockWriteLock(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockUnlock --                                                 */ /**
 *
 * Release a spinlock previously acquired via vmk_SpinlockLock
 *
 * \param[in,out] lock  Spinlock to be released
 *
 * \note Callers are required to release spinlocks in the reverse order in which
 *       they were acquired
 * \note This function will not block
 *
 ******************************************************************************
 */

void
vmk_SpinlockUnlock(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockUnlockIRQ --                                              */ /**
 *
 * Release a IRQ spinlock previously acquired via vmk_SpinlockLockIRQ
 *
 * \param[in,out] lock  IRQ Spinlock to be released
 *
 * \note Callers are required to release spinlocks in the reverse order in which
 *       they were acquired
 * \note This function will not block
 *
 ******************************************************************************
 */

void
vmk_SpinlockUnlockIRQ(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockReadUnlock --                                             */ /**
 *
 * Release a R/W spinlock previously acquired via vmk_SpinlockReadLock
 *
 * \param[in,out] lock  Spinlock to be released
 *
 * \note Callers are required to release spinlocks in the reverse order in which
 *       they were acquired
 * \note This function will not block
 *
 ******************************************************************************
 */

void
vmk_SpinlockReadUnlock(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockWriteUnlock --                                            */ /**
 *
 * Release a R/W spinlock previously acquired via vmk_SpinlockWriteLock
 *
 * \param[in,out] lock  Spinlock to be released
 *
 * \note Callers are required to release spinlocks in the reverse order in which
 *       they were acquired
 * \note This function will not block
 *
 ******************************************************************************
 */

void
vmk_SpinlockWriteUnlock(vmk_Lock lock);


/*
 ******************************************************************************
 * vmk_SpinlockAssertHeldOnPCPUInt --
 *
 * This is used by vmk_SpinlockAssertHeldOnPCPU().  VMKAPI clients should not
 * call this function directly.
 *
 * \note This function will not block
 *
 ******************************************************************************
 */

/** \cond nodoc */
void
vmk_SpinlockAssertHeldOnPCPUInt(vmk_Lock lock);
/** \endcond */

/*
 ******************************************************************************
 * vmk_SpinlockAssertHeldOnPCPU --                                       */ /**
 *
 * \brief Asserts that a lock is held on the current PCPU
 *
 * \param[in]  lock  Lock to check
 *
 * \note Checks are only executed on debug builds.
 * \note This function will not block
 *
 ******************************************************************************
 */

static VMK_ALWAYS_INLINE void
vmk_SpinlockAssertHeldOnPCPU(
   vmk_Lock lock)
{
#ifdef VMX86_DEBUG
   vmk_SpinlockAssertHeldOnPCPUInt(lock);
#endif
}

#endif
/** @} */
/** @} */