vmkdrivers/BLD/build/HEADERS/vmkapi-current/vmkernel64/release/base/vmkapi_sem.h

564 lines
18 KiB
C
Raw Normal View History

2015-10-23 19:21:55 +00:00
/* **********************************************************
* Copyright 2004 - 2009 VMware, Inc. All rights reserved.
* **********************************************************/
/*
* @VMKAPIMOD_LICENSE@
*/
/*
***********************************************************************
* Semaphores */ /**
* \defgroup Semaphores Semaphores
*
* \par Binary Semaphore Ranks:
* Binary semaphores are semaphores which may be treated like blocking
* locks. As such, they take a rank and sub-rank in a manner analogous
* the the lock ranking used for spinlocks.\n
* \n
* When a world locks a binary semaphore \em BS1 with major rank \em R1 and
* minor rank \em r1, it may only lock another binary semaphore BS2 with
* major rank \em R2 and minor rank \em r2 when:
* \n
* \em R2 > \em R1 \n
* or \n
* \em R2 == \em R1 and \em r2 > \em r1 \n
* \n
* Be aware that rank checking is only performed on debug builds.
* @{
***********************************************************************
*/
#ifndef _VMKAPI_SEM_H_
#define _VMKAPI_SEM_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 */
#include "base/vmkapi_types.h"
#include "base/vmkapi_module.h"
#include "base/vmkapi_status.h"
/** \cond nodoc */
/* Private definitions */
#define _VMK_SEMA_RANK_UNRANKED 0x10000
#define _VMK_SEMA_RANK_MAX 0xffff
#define _VMK_SEMA_RANK_MIN 0
#define _VMK_SEMA_RANK_LEAF _VMK_SEMA_RANK_MAX
#define _VMK_SEMA_RANK_STORAGE 0x8000
typedef vmk_uint32 _vmk_SemaRank, _vmk_SemaRankMinor;
/** \endcond nodoc */
/**
* \brief unranked rank
*/
#define VMK_SEMA_RANK_UNRANKED _VMK_SEMA_RANK_UNRANKED
/**
* \brief Leaf rank for semaphores
*/
#define VMK_SEMA_RANK_LEAF _VMK_SEMA_RANK_LEAF
/**
* \brief Maximum rank for semaphores
*/
#define VMK_SEMA_RANK_MAX _VMK_SEMA_RANK_MAX
/**
* \brief Minimum rank for semaphores
*/
#define VMK_SEMA_RANK_MIN _VMK_SEMA_RANK_MIN
/**
* \brief Rank for semaphores in storage components
*/
#define VMK_SEMA_RANK_STORAGE _VMK_SEMA_RANK_STORAGE
/**
* \brief Rank for semaphores
*/
typedef _vmk_SemaRank vmk_SemaphoreRank;
/**
* \brief Sub rank for semaphores
*/
typedef _vmk_SemaRankMinor vmk_SemaphoreRankMinor;
/**
* \brief Opaque handle for semaphores
*/
typedef struct vmk_SemaphoreInt *vmk_Semaphore;
/**
* \brief Opaque handle for readers-writers semaphores
*/
typedef struct vmk_SemaphoreRWInt *vmk_SemaphoreRW;
/*
***********************************************************************
* vmk_SemaCreate -- */ /**
*
* \ingroup Semaphores
* \brief Allocate and initialize a counting semaphore
*
* \note Requires that the module heap be initialized.
*
* \param[out] sema New counting semaphore.
* \param[in] moduleID Module on whose behalf the semaphore
* is created.
* \param[in] name Human-readable name of the semaphore.
* \param[in] value Initial count.
*
* \retval VMK_OK The semaphore was successfully created
* \retval VMK_NO_MEMORY The semaphore could not be allocated
* \retval VMK_NO_MODULE_HEAP The module has no heap to allocate from
*
***********************************************************************
*/
VMK_ReturnStatus vmk_SemaCreate(
vmk_Semaphore *sema,
vmk_ModuleID moduleID,
const char *name,
vmk_int32 value);
/*
***********************************************************************
* vmk_BinarySemaCreate -- */ /**
*
* \ingroup Semaphores
* \brief Allocate and initialize a binary semaphore
*
* \note Requires that the module heap be initialized.
*
* \param[out] sema New counting semaphore.
* \param[in] moduleID Module on whose behalf the semaphore
* is created.
* \param[in] name Human-readable name of the semaphore.
* \param[in] majorRank Major rank of the semaphore.
* The rank value must be greater than or
* equal to VMK_SEMA_RANK_MIN and less than
* or equal to VMK_SEMA_RANK_MAX.
* \param[in] minorRank Minor rank of the semaphore.
* The rank value must be greater than or
* equal to VMK_SEMA_RANK_MIN and less than
* or equal to VMK_SEMA_RANK_MAX.
*
* \retval VMK_OK The semaphore was successfully created
* \retval VMK_NO_MEMORY The semaphore could not be allocated
* \retval VMK_NO_MODULE_HEAP The module has no heap to allocate from
*
***********************************************************************
*/
VMK_ReturnStatus vmk_BinarySemaCreate(
vmk_Semaphore *sema,
vmk_ModuleID moduleID,
const char *name,
vmk_SemaphoreRank majorRank,
vmk_SemaphoreRankMinor minorRank);
/*
***********************************************************************
* _vmkSemaIsLocked
*
* This is used by VMK_ASSERT_SEMA_LOCKED and VMK_ASSERT_SEMA_UNLOCKED.
* VMKAPI users should not call this function directly.
*
***********************************************************************
*/
/** \cond nodoc */
VMK_ReturnStatus _vmkSemaIsLocked(
vmk_Semaphore *sema,
vmk_Bool *isLocked);
/** \endcond */
/*
***********************************************************************
* VMK_ASSERT_SEMA_LOCKED -- */ /**
*
* \ingroup Semaphores
* \brief Assert that a semaphore is currently locked only in
* debug builds.
*
* \param[in] sema Semaphore to check.
*
***********************************************************************
*/
#if defined(VMX86_DEBUG)
#define VMK_ASSERT_SEMA_LOCKED(sema) \
do { \
vmk_Bool _vmkCheckLockState ; \
VMK_ASSERT(_vmkSemaIsLocked((sema),&_vmkCheckLockState) == \
VMK_OK); \
VMK_ASSERT(_vmkCheckLockState); \
} while(0)
#else
#define VMK_ASSERT_SEMA_LOCKED(sema)
#endif
/*
***********************************************************************
* VMK_ASSERT_SEMA_UNLOCKED -- */ /**
*
* \ingroup Semaphores
* \brief Assert that a semaphore is currently unlocked only in
* debug builds.
*
* \param[in] sema Semaphore to check.
*
***********************************************************************
*/
#if defined(VMX86_DEBUG)
#define VMK_ASSERT_SEMA_UNLOCKED(sema) \
do { \
vmk_Bool _vmkCheckLockState ; \
VMK_ASSERT(_vmkSemaIsLocked((sema),&_vmkCheckLockState) == \
VMK_OK); \
VMK_ASSERT(!_vmkCheckLockState); \
} while(0)
#else
#define VMK_ASSERT_SEMA_UNLOCKED(sema)
#endif
/*
***********************************************************************
* vmk_SemaLock -- */ /**
*
* \ingroup Semaphores
* \brief Acquire a semaphore
*
* \pre Shall be called from a blockable context.
* \pre The caller shall not already hold a semaphore of lower or equal
* rank if the semaphore is a binary semaphore.
*
* \param[in] sema The semaphore to acquire.
*
***********************************************************************
*/
void vmk_SemaLock(
vmk_Semaphore *sema);
/*
***********************************************************************
* vmk_SemaTryLock -- */ /**
*
* \ingroup Semaphores
* \brief Try to acquire a semaphore.
*
* This tries to acquire the given semaphore once.
* If the semaphore is already locked, it returns immediately.
*
* \pre Shall be called from a blockable context.
*
* \param[in] sema Semaphore to attempt to acquire.
*
* \retval VMK_OK The semaphore was successfully acquired.
* \retval VMK_BUSY The semaphore is currently locked.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_SemaTryLock(
vmk_Semaphore *sema);
/*
***********************************************************************
* vmk_SemaUnlock -- */ /**
*
* \ingroup Semaphores
* \brief Release a semaphore
*
* \param[in] sema Semaphore to unlock.
*
***********************************************************************
*/
void vmk_SemaUnlock(
vmk_Semaphore *sema);
/*
***********************************************************************
* vmk_SemaDestroy -- */ /**
*
* \ingroup Semaphores
* \brief Destroy a semaphore
*
* Revert all side effects of vmk_SemaCreate or vmk_BinarySemaCreate.
*
* \param[in] sema Semaphore to destroy.
*
***********************************************************************
*/
void vmk_SemaDestroy(vmk_Semaphore *sema);
/*
***********************************************************************
* VMK_ASSERT_RWSEMA_HAS_READERS -- */ /**
*
* \ingroup Semaphores
* \brief Assert that a readers-writers semaphore has at least one
* shared reader only in debug builds.
*
* \param[in] sema Semaphore to check.
*
***********************************************************************
*/
#if defined(VMX86_DEBUG)
#define VMK_ASSERT_RWSEMA_HAS_READERS(sema) \
do { \
VMK_ASSERT(vmk_RWSemaHasReaders(sema) == VMK_TRUE); \
} while(0)
#else
#define VMK_ASSERT_RWSEMA_HAS_READERS(sema)
#endif
/*
***********************************************************************
* VMK_ASSERT_RWSEMA_HAS_WRITER -- */ /**
*
* \ingroup Semaphores
* \brief Assert that a readers-writers semaphore has a writer only in
* debug builds.
*
* \param[in] sema Semaphore to check.
*
***********************************************************************
*/
#if defined(VMX86_DEBUG)
#define VMK_ASSERT_RWSEMA_HAS_WRITER(sema) \
do { \
VMK_ASSERT(vmk_RWSemaHasWriter(sema) == VMK_TRUE); \
} while(0)
#else
#define VMK_ASSERT_RWSEMA_HAS_WRITER(sema)
#endif
/*
***********************************************************************
* VMK_ASSERT_RWSEMA_HAS_READERS_WRITERS -- */ /**
*
* \ingroup Semaphores
* \brief Assert that a readers-writers semaphore has a writer only in
* debug builds.
*
* \param[in] sema Semaphore to check.
*
***********************************************************************
*/
#if defined(VMX86_DEBUG)
#define VMK_ASSERT_RWSEMA_HAS_READERS_WRITERS(sema) \
do { \
VMK_ASSERT(vmk_RWSemaHasReadersWriters(sema) == VMK_TRUE); \
} while(0)
#else
#define VMK_ASSERT_RWSEMA_HAS_READERS_WRITERS(sema)
#endif
/*
***********************************************************************
* vmk_RWSemaCreate -- */ /**
*
* \ingroup Semaphores
* \brief Allocate and initialize a readers-writers semaphore
*
* \param[out] sema New readers-writers semaphore.
* \param[in] moduleID Module on whose behalf the semaphore
* is created.
* \param[in] name Human-readable name of the semaphore.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_RWSemaCreate(
vmk_SemaphoreRW *sema,
vmk_ModuleID moduleID,
const char *name);
/*
***********************************************************************
* vmk_RWSemaDestroy -- */ /**
*
* \ingroup Semaphores
* \brief Destroy a readers-writers semaphore
*
* Revert all side effects of vmk_RWSemaCreate.
*
* \param[in] sema Readers-writers semaphore to destroy.
*
***********************************************************************
*/
void vmk_RWSemaDestroy(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaReadLock -- */ /**
*
* \ingroup Semaphores
* \brief Acquire a readers-writers semaphore for shared read access.
*
* \pre Shall be called from a blockable context.
*
* \param[in] sema Readers-writers semaphore to acquire.
*
***********************************************************************
*/
void vmk_RWSemaReadLock(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaWriteLock -- */ /**
*
* \ingroup Semaphores
* \brief Acquire a readers-writers semaphore for exclusive write
* access.
*
* \pre Shall be called from a blockable context.
*
* \param[in] sema Readers-writers semaphore to acquire.
*
***********************************************************************
*/
void vmk_RWSemaWriteLock(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaReadUnlock -- */ /**
*
* \ingroup Semaphores
* \brief Release a readers-writers semaphore from shared read access.
*
* \param[in] sema Readers-writers semaphore to release.
*
***********************************************************************
*/
void vmk_RWSemaReadUnlock(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaWriteUnlock -- */ /**
*
* \ingroup Semaphores
* \brief Release a readers-writers semaphore from exclusive write
* access.
*
* \param[in] sema Readers-writers semaphore to release.
*
***********************************************************************
*/
void vmk_RWSemaWriteUnlock(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaUpgradeFromRead -- */ /**
*
* \ingroup Semaphores
* \brief Upgrade a readers-writers semaphore to exclusive write access.
*
* This requests an upgrade to exclusive writers access for the
* readers-writers semaphore while already holding shared reader access.
* If the upgrade is not immediately available, only the first caller
* can block waiting for the upgrade. Others fail, but they retain
* shared reader access.
*
* \pre Shall be called from a blockable context.
* \pre Shall already have read access to the semaphore.
*
* \param[in] sema Readers-writers semaphore to upgrade.
*
* \retval VMK_OK The semaphore was upgraded.
* \retval VMK_BUSY The semaphore could not be upgraded.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_RWSemaUpgradeFromRead(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaTryUpgradeFromRead -- */ /**
*
* \ingroup Semaphores
* \brief Attempt to upgrade a readers-writers semaphore to
* exclusive write access.
*
* This attempts to obtain exclusive writers access to the
* readers-writers semaphore while already holding shared reader access.
* If the upgrade is not immediately available, shared reader access
* is retained.
*
* \pre Shall already have read access to the semaphore.
*
* \param[in] sema Readers-writers semaphore to upgrade.
*
* \retval VMK_OK The semaphore was upgraded.
* \retval VMK_BUSY The semaphore could not be upgraded.
*
***********************************************************************
*/
VMK_ReturnStatus vmk_RWSemaTryUpgradeFromRead(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaDowngradeToRead -- */ /**
*
* \ingroup Semaphores
* \brief Downgrade a readers-writers semaphore from exclusive
* write access to shared read access.
*
* \pre Shall already have write access to the semaphore.
*
* \param[in] sema Readers-writers semaphore to downgrade.
*
***********************************************************************
*/
void vmk_RWSemaDowngradeToRead(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_RWSemaHasReaders -- */ /**
*
* \ingroup Semaphores
* \brief Determine if a readers-writers semaphore currently has one or
* more readers.
*
* \param[in] sema Readers-writers semaphore to inspect.
*
***********************************************************************
*/
vmk_Bool vmk_RWSemaHasReaders(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_SemaHasWriter -- */ /**
*
* \ingroup Semaphores
* \brief Determine if a readers-writers semaphore currently has
* a writer.
*
* \param[in] sema Readers-writers semaphore to inspect.
*
***********************************************************************
*/
vmk_Bool vmk_RWSemaHasWriter(vmk_SemaphoreRW *sema);
/*
***********************************************************************
* vmk_SemaHasReadersWriters -- */ /**
*
* \ingroup Semaphores
* \brief Determine if a readers-writers semaphore currently has any
* readers or an exclusive writer.
*
* \param[in] sema Readers-writers semaphore to inspect.
*
***********************************************************************
*/
vmk_Bool vmk_RWSemaHasReadersWriters(vmk_SemaphoreRW *sema);
#endif /* _VMKAPI_SEM_H_ */
/** @} */