blob: c13404d7f6a76904f43bad6ddf121ef43a337326 [file] [log] [blame]
/*
* Copyright 2010-2016 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIPIPELINE_SOURCE_H
#define _COIPIPELINE_SOURCE_H
/** @ingroup COIPipeline
* @addtogroup COIPipelineSource
@{
* @file source/COIPipeline_source.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
//////////////////////////////////////////////////////////////////////////////
/// These flags specify how a buffer will be used within a run function. They
/// allow the runtime to make optimizations in how it moves the data around.
/// These flags can affect the correctness of an application, so they must be
/// set properly. For example, if a buffer is used in a run function with the
/// COI_SINK_READ flag and then mapped on the source, the runtime may use a
/// previously cached version of the buffer instead of retrieving data from
/// the sink.
typedef enum COI_ACCESS_FLAGS
{
/// Specifies that the run function will only read the associated buffer.
COI_SINK_READ = 1,
/// Specifies that the run function will write to the associated buffer.
COI_SINK_WRITE,
/// Specifies that the run function will overwrite the entire associated
/// buffer and therefore the buffer will not be synchronized with the
/// source before execution.
COI_SINK_WRITE_ENTIRE,
/// Specifies that the run function will only read the associated buffer
/// and will maintain the reference count on the buffer after
/// run function exit.
COI_SINK_READ_ADDREF,
/// Specifies that the run function will write to the associated buffer
/// and will maintain the reference count on the buffer after
/// run function exit.
COI_SINK_WRITE_ADDREF,
/// Specifies that the run function will overwrite the entire associated
/// buffer and therefore the buffer will not be synchronized with the
/// source before execution and will maintain the reference count on the
/// buffer after run function exit.
COI_SINK_WRITE_ENTIRE_ADDREF
} COI_ACCESS_FLAGS;
#define COI_PIPELINE_MAX_PIPELINES 512
#define COI_PIPELINE_MAX_IN_BUFFERS 16384
#define COI_PIPELINE_MAX_IN_MISC_DATA_LEN 32768
///////////////////////////////////////////////////////////////////////////////
///
/// Create a pipeline associated with a remote process. This pipeline can
/// then be used to execute remote functions and to share data using
/// COIBuffers.
///
/// @param in_Process
/// [in] A handle to an already existing process that the pipeline
/// will be associated with.
///
/// @param in_Mask
/// [in] An optional mask of the set of hardware threads on which the
/// sink pipeline command processing thread could run.
///
/// @param in_StackSize
/// [in] An optional value that will be used when the pipeline
/// processing thread is created on the sink. If the user passes in
/// 0 the OS default stack size will be used. Otherwise the value
/// must be PTHREAD_STACK_MIN (16384) bytes or larger and must be
/// a multiple of a page (4096 bytes).
///
/// @param out_pPipeline
/// [out] Handle returned to uniquely identify the pipeline that was
/// created for use in later API calls.
///
///
/// @return COI_SUCCESS if the pipeline was successfully created.
///
/// @return COI_INVALID_HANDLE if the in_Process handle passed in was invalid.
///
/// @return COI_INVALID_POINTER if the out_pPipeline pointer was NULL.
///
/// @return COI_RESOURCE_EXHAUSTED if no more COIPipelines can be created. The
/// maximum number of pipelines allowed is COI_PIPELINE_MAX_PIPELINES.
/// It is recommended in most cases to not exceed the number of CPU's
/// that are reported on the offload device, performance will suffer.
///
///
/// @return COI_OUT_OF_RANGE if the in_StackSize > 0 &&
/// in_StackSize < PTHREAD_STACK_MIN or if in_StackSize is not a
/// multiple of a page (4096 bytes).
///
/// @return COI_OUT_OF_RANGE if the in_Mask is set to all zeroes. If no mask
/// is desired then the in_Mask should be passed as NULL, otherwise
/// at least one thread must be set.
///
/// @return COI_TIME_OUT_REACHED if establishing the communication channel with
/// the remote pipeline timed out.
///
/// @return COI_RETRY if the pipeline cannot be created due to the number of
/// source-to-sink connections in use. A subsequent call to
/// COIPipelineCreate may succeed if resources are freed up.
///
/// @return COI_PROCESS_DIED if in_Process died.
///
COIACCESSAPI
COIRESULT
COIPipelineCreate(
COIPROCESS in_Process,
COI_CPU_MASK in_Mask,
uint32_t in_StackSize,
COIPIPELINE *out_pPipeline);
///////////////////////////////////////////////////////////////////////////////
///
/// Destroys the indicated pipeline, releasing its resources.
///
/// @param in_Pipeline
/// [in] Pipeline to destroy.
///
///
/// @return COI_SUCCESS if the pipeline was destroyed
///
COIACCESSAPI
COIRESULT
COIPipelineDestroy(
COIPIPELINE in_Pipeline);
//////////////////////////////////////////////////////////////////////////////
///
/// Enqueues a function in the remote process binary to be executed. The
/// function execution is asynchronous in regards to the Source and all
/// run functions enqueued on a pipeline are executed in-order. The run
/// function will only execute when all of the required buffers are present
/// in the Sink's memory.
///
/// Potential Hazards while using Runfunctions:
///
/// 1. Proper care has to be taken while setting the input dependencies for
/// RunFunctions. Setting it incorrectly can lead to cyclic dependencies
/// and can cause the respective pipeline to stall.
/// 2. RunFunctions can also segfault if enough memory space is not available
/// on the sink for the buffers passed in. Buffers that are AddRef'd
/// need to be accounted for available memory space. In other
/// words, this memory is not available for use until it is freed up.
/// 3. Unexpected segmentation faults or erroneous behavior can occur if
/// handles or data passed in to Runfunction gets destroyed before the
/// RunFunction finishes.
/// For example, if a variable passed in as Misc data or the buffer gets
/// destroyed before the runtime receives the completion notification
/// of the Runfunction, it can cause unexpected behavior. So it is always
/// recommended to wait for RunFunction completion event before any related
/// destroy event occurs.
///
/// The runtime expects users to handle such scenarios. COIPipelineRunFunction
/// returns COI_SUCCESS for above cases because it was queued up successfully.
/// Also if you try to destroy a pipeline with a stalled function then the
/// destroy call will hang. COIPipelineDestroy waits until all the functions
/// enqueued are finished executing.
///
/// @param in_Pipeline
/// [in] Handle to a previously created pipeline that this run
/// function should be enqueued to.
///
/// @param in_Function
/// [in] Previously returned handle from a call to
/// COIPipelineGetFunctionHandle() that represents a function in the
/// application running on the Sink process.
///
/// @param in_NumBuffers
/// [in] The number of buffers that are being passed to the run
/// function. This number must match the number of buffers in the
/// in_pBuffers and in_pBufferAccessFlags arrays. Must be less than
/// COI_PIPELINE_MAX_IN_BUFFERS.
///
/// @param in_pBuffers
/// [in] An array of COIBUFFER handles that the function is expected
/// to use during its execution. Each buffer when it arrives at the
/// Sink process will be at least 4k page aligned, thus, using a very
/// large number of small buffers is memory inefficient and should be
/// avoided.
///
/// @param in_pBufferAccessFlags
/// [in] An array of flag values which correspond to the buffers
/// passed in the in_pBuffers parameter. These flags are used to
/// track dependencies between different run functions being
/// executed from different pipelines.
///
/// @param in_NumDependencies
/// [in] The number of dependencies specified in the in_pDependencies
/// array. This may be 0 if the caller does not want the run function
/// to wait for any dependencies.
///
/// @param in_pDependencies
/// [in] An optional array of COIEVENT objects that this run
/// function will wait for before executing. This allows the user to
/// create dependencies between run functions in different pipelines.
/// The user may pass in NULL if they do not wish to wait for any
/// dependencies to complete.
///
/// @param in_pMiscData
/// [in] Pointer to user defined data, typically used to pass
/// parameters to Sink side functions. Should only be used for small
/// amounts data since the data will be placed directly in the
/// Driver's command buffer. COIBuffers should be used to pass large
/// amounts of data.
///
/// @param in_MiscDataLen
/// [in] Size of the in_pMiscData in bytes. Must be less than
/// COI_PIPELINE_MAX_IN_MISC_DATA_LEN, and should usually be much
/// smaller, see documentation for the parameter in_pMiscData.
///
/// @param out_pAsyncReturnValue
/// [out] Pointer to user-allocated memory where the return value from
/// the run function will be placed. This memory should not be read
/// until out_pCompletion has been signaled.
///
/// @param in_AsyncReturnValueLen
/// [in] Size of the out_pAsyncReturnValue in bytes.
///
/// @param out_pCompletion
/// [out] An optional pointer to a COIEVENT object
/// that will be signaled when this run function has completed
/// execution. The user may pass in NULL if they wish for this function
/// to be synchronous, otherwise if a COIEVENT object is passed in the
/// function is then asynchronous and closes after enqueuing the
/// RunFunction and passes back the COIEVENT that will be signaled
/// once the RunFunction has completed.
///
/// @return COI_SUCCESS if the function was successfully placed in a
/// pipeline for future execution. Note that the actual
/// execution of the function will occur in the future.
///
/// @return COI_OUT_OF_RANGE if in_NumBuffers is greater than
/// COI_PIPELINE_MAX_IN_BUFFERS or if in_MiscDataLen is greater than
/// COI_PIPELINE_MAX_IN_MISC_DATA_LEN.
///
/// @return COI_INVALID_HANDLE if the pipeline handle passed in was invalid.
///
/// @return COI_INVALID_HANDLE if the function handle passed in was invalid.
///
/// @return COI_INVALID_HANDLE if any of the buffers passed in are invalid.
///
/// @return COI_ARGUMENT_MISMATCH if in_NumDependencies is non-zero while
/// in_pDependencies was passed in as NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pDependencies is non-NULL but
/// in_NumDependencies is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_MiscDataLen is non-zero while
/// in_pMiscData was passed in as NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pMiscData is non-NULL but
/// in_MiscDataLen is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_NumBuffers is non-zero and in_pBuffers
/// or in_pBufferAccessFlags are NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pBuffers is non-NULL but
/// in_NumBuffers is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_pBufferAccessFlags is non-NULL but
/// in_NumBuffers is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_ReturnValueLen is non-zero while
/// in_pReturnValue was passed in as NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pReturnValue is non-NULL but
/// in_ReturnValueLen is zero.
///
/// @return COI_RETRY if any input buffers are still mapped when
/// passed to the run function.
///
/// @return COI_MISSING_DEPENDENCY if buffer was not created on the process
/// associated with the pipeline that was passed in.
///
/// @return COI_OUT_OF_RANGE if any of the access flags in
/// in_pBufferAccessFlags is not a valid COI_ACCESS_FLAGS.
///
COIACCESSAPI
COIRESULT
COIPipelineRunFunction(
COIPIPELINE in_Pipeline,
COIFUNCTION in_Function,
uint32_t in_NumBuffers,
const COIBUFFER *in_pBuffers,
const COI_ACCESS_FLAGS *in_pBufferAccessFlags,
uint32_t in_NumDependencies,
const COIEVENT *in_pDependencies,
const void *in_pMiscData,
uint16_t in_MiscDataLen,
void *out_pAsyncReturnValue,
uint16_t in_AsyncReturnValueLen,
COIEVENT *out_pCompletion);
//////////////////////////////////////////////////////////////////////////////
///
/// Retrieve the engine that the pipeline is associated with.
///
/// @param in_Pipeline
/// [in] Pipeline to query.
///
/// @param out_pEngine
/// [out] The handle of the Engine.
///
/// @return COI_SUCCESS if the engine was retrieved.
///
/// @return COI_INVALID_HANDLE if the pipeline handle passed in was invalid.
///
/// @return COI_INVALID_POINTER if the out_pEngine parameter is NULL.
///
/// @return COI_PROCESS_DIED if the process associated with this engine died.
///
COIACCESSAPI
COIRESULT
COIPipelineGetEngine(
COIPIPELINE in_Pipeline,
COIENGINE *out_pEngine);
//////////////////////////////////////////////////////////////////////////////
///
/// Add a particular core:thread pair to a COI_CPU_MASK.
///
/// @param in_Process
/// [in] A handle to an already existing process that the pipeline
/// will be associated with.
///
/// @param in_CoreID
/// [in] Core to affinitize to; must be less than the number of cores
/// on the device.
///
/// @param in_ThreadID
/// [in] Thread on the core to affinitize to (0 - 3).
///
/// @param out_pMask
/// [out] Pointer to the mask to set.
///
/// @warning Unless it is explicitly done, the contents of the mask may not
/// be zero when creating or declaring a COI_CPU_MASK variable.
///
/// @return COI_SUCCESS if the mask was set.
///
/// @return COI_OUT_OF_RANGE if the in_CoreID or in_ThreadID is out of range.
///
/// @return COI_INVALID_POINTER if out_pMask is invalid.
///
/// @return COI_INVALID_HANDLE if in_Process is invalid.
///
COIACCESSAPI
COIRESULT
COIPipelineSetCPUMask(
COIPROCESS in_Process,
uint32_t in_CoreID,
uint8_t in_ThreadID,
COI_CPU_MASK *out_pMask);
//////////////////////////////////////////////////////////////////////////////
///
/// Clears a given mask. Note that the memory contents of COI_CPU_MASK are not
/// guaranteed to be zero when declaring a COI_CPU_MASK variable. Thus, prior
/// to setting a specific affinity to in_Mask it is important to call this
/// function first.
///
/// @param in_Mask
/// [in] Pointer to the mask to clear.
///
/// @return COI_SUCCESS if the mask was cleared.
///
/// @return COI_INVALID_POINTER if in_Mask is invalid.
///
COIACCESSAPI
COIRESULT
COIPipelineClearCPUMask(
COI_CPU_MASK *in_Mask);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIPIPELINE_SOURCE_H */
/*! @} */