423 lines
14 KiB
C
423 lines
14 KiB
C
|
/* **********************************************************
|
||
|
* Copyright 2008 - 2009 VMware, Inc. All rights reserved.
|
||
|
* **********************************************************/
|
||
|
|
||
|
/*
|
||
|
* @VMKAPIMOD_LICENSE@
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* HelperWorlds */ /**
|
||
|
* \defgroup HelperWorlds Helper Worlds
|
||
|
*
|
||
|
* Helper Worlds are a mechanism that allows work to be queued and
|
||
|
* run by a dynamically managed pool of worlds.
|
||
|
*
|
||
|
* @{
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
|
||
|
#ifndef _VMKAPI_HELPER_WORLDS_H_
|
||
|
#define _VMKAPI_HELPER_WORLDS_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_const.h"
|
||
|
#include "base/vmkapi_types.h"
|
||
|
#include "base/vmkapi_heap.h"
|
||
|
#include "base/vmkapi_world.h"
|
||
|
|
||
|
/** Maximum length of a helper name, including the trailing nul */
|
||
|
#define VMK_HELPER_NAME_MAX 32
|
||
|
|
||
|
/** Invalid helper ID */
|
||
|
#define VMK_HELPER_INVALID_ID ((vmk_Helper)-1)
|
||
|
|
||
|
/** Use default request properties */
|
||
|
#define VMK_HELPER_DEFAULT_REQ_PROPS ((const vmk_HelperRequestProps *)NULL)
|
||
|
|
||
|
/* Opaque helper definition */
|
||
|
typedef vmk_uintptr_t vmk_Helper;
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperTagComparator -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Compare two request tags to see if they are equal
|
||
|
*
|
||
|
* This function is used to find a request or set of requests based
|
||
|
* on their tag, such as during cancellation.
|
||
|
*
|
||
|
* \note This function must not block.
|
||
|
*
|
||
|
* \param[in] tag1 First tag to compare.
|
||
|
* \param[in] tag2 Second tag to compare.
|
||
|
*
|
||
|
* \retval VMK_TRUE The tags match.
|
||
|
* \retval VMK_FALSE The tags do not match.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef vmk_Bool (*vmk_HelperTagComparator)(vmk_AddrCookie tag1,
|
||
|
vmk_AddrCookie tag2);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperConstructor -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Function invoked when a new helper world is spawned.
|
||
|
*
|
||
|
* \param[in] arg Constructor argument that was stored in the helper
|
||
|
* queue's properties.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef void (*vmk_HelperConstructor)(vmk_AddrCookie arg);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperCancelFunc -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Function invoked when a request is canceled.
|
||
|
*
|
||
|
* \param[in] data Data that was passed in with the request.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef void (*vmk_HelperCancelFunc)(vmk_AddrCookie data);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperRequestFunc -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Function invoked when a request is processed
|
||
|
*
|
||
|
* \param[in] data Data that was passed in with the request.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef void (*vmk_HelperRequestFunc)(vmk_AddrCookie data);
|
||
|
|
||
|
/**
|
||
|
* \brief Properties for a helper queue that may be updated
|
||
|
* after it is created.
|
||
|
*/
|
||
|
typedef struct vmk_HelperMutableProps
|
||
|
{
|
||
|
/**
|
||
|
* Minimum number of worlds that will continue to exist to serve
|
||
|
* the helper queue.
|
||
|
*
|
||
|
* Setting this to a value less than the value of maxWorlds indicates
|
||
|
* that the helper queue can dynamically create and destroy worlds for
|
||
|
* the helper queue but will always maintain at least the specified
|
||
|
* number of worlds in the queue.
|
||
|
*
|
||
|
* Setting this to -1 or the same value as maxWorlds indicates that
|
||
|
* the caller does not want helper worlds to exit and does not want
|
||
|
* the pool of worlds to shrink dynamically.
|
||
|
*/
|
||
|
vmk_int32 minWorlds;
|
||
|
|
||
|
/**
|
||
|
* Maximum number of worlds that will service the helper queue.
|
||
|
*
|
||
|
* Setting this to 0 or less indicates that the helper queue should
|
||
|
* use the default number of worlds to service the helper queue.
|
||
|
*
|
||
|
* Setting this to 1 or more indicates that the helper queue should
|
||
|
* use the specified number of worlds as the maximum number of worlds
|
||
|
* that can back the queue.
|
||
|
*/
|
||
|
vmk_int32 maxWorlds;
|
||
|
|
||
|
/**
|
||
|
* Maximum number of milliseconds a world backing the helper
|
||
|
* queue can be idle before it is retired.
|
||
|
*
|
||
|
* Setting this to 0 or less indicates that the default idle time
|
||
|
* should be used.
|
||
|
*
|
||
|
* Setting this to 1 or more indiciates that if a world in the pool
|
||
|
* backing the helper queue has been idle for the specified number
|
||
|
* of milliseconds it will be retired.
|
||
|
*/
|
||
|
vmk_int32 maxIdleTime;
|
||
|
|
||
|
/**
|
||
|
* Maximum number of milliseconds a request can wait in the
|
||
|
* queue before a new world will be created to service the request.
|
||
|
*
|
||
|
* Setting this to 0 or less indiciates that the helper queue should
|
||
|
* use the default time.
|
||
|
*
|
||
|
* Setting this to 1 or more indicates that after the specified number
|
||
|
* of milliseconds a new world will be added to the pool of worlds
|
||
|
* backing the helper queue.
|
||
|
*
|
||
|
* \note The specified maximum number of worlds will not be
|
||
|
* exceeded even if a request has been waiting longer
|
||
|
* than the specified time.
|
||
|
*/
|
||
|
vmk_int32 maxRequestBlockTime;
|
||
|
}
|
||
|
vmk_HelperMutableProps;
|
||
|
|
||
|
/**
|
||
|
* \brief Properties for a new helper queue
|
||
|
*/
|
||
|
typedef struct
|
||
|
{
|
||
|
/** Human readable name for the helper queue */
|
||
|
char name[VMK_HELPER_NAME_MAX];
|
||
|
|
||
|
/** A heap the helper can use for allocations */
|
||
|
vmk_HeapID heap;
|
||
|
|
||
|
/**
|
||
|
* Should an IRQ spinlock should be used when synchronizing
|
||
|
* between producers and consumers of the helper queue?
|
||
|
*/
|
||
|
vmk_Bool useIrqSpinlock;
|
||
|
|
||
|
/**
|
||
|
* Should all memory for requests be preallocated when
|
||
|
* the helper queue is created?
|
||
|
*/
|
||
|
vmk_Bool preallocRequests;
|
||
|
|
||
|
/**
|
||
|
* Can callers block when submitting requests?
|
||
|
* Callers can override this setting on a per-call basis.
|
||
|
*/
|
||
|
vmk_Bool blockingSubmit;
|
||
|
|
||
|
/**
|
||
|
* Maximum number of requests this queue can support
|
||
|
*/
|
||
|
vmk_uint32 maxRequests;
|
||
|
|
||
|
/**
|
||
|
* Initial setting for properties which may be updated after
|
||
|
* the helper queue is created.
|
||
|
*/
|
||
|
vmk_HelperMutableProps mutables;
|
||
|
|
||
|
/**
|
||
|
* Function to compare two tags that identify requests
|
||
|
*
|
||
|
* Can be set to NULL if no function is desired.
|
||
|
*/
|
||
|
vmk_HelperTagComparator tagCompare;
|
||
|
|
||
|
/**
|
||
|
* Function to call when a new world is added to the
|
||
|
* pool of worlds backing the helper queue.
|
||
|
*
|
||
|
* This function will run in the context of the
|
||
|
* new world.
|
||
|
*
|
||
|
* This function will be called before running
|
||
|
* any helper requests on the new world.
|
||
|
*
|
||
|
* This can be set to NULL if no function is desired.
|
||
|
*/
|
||
|
vmk_HelperConstructor constructor;
|
||
|
|
||
|
/** Data to pass to the constructor function */
|
||
|
vmk_AddrCookie constructorArg;
|
||
|
}
|
||
|
vmk_HelperProps;
|
||
|
|
||
|
/**
|
||
|
* \brief Properties for a helper request
|
||
|
*/
|
||
|
typedef struct vmk_HelperRequestProps {
|
||
|
/** Should the submission of this request block the caller? */
|
||
|
vmk_Bool requestMayBlock;
|
||
|
|
||
|
/**
|
||
|
* A caller-supplied tag to identify the request.
|
||
|
*
|
||
|
* This tag is used to identify the request for calls
|
||
|
* such as vmk_HelperCancelRequest().
|
||
|
*/
|
||
|
vmk_AddrCookie tag;
|
||
|
|
||
|
/**
|
||
|
* An optional function to call after a request is canceled
|
||
|
* to perform cleanup.
|
||
|
*
|
||
|
* May be set to NULL if no function is required.
|
||
|
*
|
||
|
* This field cannot be set if the tag field is set to zero.
|
||
|
*/
|
||
|
vmk_HelperCancelFunc cancelFunc;
|
||
|
|
||
|
/**
|
||
|
* World to which to bill helper work or VMK_INVALID_WORLD_ID
|
||
|
* if there is no world to bill.
|
||
|
*/
|
||
|
vmk_WorldID worldToBill;
|
||
|
} vmk_HelperRequestProps;
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperCreate -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Create a new helper world queue.
|
||
|
*
|
||
|
* \param[in] props Creation properties for the new helper queue.
|
||
|
* \param[out] helper The newly created helper queue.
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_HelperCreate(vmk_HelperProps *props,
|
||
|
vmk_Helper *helper);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperDestroy -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Destroy an existing helper world queue.
|
||
|
*
|
||
|
* \param[in] helper Helper queue to destroy.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_HelperDestroy(vmk_Helper helper);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperUpdateProps -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Update the mutable properties on an existing helper queue.
|
||
|
*
|
||
|
* \param[in] helper Helper queue to destroy.
|
||
|
* \param[in] props New properties for the helper queue.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_HelperUpdateProps(vmk_Helper helper,
|
||
|
const vmk_HelperMutableProps *props);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperRequestPropsInit -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Initialize a vmk_HelperRequestProps structure.
|
||
|
*
|
||
|
* The resulting structure will have all properties set to their default.
|
||
|
*
|
||
|
* \param[in] props Pointer to the parameters to initialize.
|
||
|
*
|
||
|
* \retval VMK_INVALID_NAME Name for the helper queue is too long
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
void vmk_HelperRequestPropsInit(vmk_HelperRequestProps *props);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperSubmitRequest -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Submit a request to a helper world queue to be executed later
|
||
|
*
|
||
|
* \param[in] helper Helper queue to send the request to.
|
||
|
* \param[in] requestFunc Function to execute
|
||
|
* \param[in] data Data to pass to the function that will be
|
||
|
* executed.
|
||
|
* \param[in] props Properties of this request submission or
|
||
|
* VMK_HELPER_DEFAULT_PARAMS if the default
|
||
|
* parameters are desired.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_HelperSubmitRequest(vmk_Helper helper,
|
||
|
vmk_HelperRequestFunc requestFunc,
|
||
|
vmk_AddrCookie *data,
|
||
|
const vmk_HelperRequestProps *props);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperSubmitDelayedRequest -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Submit a request to a helper world queue to be executed only
|
||
|
* after a specified amount of time.
|
||
|
*
|
||
|
* \param[in] helper Helper queue to send the request to.
|
||
|
* \param[in] requestFunc Function to execute
|
||
|
* \param[in] data Data to pass to the function that will be
|
||
|
* executed.
|
||
|
* \param[in] props Properties of this request submission or
|
||
|
* VMK_HELPER_DEFAULT_PARAMS if the default
|
||
|
* parameters are desired.
|
||
|
* \param[in] timeoutMS Timeout in millseconds after which the function
|
||
|
* would be executed by the helper.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_HelperSubmitDelayedRequest(vmk_Helper helper,
|
||
|
vmk_HelperRequestFunc requestFunc,
|
||
|
vmk_AddrCookie *data,
|
||
|
vmk_uint32 timeoutMS,
|
||
|
const vmk_HelperRequestProps *props);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperCancelRequest -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Cancel requests on the queue that have the specified tag.
|
||
|
*
|
||
|
* \param[in] helper Helper queue on which to issue the cancel.
|
||
|
* \param[in] requestTag Tag used to identify which requests to
|
||
|
* cancel.
|
||
|
* \param[out] numCancelled Number of requests that were actually
|
||
|
* cancelled.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_HelperCancelRequest(vmk_Helper helper,
|
||
|
vmk_AddrCookie requestTag,
|
||
|
vmk_uint32 *numCancelled);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_HelperCurrentRequestCount -- */ /**
|
||
|
*
|
||
|
* \ingroup HelperWorlds
|
||
|
* \brief Get a snapshot of the current number of pending requests on
|
||
|
* a helper queue.
|
||
|
*
|
||
|
* \note The count returned by this function does not include the
|
||
|
* count of requests that are actively being processed.
|
||
|
*
|
||
|
* \param[in] helper Helper queue to check.
|
||
|
*
|
||
|
* \return The number of pending requests on the helper queue.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
vmk_uint32 vmk_HelperCurrentRequestCount(vmk_Helper helper);
|
||
|
|
||
|
#endif /* _VMKAPI_HELPER_WORLDS_H_ */
|
||
|
/** @} */
|