// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
return 0;
}
+
+int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, vector<AliHLTComponent_DataType>* tgtList)
+{
+ int iResult=0;
+ if (pConsumer) {
+ vector<AliHLTComponent_DataType> ctlist;
+ ((AliHLTComponent*)pConsumer)->GetInputDataTypes(ctlist);
+ vector<AliHLTComponent_DataType>::iterator type=ctlist.begin();
+ while (type!=ctlist.end() && iResult==0) {
+ if ((*type)==GetOutputDataType()) {
+ if (tgtList) tgtList->push_back(*type);
+ iResult++;
+ break;
+ }
+ type++;
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
// Spawn function, return new class instance
virtual AliHLTComponent* Spawn() = 0;
+
+ int FindMatchingDataTypes(AliHLTComponent* pConsumer, vector<AliHLTComponent_DataType>* tgtList);
static int SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite=0) {
int iResult=0;
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
}
}
-int AliHLTConfiguration::GetArguments(int* pArgc, const char*** pArgv)
+int AliHLTConfiguration::GetArguments(const char*** pArgv)
{
int iResult=0;
- if (pArgc && pArgv) {
- *pArgc=fArgc;
+ if (pArgv) {
+ iResult=fArgc;
*pArgv=(const char**)fArgv;
} else {
iResult=-EINVAL;
fpConfiguration=NULL;
fpComponent=NULL;
fpBlockDataArray=NULL;
+ fBlockDataArraySize=0;
+ fpDataBuffer=NULL;
}
AliHLTTask::AliHLTTask(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH)
fpConfiguration=NULL;
fpComponent=NULL;
fpBlockDataArray=NULL;
+ fBlockDataArraySize=0;
+ fpDataBuffer=NULL;
Init(fConf, pCH);
}
if (pCH) {
int argc=0;
const char** argv=NULL;
- if ((iResult=fConf->GetArguments(&argc, &argv))>=0) {
+ if ((iResult=fConf->GetArguments(&argv))>=0) {
+ argc=iResult; // just to make it clear
iResult=pCH->CreateComponent(fConf->GetComponentID(), NULL, argc, argv, fpComponent);
if (fpComponent) {
} else {
return TObject::GetName();
}
-AliHLTConfiguration* AliHLTTask::GetConf()
+AliHLTConfiguration* AliHLTTask::GetConf() const
{
return fpConfiguration;
}
-AliHLTComponent* AliHLTTask::GetComponent()
+AliHLTComponent* AliHLTTask::GetComponent() const
{
return fpComponent;
}
}
}
+/* this function is most likely depricated
int AliHLTTask::InsertBlockData(AliHLTComponent_BlockData* pBlock, AliHLTTask* pSource)
{
int iResult=0;
return iResult;
}
+*/
int AliHLTTask::SetDependency(AliHLTTask* pDep)
{
return iResult;
}
-int AliHLTTask::BuildBlockDataArray(AliHLTComponent_BlockData*& pTgt)
+/* this function is most likely depricated
+int AliHLTTask::BuildBlockDataArray(AliHLTComponent_BlockData*& pBlockData)
{
int iResult=0;
return iResult;
}
+*/
+int AliHLTTask::StartRun()
+{
+ int iResult=0;
+ int iNofInputDataBlocks=0;
+ AliHLTComponent* pComponent=GetComponent();
+ if (pComponent) {
+ // determine the number of input data blocks provided from the source tasks
+ TObjLink* lnk=fListDependencies.FirstLink();
+ while (lnk && iResult>=0) {
+ AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
+ if (pSrcTask) {
+ if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
+ iNofInputDataBlocks+=iResult;
+ } else if (iResult==0) {
+ HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
+ } else {
+ HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
+ iResult=-EFAULT;
+ }
+ }
+ lnk=lnk->Next();
+ }
+ if (iResult>=0) {
+ if (fpBlockDataArray) {
+ HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
+ delete [] fpBlockDataArray;
+ fpBlockDataArray=NULL;
+ fBlockDataArraySize=0;
+ }
+
+ // component init
+ //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
+
+ // allocate internal task varables for bookkeeping aso.
+ fpBlockDataArray=new AliHLTComponent_BlockData[iNofInputDataBlocks];
+ if (fpBlockDataArray) {
+ fBlockDataArraySize=iNofInputDataBlocks;
+ } else {
+ HLTError("memory allocation failed");
+ iResult=-ENOMEM;
+ }
+ }
+ } else {
+ HLTError("task %s (%p) does not have a component", GetName(), this);
+ iResult=-EFAULT;
+ }
+ return iResult;
+}
-// int AliHLTTask::ProcessTask(...)
-// {
-// int iResult=0;
-// return iResult;
-// }
+int AliHLTTask::EndRun()
+{
+ int iResult=0;
+ return iResult;
+}
+int AliHLTTask::ProcessTask()
+{
+ int iResult=0;
+ if (fpComponent && fpBlockDataArray) {
+ int iSourceDataBlock=0;
+ int iInputDataVolume=0;
+
+ int iNofInputDataBlocks=0;
+ /* TODO: the assumption of only one output data type per component is the current constraint
+ * later it should be checked how many output blocks of the source component match the input
+ * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
+ * certain output block is always been produced, the initialization could be done in the
+ * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
+ */
+ iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
+ // is not been used since the allocation was done in StartRun, but check the size
+ if (iNofInputDataBlocks>fBlockDataArraySize) {
+ HLTError("block data array too small");
+ }
+
+ AliHLTTask* pSrcTask=NULL;
+ TList subscribedTaskList;
+ TObjLink* lnk=fListDependencies.FirstLink();
+
+ // subscribe to all source tasks
+ while (lnk && iResult>=0) {
+ pSrcTask=(AliHLTTask*)lnk->GetObject();
+ if (pSrcTask) {
+ if (pSrcTask->GetNofMatchingDataBlocks(this)<fBlockDataArraySize-iSourceDataBlock) {
+ if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
+ for (int i=0; i<iResult; i++) {
+ iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
+ // put the source task as many times into the list as it provides data blocks
+ // makes the bookkeeping for the data release easier
+ subscribedTaskList.Add(pSrcTask);
+ }
+ iSourceDataBlock+=iResult;
+ HLTDebug("Task %s (%p) successfully subscribed to %d data blocks of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
+ iResult=0;
+ } else {
+ HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
+ iResult=-EFAULT;
+ }
+ } else {
+ HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
+ iResult=-EFAULT;
+ }
+ } else {
+ HLTFatal("fatal internal error in ROOT list handling");
+ iResult=-EFAULT;
+ }
+ lnk=lnk->Next();
+ }
+
+ // process the event
+ if (iResult>=0) {
+ long unsigned int iConstBase=0;
+ double fInputMultiplier=0;
+ fpComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
+ int iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
+ AliHLTUInt8_t* pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
+ AliHLTComponent_EventData evtData;
+ AliHLTComponent_TriggerData trigData;
+ AliHLTUInt32_t size=iOutputDataSize;
+ AliHLTUInt32_t outputBlockCnt=0;
+ AliHLTComponent_BlockData* outputBlocks=NULL;
+ AliHLTComponent_EventDoneData* edd;
+ if (pTgtBuffer!=NULL || iOutputDataSize==0) {
+ iResult=fpComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
+ } else {
+ }
+ }
+
+ // now release all buffers which we have subscribed to
+ iSourceDataBlock=0;
+ lnk=subscribedTaskList.FirstLink();
+ while (lnk) {
+ pSrcTask=(AliHLTTask*)lnk->GetObject();
+ if (pSrcTask) {
+ int iTempRes=0;
+ if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
+ HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
+ } else {
+ HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
+ }
+ } else {
+ HLTFatal("fatal internal error in ROOT list handling");
+ iResult=-EFAULT;
+ }
+ subscribedTaskList.Remove(lnk);
+ lnk=subscribedTaskList.FirstLink();
+ iSourceDataBlock++;
+ }
+ if (subscribedTaskList.GetSize()>0) {
+ HLTError("task %s (%p): could not release all data buffers", GetName(), this);
+ }
+ } else {
+ HLTError("internal failure: task not initialized");
+ iResult=-EFAULT;
+ }
+ return iResult;
+}
+
+int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask)
+{
+ int iResult=0;
+ if (pConsumerTask) {
+ if (fpDataBuffer) {
+ iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
+ } else {
+ HLTFatal("internal data buffer missing");
+ iResult=-EFAULT;
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
+
+int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask)
+{
+ int iResult=0;
+ if (pConsumerTask) {
+ AliHLTComponent* pComponent=GetComponent();
+ if (!pComponent) {
+ // init
+ }
+ if (pComponent) {
+ iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
+ } else {
+ HLTFatal("task initialization failed");
+ iResult=-EFAULT;
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
+
+int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponent_BlockData* pBlockDesc, int iArraySize)
+{
+ int iResult=0;
+ if (pConsumerTask) {
+ if (fpDataBuffer) {
+ iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), pBlockDesc, iArraySize);
+ } else {
+ HLTFatal("internal data buffer missing");
+ iResult=-EFAULT;
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
+
+int AliHLTTask::Release(AliHLTComponent_BlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
+{
+ int iResult=0;
+ if (pConsumerTask && pBlockDesc) {
+ if (fpDataBuffer) {
+ iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
+ } else {
+ HLTFatal("internal data buffer missing");
+ iResult=-EFAULT;
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
+/* this function is most likely depricated
int AliHLTTask::ClearSourceBlocks()
{
int iResult=0;
return iResult;
}
+*/
void AliHLTTask::PrintStatus()
{
/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice */
-/* AliHLTConfiguration
- base class for HLT configurations
- */
+/** @file AliHLTConfiguration.h
+ @author Matthias Richter
+ @date
+ @brief base class and handling of HLT configurations.
+*/
#include <cerrno>
#include <TObject.h>
#include <TList.h>
#include "AliHLTDataTypes.h"
#include "AliHLTLogging.h"
+#include "AliHLTDataBuffer.h"
class AliHLTConfigurationHandler;
-/*****************************************************************************************************
- *
- * AliHLTConfiguration
- *
- * this class describes a certain configuration af an HLT processing step by the following parameters:
- * - a unique id string/name
- * - the id of the component
- * - the ids of the configurations it requires input from
- * - the arguments, which are passed to the component when it is initialized
+
+/**
+ * @class AliHLTConfiguration
+ * This class describes a certain configuration af an HLT processing step
+ * by the following parameters:
+ * - a unique id string/name
+ * - the id of the component
+ * - the ids of the configurations it requires input from
+ * - the arguments, which are passed to the component when it is initialized
*
- * The setup of a configuration requires simply the creation of a global object of class AliHLTConfiguration.
- * The Configuration is automatically registered in the list of available configurations. The list is used
- * by the handler to resolve the dependencies upon other configurations. Hierarchies can be built up in
- * an easy way.
+ * The setup of a configuration requires simply the creation of a global object
+ * of @class AliHLTConfiguration. The Configuration is automatically registered
+ * in the list of available configurations maintained by the @class
+ * AliHLTConfigurationHandler. The list is used by to resolve the dependencies
+ * on other configurations. Hierarchies can be built up in an easy way.
*
- * A configuration is interpreted by the Configuration Handler and transformed into a Task List.
+ * A configuration is interpreted by the @class AliHLTConfigurationHandler and
+ * transformed into a Task List.
+ * @ingroup AliHLTbase
*/
class AliHLTConfiguration : public TObject, public AliHLTLogging {
public:
+ /**
+ * standard constructor. The configuration is automatically registered in the
+ * global configuration manager
+ */
AliHLTConfiguration();
- AliHLTConfiguration(const char* id, const char* component, const char* sources, const char* arguments);
+ /**
+ * constructor. The configuration is automatically registered in the
+ * global configuration manager
+ * @param id unique id of the configuration
+ * @param component component id
+ * @param sources blank separated list of source configuration ids
+ * @param arguments argument string passed to the component at initialization
+ */
+ AliHLTConfiguration(const char* id, const char* component,
+ const char* sources, const char* arguments);
+ /** destructor */
virtual ~AliHLTConfiguration();
- /****************************************************************************************************
+ /*****************************************************************************
* global initialization
*/
+
+ /**
+ * Global initialization of the configuration handler.
+ */
static int GlobalInit(AliHLTConfigurationHandler* pHandler);
+ /**
+ * Global de-init and cleanup of the global configuration handler
+ */
static int GlobalDeinit();
- /****************************************************************************************************
- * properties
+ /*****************************************************************************
+ * properties of the configuration
*/
- // configuration id, a unique name
- // overridden TObject function in order to return the configuration name instead of the class name
- // enables use of TList standard functions
+ /**
+ * Get configuration id, a unique name
+ * This is an overridden TObject function in order to return the configuration
+ * name instead of the class name. Enables use of TList standard functions.
+ * @return configuration id
+ */
const char *GetName() const;
- // id of the component
+ /**
+ * Get id of the component.
+ * The id is a unique string.
+ * @return id of the component
+ */
const char* GetComponentID() {return fComponent;}
- // print status info
+ /**
+ * Print status info.
+ * Short summary on id, component, sources and unresolved sources.
+ */
void PrintStatus();
- // get a certain source
+ /**
+ * Get a certain source.
+ * @param id of the source configuration
+ * @result pointer to the corresponding configuration descriptor
+ */
AliHLTConfiguration* GetSource(const char* id);
- // try to find a dependency recursively in the list of sources
- // parameter:
- // id - the source to search for
- // pTgtList - (optional) target list to receive the dependency tree
- // result:
- // 0 if not found
- // n found in the n-th level
- // dependency list in the target list
+ /**
+ * Try to find a dependency recursively in the list of sources.
+ * @param id the source to search for
+ * @param pTgtList (optional) target list to receive the dependency tree
+ * @return
+ * 0 if not found
+ * n found in the n-th level
+ * dependency list in the target list
+ */
int FollowDependency(const char* id, TList* pTgtList=NULL);
- // get the number of resolved sources
+ /**
+ * Get the number of resolved sources.
+ * @return number of resolved sources
+ */
int GetNofSources() {return fListSources.size();}
- // 1 if all sources are resolved
- // try to resolve if bAuto==1
+ /**
+ * Check resolving status.
+ * @param bAuto resolve if ==1
+ * @return 1 if all sources resolved
+ */
int SourcesResolved(int bAuto=0);
- // start iteration and get the first source
+ /**
+ * Start iteration and get the first source.
+ * @result pointer to the first configuration descriptor
+ */
AliHLTConfiguration* GetFirstSource();
- // continue iteration and get the next source
+ /**
+ * Continue iteration and get the next source.
+ * @result pointer to the next configuration descriptor in the list
+ */
AliHLTConfiguration* GetNextSource();
- // invalidate a dependency and mark the configuration to be re-evaluted
+ /**
+ * Invalidate a dependency and mark the configuration to be re-evaluted.
+ * @param pConf pointer to configuration descriptor
+ */
int InvalidateSource(AliHLTConfiguration* pConf);
- // mark the configuration to be re-evaluted
+ /**
+ * Mark the configuration to be re-evaluted.
+ */
int InvalidateSources() {fNofSources=-1; return 0;}
- // return the arguments array
- int GetArguments(int* pArgc, const char*** pArgv);
+ /**
+ * Get the arguments array.
+ * @param pArgv pointer to receive argument array pointer
+ * @return argc if succeeded, neg. error code if failed
+ */
+ int GetArguments(const char*** pArgv);
protected:
*/
int InterpreteString(const char* arg, vector<char*>& argList);
- const char* fID; // id of this configuration
- const char* fComponent; // component id of this configuration
+ /** id of this configuration */
+ const char* fID;
+ /** component id of this configuration */
+ const char* fComponent;
- const char* fStringSources; // the 'sources' string as passed to the constructor
+ /** the <i>sources</i> string as passed to the constructor */
+ const char* fStringSources;
+ /** number of resolved sources, -1 indicates re-evaluation */
int fNofSources;
- vector<AliHLTConfiguration*> fListSources; // list of sources
- vector<AliHLTConfiguration*>::iterator fListSrcElement; // iterator for the above list
-
- const char* fArguments; // the arguments string as passed to the constructor
- int fArgc; // number of arguments
- char** fArgv; // argument array
+ /** list of sources */
+ vector<AliHLTConfiguration*> fListSources;
+ /** iterator for the above list */
+ vector<AliHLTConfiguration*>::iterator fListSrcElement;
+
+ /**
+ * The argument string as passed to the constructor.
+ * Specifies the arguments for the Analysys component. The string will
+ * be parsed and the separated arguments stored in the @ref fArgv array
+ * and @ref fArgc member.
+ */
+ const char* fArguments;
+ /** number of arguments */
+ int fArgc;
+ /** argument array */
+ char** fArgv;
static AliHLTConfigurationHandler* fConfigurationHandler;
class AliHLTComponent;
class AliHLTComponentHandler;
-/*****************************************************************************************************
- *
- * AliHLTTask
- *
- * a task collects all the information which is necessary to process a certain step in the HLT data
- * processing chain:
- * 1. the instance of the component
- * 2. the data buffer which receives the result of the component and provides the data to other
- * tasks/components
- * 3. a list of all dependencies
- * 4. a list of consumers
- * 5. the task object holds the configuration object
- */
+/******************************************************************************/
+
+ /**
+ * @class AliHLTTask
+ * A task collects all the information which is necessary to process a certain
+ * step in the HLT data processing chain:
+ * - the instance of the component
+ * - the data buffer which receives the result of the component and provides
+ * the data to other tasks/components
+ * - a list of all dependencies
+ * - a list of consumers
+ * - the task object holds the configuration object
+ */
class AliHLTTask : public TObject, public AliHLTLogging {
public:
+ /** standard constructor */
AliHLTTask();
- AliHLTTask(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH);
+ /** constructor
+ @param pConf pointer to configuration descriptor
+ @param pCH the HLT component handler
+ */
+ AliHLTTask(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH);
+ /** destructor */
virtual ~AliHLTTask();
- /* initialize the task
+ /**
+ * Initialize the task.
+ * The task is initialized with a configuration descriptor. It needs a
+ * component handler instance to create the analysis component.
+ * @param pConf pointer to configuration descriptor
+ * @param pCH the HLT component handler
*/
- int Init(AliHLTConfiguration* fConf, AliHLTComponentHandler* pCH);
+ int Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH);
- // overridden TObject function in order to return the configuration name instead of the class name
- // enables use of TList standard functions
+ /**
+ * Get the name of the object.
+ * This is an overridden TObject function in order to return the configuration
+ * name instead of the class name. Enables use of TList standard functions.
+ * @return name of the configuration
+ */
const char *GetName() const;
- /* return pointer to configuration
- * the tasks holds internally the configuration object, which is returned by the function
+ /**
+ * Return pointer to configuration.
+ * The tasks holds internally the configuration object.
+ * @return pointer to configuration
*/
- AliHLTConfiguration* GetConf();
+ AliHLTConfiguration* GetConf() const;
- /* return pointer to component, which the task internally holds
+ /**
+ * Return pointer to component, which the task internally holds.
+ * <b>Never delete this object!!!</b>
+ * @return instance of the component
*/
- AliHLTComponent* GetComponent();
-
- /* find a dependency with name/id
- * searches in the list of dependencies for a task
- * NOTE: the id specifies a CONFIGURATION not a COMPONENT
+ AliHLTComponent* GetComponent() const;
+
+ /**
+ * Find a dependency with a certain <i>name/id<i>.
+ * Searches in the list of dependencies for a task.
+ * @param id the id of the <b>CONFIGURATION</b><br>
+ * <b>NOTE:</b> the id does NOT specify a COMPONENT
+ * @return pointer to task
*/
AliHLTTask* FindDependency(const char* id);
- /* insert block data to the list
- * the data has to come from a task the current one depend on
+ /*
+ * insert block data to the list
+ * the data has to come from a task the current one depends on
* result:
* -EEXIST : the block data from this task has already been inserted
* -ENOENT : no dependencies to the task the data is coming from
*/
+ /*
+ * this function is most likely depricated
int InsertBlockData(AliHLTComponent_BlockData* pBlock, AliHLTTask* pSource);
-
- /* add a dependency for the task
- * the task which the current task depends on is added to the list
- * result: 0 if suceeded, neg error code if failed
- * -EEXIST : the dependencies already exists
+ */
+
+ /**
+ * Add a dependency for the task.
+ * The task maintains a list of other tasks it depends on.
+ * @param pDep pointer to a task descriptor
+ * @return 0 if suceeded, neg error code if failed <br>
+ * -EEXIST : the dependencie exists already
*
*/
int SetDependency(AliHLTTask* pDep);
- /* return number of unresolved dependencies
- * iterate through all the configurations the task depends on and check whether a corresponding
- * task is available in the list
+ /**
+ * Return number of unresolved dependencies.
+ * Iterate through all the configurations the task depends on and check
+ * whether a corresponding task is available in the list.
+ * @return number of unresolved dependencies
*/
int CheckDependencies();
- /* check whether the current task depends on the task pTask
- * result:
- * 1 the current task depends upon pTask
- * 0 no dependency
- * neg error code if failure
+ /**
+ * Check whether the current task depends on the task pTask.
+ * @param pTask pointer to Task descriptor
+ * @return 1 the current task depends on pTask <br>
+ * 0 no dependency <br>
+ * neg. error code if failed
*/
int Depends(AliHLTTask* pTask);
- /* find a target
+ /**
+ * Find a target with a certain id.
+ * Tasks which depend on the current task are referred to be <i>targets</i>.
+ * @param id configuration id to search for
+ * @return pointer to task instance
*/
AliHLTTask* FindTarget(const char* id);
- /* insert task into target list
+ /**
+ * Insert task into target list.
+ * The target list specifies all the tasks which depend on the current task.
+ * @param pDep pointer task object
+ * @return >=0 if succeeded, neg. error code if failed
*/
int SetTarget(AliHLTTask* pDep);
// build a monolithic array of block data
- // result: array size, pointer to array in the target pTgt
+ // @param pBlockData reference to the block data target
+ // @return: array size, pointer to array in the target pTgt
//
- int BuildBlockDataArray(AliHLTComponent_BlockData*& pTgt);
+ /* this function is most likely depricated
+ int BuildBlockDataArray(AliHLTComponent_BlockData*& pBlockData);
+ */
+
+ /**
+ * Prepare the task for event processing.
+ * The method initializes the Data Buffer and calls the
+ * @ref AliHLTComponent::Init method of the component.<br>
+ * The @ref ProcessTask methode can be called an arbitrary number of times
+ * as soon as the task is in <i>running</i> mode.
+ */
+ int StartRun();
- /* process the task if all dependencies are resolved
- * reset the source block data list
+ /**
+ * Clean-up the task after event processing.
+ * The method cleans up internal structures and calls the
+ * @ref AliHLTComponent::Deinit method of the component.
+ */
+ int EndRun();
+
+ /**
+ * Process the task.
+ * If all dependencies are resolved the tasks subscribes to the data of
+ * all source tasks, builds the block descriptor and calls the
+ * @ref AliHLTComponent::ProcessEvent method of the component, after
+ * processing, the data blocks are released. <br>
+ * The @ref StartRun method must be called before.
*/
- //int ProcessTask(...);
+ int ProcessTask();
// clear the list of source data blocks
// the list of source data blocks has to be cleared at the beginning of
// a new event
+ /* this function is most likely depricated
int ClearSourceBlocks();
+ */
+
+ /**
+ * Determine the number of matching data block between the component and the
+ * data buffer of a consumer component. It checks which data types from the
+ * list of input data types of the consumer component can be provided by data
+ * blocks of the current component.
+ * @param pConsumerTask the task which subscribes to the data
+ * @return number of matching data blocks
+ */
+ int GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask);
+
+ /**
+ * Determine the number of matching data types between the component and a
+ * consumer component. It checks which data types from the list of input data
+ * types of the consumer component can be provided by the current component.
+ * @param pConsumerTask the task which subscribes to the data
+ * @return number of matching data types
+ */
+ int GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask);
+
+ /**
+ * Subscribe to the data of a source task.
+ * The function prepares the block descriptors for subsequent use with the
+ * @ref AliHLTComponent::ProcessEvent method, the method prepares all block
+ * descriptors which match the input data type of the consumer the function
+ * returns the number of blocks which would be prepared in case the target
+ * array is big enough.
+ * @param pConsumerTask the task which subscribes to the data
+ * @param arrayBlockDesc pointer to block descriptor to be filled
+ * @param iArraySize size of the block descriptor array
+ * @return number of matching data blocks, negative error code if failed
+ */
+ int Subscribe(const AliHLTTask* pConsumerTask,
+ AliHLTComponent_BlockData* arrayBlockDesc, int iArraySize);
+
+ /**
+ * Release a block descriptor.
+ * Notification from consumer task.
+ * @param pBlockDesc descriptor of the data segment
+ * @param pConsumerTask the task which subscribed to the data
+ * @return: >0 if success, negative error code if failed
+ */
+ int Release(AliHLTComponent_BlockData* pBlockDesc,
+ const AliHLTTask* pConsumerTask);
- // print the status of the task with component, dependencies and targets
+ /**
+ * Print the status of the task with component, dependencies and targets.
+ */
void PrintStatus();
- // search task dependency list recursively to find a dependency
- // parameter:
- // id - the task to search for
- // pTgtList - (optional) target list to receive the dependency tree
- // result:
- // 0 if not found
- // n found in the n-th level
- // dependency list in the target list
+ /**
+ * Search task dependency list recursively to find a dependency.
+ * @param id id of the task to search for
+ * @param pTgtList (optional) target list to receive dependency tree
+ * @return 0 if not found, >0 found in the n-th level,
+ dependency list in the target list
+ */
int FollowDependency(const char* id, TList* pTgtList=NULL);
- // print the tree for a certain dependency either from the task or configuration list
- // each task posseses two "link lists": The configurations are the the origin of the
- // task list. In case of an error during the built of the task list, the dependencies
- // for the task list might be incomplete. In this case the configurations can give
- // infomation on the error reason
- // parameter:
- // id - the dependency to search for
- // bFromConfiguration (default=0) - if 0 the task dependency list is used, if one the configuration list is used
- void PrintDependencyTree(const char* id, int bFromConfiguration=0);
+ /**
+ * Print the tree for a certain dependency either from the task or
+ * configuration list.
+ * Each task posseses two "link lists": The configurations are the origin
+ * of the task list. In case of an error during the built of the task list,
+ * the dependencies for the task list might be incomplete. In this case the
+ * configurations can give infomation on the error reason.
+ * @param id id of the dependency to search for
+ * @param bMode 0 (default) from task dependency list, <br>
+ * 1 from configuration list
+ */
+ void PrintDependencyTree(const char* id, int bMode=0);
+
+ /**
+ * Get number of source tasks.
+ * @return number of source tasks
+ */
+ int GetNofSources() {return fListDependencies.GetSize();}
private:
+ /** the configuration descriptor */
AliHLTConfiguration* fpConfiguration;
+ /** the component described by this task */
AliHLTComponent* fpComponent;
- vector<AliHLTComponent_BlockData*> fSources;
+ /** the data buffer for the component processing */
+ AliHLTDataBuffer* fpDataBuffer;
+ /** the list of targets (tasks which depend upon the current one) */
TList fListTargets;
+ /** the list of sources (tasks upon which the current one depends) */
TList fListDependencies;
+ /**
+ * block data array to be passed as argument to the
+ * @ref AliHLTComponent::ProcessEvent method.
+ * Filled through subscription to source tasks (@ref Subscribe).
+ */
AliHLTComponent_BlockData* fpBlockDataArray;
+ /** size of the block data array */
+ int fBlockDataArraySize;
ClassDef(AliHLTTask, 0);
};
//AliHLTConfigurationHandler(AliHLTConfiguration* pConf);
virtual ~AliHLTConfigurationHandler();
- /****************************************************************************************************
+ /*****************************************************************************
* registration
*/
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
AliHLTConsumerDescriptor::AliHLTConsumerDescriptor()
{
fpConsumer=NULL;
- memset(&fDataType, 0, sizeof(AliHLTComponent_DataType));
- fDataType.fStructSize=sizeof(AliHLTComponent_DataType);
- fpSegment=NULL;
+ fSegments.clear();
}
-AliHLTConsumerDescriptor::AliHLTConsumerDescriptor(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype)
+AliHLTConsumerDescriptor::AliHLTConsumerDescriptor(AliHLTComponent* pConsumer)
{
fpConsumer=pConsumer;
- fDataType=datatype;
- fpSegment=NULL;
+ fSegments.clear();
}
AliHLTConsumerDescriptor::~AliHLTConsumerDescriptor()
{
+ if (fSegments.size()>0) {
+ //HLTWarning("unreleased data segments found");
+ }
}
-int AliHLTConsumerDescriptor::SetActiveDataSegment(AliHLTDataSegment* pSegment)
+int AliHLTConsumerDescriptor::SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
{
int iResult=0;
+ AliHLTDataSegment segment(offset, size);
+ fSegments.push_back(segment);
+ //HLTDebug("set active segment (%d:%d) for consumer %p", offset, size, this);
return iResult;
}
int AliHLTConsumerDescriptor::CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
{
int iResult=0;
+ if (fSegments.size()>0) {
+ vector<AliHLTDataSegment>::iterator segment=fSegments.begin();
+ while (segment!=fSegments.end()) {
+ if (iResult=((*segment).fSegmentOffset==offset && (*segment).fSegmentSize==size)) {
+ break;
+ }
+ segment++;
+ }
+ } else {
+ //HLTWarning("no data segment active for consumer %p", this);
+ iResult=-ENODATA;
+ }
return iResult;
}
-int AliHLTConsumerDescriptor::ReleaseActiveDataSegment()
+int AliHLTConsumerDescriptor::ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
{
int iResult=0;
+ if (fSegments.size()>0) {
+ vector<AliHLTDataSegment>::iterator segment=fSegments.begin();
+ while (segment!=fSegments.end()) {
+ if (iResult=((*segment).fSegmentOffset==offset && (*segment).fSegmentSize==size)) {
+ fSegments.erase(segment);
+ break;
+ }
+ segment++;
+ }
+ if (iResult=0) {
+ //HLTWarning("no data segment (%d:%d) active for consumer %p", offset, size, this);
+ iResult=-ENOENT;
+ }
+ } else {
+ //HLTWarning("no data segment active for consumer %p", this);
+ iResult=-ENODATA;
+ }
return iResult;
}
{
// TODO: do the right initialization
//fSegments.empty();
- //fConsumers;
- //fActiveConsumers;
- //fReleasedConsumers;
+ //fConsumers.empty;
+ //fActiveConsumers.empty;
+ //fReleasedConsumers.empty;
fpBuffer=NULL;
fFlags=0;
fNofInstances++;
CleanupConsumerList();
}
-int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype)
+int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer)
{
int iResult=0;
if (pConsumer) {
- AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer, datatype);
+ AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer);
if (pDesc) {
fConsumers.push_back(pDesc);
} else {
return iResult;
}
-int AliHLTDataBuffer::Subscribe(AliHLTComponent_DataType datatype, const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* pBlockDesc)
+int AliHLTDataBuffer::FindMatchingDataBlocks(const AliHLTComponent* pConsumer, vector<AliHLTComponent_DataType>* tgtList)
+{
+ int iResult=0;
+ if (pConsumer) {
+ vector<AliHLTDataSegment> segments;
+ if ((iResult=FindMatchingDataSegments(pConsumer, segments))>=0) {
+ if (tgtList) {
+ vector<AliHLTDataSegment>::iterator segment=segments.begin();
+ while (segment!=segments.end()) {
+ tgtList->push_back((*segment).fDataType);
+ segment++;
+ }
+ }
+ iResult=segments.size();
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
+
+int AliHLTDataBuffer::FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataSegment>& tgtList)
+{
+ int iResult=0;
+ if (pConsumer) {
+ vector<AliHLTComponent_DataType> dtlist;
+ ((AliHLTComponent*)pConsumer)->GetInputDataTypes(dtlist);
+ vector<AliHLTDataSegment>::iterator segment=fSegments.begin();
+ while (segment!=fSegments.end()) {
+ vector<AliHLTComponent_DataType>::iterator type=dtlist.begin();
+ while (type!=dtlist.end()) {
+ if ((*segment).fDataType==(*type)) {
+ tgtList.push_back(*segment);
+ iResult++;
+ break;
+ }
+ type++;
+ }
+ segment++;
+ }
+ } else {
+ iResult=-EINVAL;
+ }
+ return iResult;
+}
+
+int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* arrayBlockDesc, int iArraySize)
{
int iResult=0;
- if (pConsumer && pBlockDesc) {
+ if (pConsumer && arrayBlockDesc) {
if (fpBuffer) {
- AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, datatype, fConsumers);
+ AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fConsumers);
if (pDesc) {
- AliHLTDataSegment* pSegment=FindDataSegment(datatype);
- if (pSegment) {
- // move this consumer to the active list
- if ((iResult=ChangeConsumerState(pDesc, fConsumers, fActiveConsumers))>=0) {
- pDesc->SetActiveDataSegment(pSegment);
+ vector<AliHLTDataSegment> tgtList;
+ /* TODO: think about a good policy for this check
+ * is it enough that at least one segment is available, or have all to be available?
+ * or is it possible to have optional segments?
+ */
+ if ((iResult=FindMatchingDataSegments(pConsumer, tgtList))>0) {
+ int i =0;
+ vector<AliHLTDataSegment>::iterator segment=tgtList.begin();
+ while (segment!=tgtList.end() && i<iArraySize) {
// fill the block data descriptor
- pBlockDesc->fStructSize=sizeof(AliHLTComponent_BlockData);
+ arrayBlockDesc[i].fStructSize=sizeof(AliHLTComponent_BlockData);
// the shared memory key is not used in AliRoot
- pBlockDesc->fShmKey.fStructSize=sizeof(AliHLTComponent_ShmData);
- pBlockDesc->fShmKey.fShmType=0;
- pBlockDesc->fShmKey.fShmID=0;
- pBlockDesc->fOffset=pSegment->fSegmentOffset;
- pBlockDesc->fPtr=fpBuffer->fPtr;
- pBlockDesc->fSize=pSegment->fSegmentSize;
- pBlockDesc->fDataType=pSegment->fDataType;
- pBlockDesc->fSpecification=pSegment->fSpecification;
- HLTDebug("component %p (%s) subscribed to data buffer %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this, datatype.fID);
+ arrayBlockDesc[i].fShmKey.fStructSize=sizeof(AliHLTComponent_ShmData);
+ arrayBlockDesc[i].fShmKey.fShmType=gkAliHLTComponent_InvalidShmType;
+ arrayBlockDesc[i].fShmKey.fShmID=gkAliHLTComponent_InvalidShmID;
+ arrayBlockDesc[i].fOffset=(*segment).fSegmentOffset;
+ arrayBlockDesc[i].fPtr=fpBuffer->fPtr;
+ arrayBlockDesc[i].fSize=(*segment).fSegmentSize;
+ arrayBlockDesc[i].fDataType=(*segment).fDataType;
+ arrayBlockDesc[i].fSpecification=(*segment).fSpecification;
+ pDesc->SetActiveDataSegment(arrayBlockDesc[i].fOffset, arrayBlockDesc[i].fSize);
+ HLTDebug("component %p (%s) subscribed to segment #%d offset %d", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), i, arrayBlockDesc[i].fOffset);
+ i++;
+ segment++;
+ }
+ // move this consumer to the active list
+ if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) {
+ HLTDebug("component %p (%s) subscribed to data buffer %p", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this);
} else {
+ // TODO: cleanup the consumer descriptor correctly
+ memset(arrayBlockDesc, 0, iArraySize*sizeof(AliHLTComponent_BlockData));
HLTError("can not activate consumer %p for data buffer %p", pConsumer, this);
iResult=-EACCES;
}
} else {
- HLTError("unresolved data segment: %s::%s is not available", datatype.fID, datatype.fOrigin);
+ HLTError("unresolved data segment(s) for component %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID());
iResult=-EBADF;
}
} else {
- HLTWarning("can not find consumer %p in component list of data buffer %d", pConsumer, this);
+ HLTError("component %p is not a data consumer of data buffer %s", pConsumer, this);
iResult=-ENOENT;
}
} else {
{
int iResult=0;
if (pBlockDesc && pConsumer) {
- AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, pBlockDesc->fDataType, fActiveConsumers);
- if (pDesc) {
- if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) {
- HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pBlockDesc->fOffset, pBlockDesc->fSize);
- // TODO: appropriate error handling, but so far optional
- iResult=0;
- }
- pDesc->ReleaseActiveDataSegment();
+ AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers);
+ if (pDesc) {
+ if ((iResult=pDesc->CheckActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize))!=1) {
+ HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
+ // TODO: appropriate error handling, but so far optional
+ iResult=0;
+ } else {
+ pDesc->ReleaseActiveDataSegment(pBlockDesc->fOffset, pBlockDesc->fSize);
pBlockDesc->fOffset=0;
pBlockDesc->fPtr=NULL;
pBlockDesc->fSize=0;
+ }
+ if (pDesc->GetNofActiveSegments()==0) {
if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
if (GetNofActiveConsumers()==0) {
- // this is the last consumer, release the raw buffer
- AliHLTRawBuffer* pBuffer=fpBuffer;
+ // this is the last consumer, reset the consumer list and release the raw buffer
ResetDataBuffer();
- ReleaseRawBuffer(pBuffer);
}
} else {
HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
iResult=-EACCES;
}
- } else {
- HLTWarning("component %p has currently not subscribed to the data buffer", pConsumer);
- iResult=-ENOENT;
}
+ } else {
+ HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this);
+ iResult=-ENOENT;
+ }
} else {
HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
iResult=-EINVAL;
{
int iResult=0;
if (pTgt && arrayBlockData && iSize>=0) {
- AliHLTDataSegment segment;
- memset(&segment, 0, sizeof(AliHLTDataSegment));
- for (int i=0; i<iSize; i++) {
- if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<fpBuffer->fSize) {
- segment.fSegmentOffset=arrayBlockData[i].fOffset;
- segment.fSegmentSize=arrayBlockData[i].fSize;
- segment.fDataType=arrayBlockData[i].fDataType;
- segment.fSpecification=arrayBlockData[i].fSpecification;
- fSegments.push_back(segment);
+ if (fpBuffer) {
+ if (fpBuffer->fPtr==(void*)pTgt) {
+ AliHLTDataSegment segment;
+ memset(&segment, 0, sizeof(AliHLTDataSegment));
+ for (int i=0; i<iSize; i++) {
+ if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<fpBuffer->fSize) {
+ segment.fSegmentOffset=arrayBlockData[i].fOffset;
+ segment.fSegmentSize=arrayBlockData[i].fSize;
+ segment.fDataType=arrayBlockData[i].fDataType;
+ segment.fSpecification=arrayBlockData[i].fSpecification;
+ fSegments.push_back(segment);
+ } else {
+ HLTError("block data specification #%d (%s@%s) exceeds size of data buffer", i, arrayBlockData[i].fDataType.fOrigin, arrayBlockData[i].fDataType.fID);
+ }
+ }
} else {
- HLTError("block data specification #%d (%s@%s) exceeds size of data buffer", i, arrayBlockData[i].fDataType.fOrigin, arrayBlockData[i].fDataType.fID);
+ HLTError("this data buffer (%p) does not match the internal data buffer %p of raw buffer %p", pTgt, fpBuffer->fPtr, fpBuffer);
}
+ } else {
+ HLTFatal("internal data structur missmatch");
+ iResult=-EFAULT;
}
} else {
- HLTError("inavalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
+ HLTError("invalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
iResult=-EINVAL;
}
return iResult;
pRawBuffer=*buffer;
pRawBuffer->fSize=size;
fFreeBuffers.erase(buffer);
- //HLTDebug("raw buffer container %p provided for request of %d bytes (total %d available in buffer %p)", pRawBuffer, size, pRawBuffer->fTotalSize, pRawBuffer->fPtr);
+ fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "raw buffer container %p provided for request of %d bytes (total %d available in buffer %p)", pRawBuffer, size, pRawBuffer->fTotalSize, pRawBuffer->fPtr);
fActiveBuffers.push_back(pRawBuffer);
- } else {
- // check the next element
- buffer++;
+ break;
}
+ buffer++;
}
if (pRawBuffer==NULL) {
+ // no buffer found, create a new one
pRawBuffer=new AliHLTRawBuffer;
if (pRawBuffer) {
memset(pRawBuffer, 0, sizeof(AliHLTRawBuffer));
pRawBuffer->fSize=size;
pRawBuffer->fTotalSize=size;
fActiveBuffers.push_back(pRawBuffer);
- //HLTDebug("new raw buffer %p of size %d created (container %p)", pRawBuffer->fPtr, pRawBuffer->fTotalSize, pRawBuffer);
+ fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "new raw buffer %p of size %d created (container %p)", pRawBuffer->fPtr, pRawBuffer->fTotalSize, pRawBuffer);
} else {
delete pRawBuffer;
pRawBuffer=NULL;
- //HLTError("memory allocation failed");
+ fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed");
}
} else {
- //HLTError("memory allocation failed");
+ fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "memory allocation failed");
}
}
return pRawBuffer;
fFreeBuffers.push_back(*buffer);
fActiveBuffers.erase(buffer);
} else {
- //HLTWarning("can not find raw buffer container %p in the list of active containers", pBuffer);
+ fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "can not find raw buffer container %p in the list of active containers", pBuffer);
iResult=-ENOENT;
}
} else {
- //HLTError("invalid parameter");
+ fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "invalid parameter");
iResult=-EINVAL;
}
return iResult;
}
buffer=fActiveBuffers.begin();
while (buffer!=fFreeBuffers.end()) {
- //HLTWarning("request to delete active raw buffer container %d (raw buffer %p, size %d)", *buffer, *buffer->fPtr, *buffer->fTotalSize);
+ fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "request to delete active raw buffer container (raw buffer %p, size %d)", (*buffer)->fPtr, (*buffer)->fTotalSize);
free((*buffer)->fPtr);
delete *buffer;
fActiveBuffers.erase(buffer);
return iResult;
}
-AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype, vector<AliHLTConsumerDescriptor*> &list)
+AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, vector<AliHLTConsumerDescriptor*> &list)
{
AliHLTConsumerDescriptor* pDesc=NULL;
vector<AliHLTConsumerDescriptor*>::iterator desc=list.begin();
while (desc!=list.end() && pDesc==NULL) {
- if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer) && (*desc)->GetDataType()==datatype) {
+ if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer)) {
pDesc=*desc;
}
+ desc++;
}
return pDesc;
}
-int AliHLTDataBuffer::ResetDataBuffer() {
+int AliHLTDataBuffer::ResetDataBuffer()
+{
int iResult=0;
+ AliHLTRawBuffer* pBuffer=fpBuffer;
fpBuffer=NULL;
vector<AliHLTConsumerDescriptor*>::iterator desc=fReleasedConsumers.begin();
while (desc!=fReleasedConsumers.end()) {
desc=fActiveConsumers.begin();
fConsumers.push_back(pDesc);
}
+ ReleaseRawBuffer(pBuffer);
return iResult;
}
+// this is the version which works on lists of components instead of consumer descriptors
+// int AliHLTDataBuffer::ChangeConsumerState(AliHLTComponent* pConsumer, vector<AliHLTComponent*> &srcList, vector<AliHLTComponent*> &tgtList)
+// {
+// int iResult=0;
+// if (pDesc) {
+// vector<AliHLTComponent*>::iterator desc=srcList.begin();
+// while (desc!=srcList.end()) {
+// if ((*desc)==pConsumer) {
+// srcList.erase(desc);
+// tgtList.push_back(pConsumer);
+// break;
+// }
+// desc++;
+// }
+// if (desc==srcList.end()) {
+// HLTError("can not find consumer component %p in list", pConsumer);
+// iResult=-ENOENT;
+// }
+// } else {
+// HLTError("invalid parameter");
+// iResult=-EINVAL;
+// }
+// return iResult;
+// }
+
int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList)
{
int iResult=0;
tgtList.push_back(pDesc);
break;
}
+ desc++;
}
if (desc==srcList.end()) {
HLTError("can not find consumer descriptor %p in list", pDesc);
}
return iResult;
}
-
-AliHLTDataSegment* AliHLTDataBuffer::FindDataSegment(AliHLTComponent_DataType datatype)
-{
- AliHLTDataSegment* pSegment=NULL;
- vector<AliHLTDataSegment>::iterator segment=fSegments.begin();
- while (segment!=fSegments.end() && pSegment==NULL) {
- if ((*segment).fDataType==datatype) {
- // TODO: check this use of the vector
- //pSegment=segment;
- }
- }
- return pSegment;
-}
/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice */
-/* AliHLTDataBuffer
- handling of data buffers for the HLT
- */
#include <cerrno>
#include "AliHLTLogging.h"
#include "TObject.h"
#include "TList.h"
-/* internal data structure
+/* @name internal data structures
+ */
+
+/* @struct AliHLTDataSegment
+ * @brief descriptor of a data segment within the buffer
+ * @ingroup AliHLTbase
*/
struct AliHLTDataSegment {
+ AliHLTDataSegment()
+ {
+ //fDataType=0;
+ fSegmentOffset=0;
+ fSegmentSize=0;
+ fSpecification=0;
+ }
+ AliHLTDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size)
+ {
+ //fDataType=0;
+ fSegmentOffset=offset;
+ fSegmentSize=size;
+ fSpecification=0;
+ }
AliHLTComponent_DataType fDataType; // the data type of this buffer
- Int_t fSegmentOffset; // offset in byte within the data buffer
- Int_t fSegmentSize; // size of the actual content
+ AliHLTUInt32_t fSegmentOffset; // offset in byte within the data buffer
+ AliHLTUInt32_t fSegmentSize; // size of the actual content
AliHLTUInt32_t fSpecification; // data specification
};
-/* internal data structure
+/* @struct AliHLTRawBuffer
+ * @brief descriptor of the raw data buffer which can host several segments
+ * @ingroup AliHLTbase
*/
struct AliHLTRawBuffer {
- AliHLTUInt32_t fSize; // size of the buffer
- AliHLTUInt32_t fTotalSize; // total size of the buffer, including safety margin
+ AliHLTUInt32_t fSize; // size of the buffer
+ AliHLTUInt32_t fTotalSize; // total size of the buffer, including safety margin
void* fPtr; // the buffer
};
-/* internal data structure
- * there is unfortunately no unique determination of the data type from the component
- * itself possible, thats way both component and data type have to be initialized
- * and are stored in a compound
+/* @struct AliHLTConsumerDescriptor
+ * @brief there is unfortunately no unique determination of the data type from the component
+ * itself possible, thats why both component and data type have to be initialized
+ * and are stored in a compound. The class is intended to make bookkeeping easier
+ * @ingroup AliHLTbase
*/
-class AliHLTConsumerDescriptor : public TObject, public AliHLTLogging {
+class AliHLTConsumerDescriptor : public AliHLTLogging, public TObject {
private:
AliHLTComponent* fpConsumer;
- AliHLTComponent_DataType fDataType;
- AliHLTDataSegment* fpSegment;
+ vector<AliHLTDataSegment> fSegments;
public:
+ /** standard constructur */
AliHLTConsumerDescriptor();
- AliHLTConsumerDescriptor(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype);
+ /** constructur
+ * @param pConsumer pointer to the consumer component
+ */
+ AliHLTConsumerDescriptor(AliHLTComponent* pConsumer);
~AliHLTConsumerDescriptor();
+ /**
+ * Get the component of this descriptor
+ * @return pointer to the component
+ */
AliHLTComponent* GetComponent() {return fpConsumer;}
- AliHLTComponent_DataType GetDataType() {return fDataType;}
- int SetActiveDataSegment(AliHLTDataSegment* pSegment);
+ /**
+ * Set an active data segment
+ * the pointer will be handled in a container, not allocation, copy or cleanup
+ * @param pSegment pointer to the segment instance
+ * @return >=0 if succeeded
+ */
+ int SetActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
+
+ /**
+ * check whether there is an active data segment of certain size with certain offset
+ * @param offset offset of the data segment in the data buffer
+ * @param size size of the data segment in the data buffer
+ * @return > if existend, 0 if not
+ */
int CheckActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
- int ReleaseActiveDataSegment();
+
+ /** find an active data segment of certain size with certain offset
+ * will see if this is necessary
+ * @param offset offset of the data segment in the data buffer
+ * @param size size of the data segment in the data buffer
+ * @return offset of the data segment
+ */
+ //AliHLTUInt32_t FindActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
+
+ /** get the number of active segments for this consumer
+ * @return number of active segments
+ */
+ int GetNofActiveSegments() {return fSegments.size();};
+
+ /**
+ */
+ int ReleaseActiveDataSegment(AliHLTUInt32_t offset, AliHLTUInt32_t size);
+
+ //ClassDef(AliHLTConsumerDescriptor, 0)
};
+/**
+ * @class AliHLTDataBuffer handling of data buffers for the HLT
+ * @note Definition:
+ * The class provides handling of data buffers for HLT components. Each component gets its
+ * own Data Buffer instance. The buffer is grouped into different data segments according
+ * to the output of the component.<br>
+ * The Data Buffer keeps control over the data requests of the 'child' componets. Each
+ * component can subscribe to a certain segment of the data buffer. It's state is that
+ * changed from 'reserved' to 'active'. After the data processing the component has to
+ * release the segment and it's state is set to 'processed'.
+ * If all components have requested and released their data, the Raw Buffer is released
+ * and pushed back in the list of available buffers.
+ * @ingroup AliHLTbase
+ */
class AliHLTDataBuffer : public AliHLTLogging, public TObject {
public:
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // condtructors and destructors
+
+ /* standard constructor
+ */
AliHLTDataBuffer();
+
virtual ~AliHLTDataBuffer();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// initialization
- /* add component to the list of consumers
- * parameter:
- * pConsumer - a consumer of type AliHLTComponent
- * datatype - data type of the segement, the consumer is registered for
+ /**
+ * Add component to the list of consumers
+ * @param pConsumer - a consumer of type AliHLTComponent
+ * @param datatype - data type of the segement, the consumer is registered for
*/
- int SetConsumer(AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype);
+ int SetConsumer(AliHLTComponent* pConsumer);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// component to component communication
- /* subscribe to a segment of the data buffer
- * the function prepares the block descriptor for subsequent use with the AliHLTComponent::ProcessEvent
- * method
- * parameter:
- * datatype - type of the data segment
- * pConsumer - the component which subscribes to the buffer
- * pBlockDesc - pointer to receive the prepared block descriptor
- * return: >0 if success, negative error code if failed
+ /**
+ * Determine the number of matching data blocks for the component and a consumer
+ * component. <br>
+ * The first approach will support only one output data type for processing components.
+ * @param pConsumer the component which subscribes to the buffer
+ * @param tgtList (optional) the list to receive the data types
+ * @return: number of data blocks which match the input data types
+ * of the consumer, neg. error code if failed <br>
+ * -EINVAL invalid parameter <br>
*/
- int Subscribe(AliHLTComponent_DataType datatype, const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* pBlockDesc);
-
- /* release an instance of the data buffer
- * resets the variables of the block descriptor
- * parameter:
- * pBlockDesc - descriptor of the data segment
- * pConsumer - the component which subscribes to the buffer
- * return: >0 if success, negative error code if failed
+ int FindMatchingDataBlocks(const AliHLTComponent* pConsumer, vector<AliHLTComponent_DataType>* tgtList=NULL);
+
+ /**
+ * Subscribe to a segment of the data buffer.
+ * The function prepares the block descriptor for subsequent use with the AliHLTComponent::ProcessEvent
+ * method, the method can prepare several block descriptors up to the array size specified by @param
+ * iArraySize. The return value is independent from the array size the number of block descriptors
+ * which would have been prepared if there was enough space in the array<br>
+ * The method is used by the consumer component.
+ * @param pConsumer the component which subscribes to the buffer
+ * @param arrayBlockDesc pointer to block descriptor to be filled
+ * @param iArraySize size of the block descriptor array
+ * @return: number of matching data blocks if success, negative error code if failed<br>
+ * -EACCESS the state of the consumer can not be changed (activated)
+ * -EBADF unresolved data segments <br>
+ * -ENOENT consumer component not found <br>
+ * -ENODATA data buffer does not have raw data <br>
+ * -EINVAL invalid parameter <br>
+ */
+ int Subscribe(const AliHLTComponent* pConsumer, AliHLTComponent_BlockData* arrayBlockDesc, int iArraySize);
+
+ /**
+ * Release an instance of the data buffer.
+ * Resets the variables of the block descriptor.
+ * If all buffer segments are released, the Data Buffer is reseted
+ * and the Raw Buffer released.<br>
+ * The method is used by the consumer component.
+ * @param pBlockDesc descriptor of the data segment
+ * @param pConsumer the component which subscribes to the buffer
+ * @return: >0 if success, negative error code if failed <br>
+ * -EACCESS the state of the consumer can not be changed (de-activated)
+ * -ENOENT consumer component has not subscribed to the buffer <br>
+ * -EINVAL invalid parameter <br>
*/
int Release(AliHLTComponent_BlockData* pBlockDesc, const AliHLTComponent* pConsumer);
- /* get a target buffer if minimum size iMinSize
+ /**
+ * Get a target buffer of minimum size iMinSize.
+ * The method is used by the component which owns the Data Buffer to
+ * allocate a buffer for the data it is going to produce.
+ * @param iMinSize minumum size of the requested buffer
+ * @return: pointer to target buffer if
*/
AliHLTUInt8_t* GetTargetBuffer(int iMinSize);
- /* set the segments for the data buffer
- * this is usually done after the component has written the data to the buffer
- * parameter:
- * pTgt - the target buffer the segments refer to
- * arraySegments - the output block descriptors of the component
- * iSize - size of the array
+ /**
+ * Set the segments for the data buffer.
+ * This is usually done after the component has written the data to the buffer,
+ * which was requested by the @ref GetTargetBuffer method. The component might
+ * produce different types of data, for each type a segment has to be defined
+ * which describes the data inside the bauffer.<br>
+ * The @ref AliHLTComponent_BlockData segment descriptor comes directly from the
+ * @ref AliHLTComponent::ProcessEvent method.
+ * @param pTgt the target buffer which the segments refer to
+ * @param arraySegments the output block descriptors of the component
+ * @param iSize size of the array
*/
int SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponent_BlockData* arraySegments, int iSize);
- /* check if the data buffer is empty
+ /**
+ * Check if the data buffer is empty.
+ * @return 1 if empty, 0 if not
*/
int IsEmpty();
- /* get the total and maximum size of the buffer
- * lets see if this is needed later
+ /**
+ * Get the total and maximum size of the buffer.
+ * Lets see if this is needed later
*/
//int GetTotalSize();
- /* get the number of segments
+ /**
+ * Get the number of segments
+ * @return number of segments
*/
int GetNofSegments();
- /* get the number of consumers
+ /**
+ * Get the number of consumers
+ * @return number of consumers
*/
int GetNofConsumers();
- /* get the number of consumers
+ /**
+ * Get the number of active consumers
+ * @return number of active consumers
*/
int GetNofActiveConsumers();
private:
+ /* lets see if this is needed
AliHLTDataSegment* FindDataSegment(AliHLTComponent_DataType datatype);
+ */
+
+ /**
+ * Find those data segments which match the input types of a component.
+ * @param pConsumer the component which subscribes to the buffer
+ * @param tgtList the list to receive the data segment descriptors
+ * @return: number of data blocks which match the input data types
+ * of the consumer, neg. error code if failed <br>
+ * -EINVAL invalid parameter <br>
+ */
+ int FindMatchingDataSegments(const AliHLTComponent* pConsumer, vector<AliHLTDataSegment>& tgtList);
- /* reset the data buffer
- * removes all condumers back to the fConsumers list
+ /**
+ * Reset the data buffer.
+ * Removes all consumers back to the @ref fConsumers list
+ * and releases the Raw Buffer.
*/
int ResetDataBuffer();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// the data description
- vector<AliHLTDataSegment> fSegments;// the data segments within this buffer
- vector<AliHLTConsumerDescriptor*> fConsumers; // the list of all consumers which are going to subscribe to the buffer
- vector<AliHLTConsumerDescriptor*> fActiveConsumers; // the list of all consumers which are currently subscribed to the buffer
- vector<AliHLTConsumerDescriptor*> fReleasedConsumers; // the list of all consumers which are already released for the current event
+ // the data segments within this buffer
+ vector<AliHLTDataSegment> fSegments;
- AliHLTRawBuffer* fpBuffer; // the buffer instance
+ // the list of all consumers which are going to subscribe to the buffer
+ vector<AliHLTConsumerDescriptor*> fConsumers;
+ // the list of all consumers which are currently subscribed to the buffer
+ vector<AliHLTConsumerDescriptor*> fActiveConsumers;
+ // the list of all consumers which are already released for the current event
+ vector<AliHLTConsumerDescriptor*> fReleasedConsumers;
- AliHLTUInt32_t fFlags; // flags indicating the state of the buffer
+ // the buffer instance
+ AliHLTRawBuffer* fpBuffer;
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // global buffer handling
+ // flags indicating the state of the buffer
+ AliHLTUInt32_t fFlags;
- /* create a raw buffer of a certain size
- * the function tries to find a buffer of the given size (or a little bit bigger) from the list of free buffers
- * if no buffer is available, a new one is created
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // global buffer handling, internal use only
+
+ /**
+ * Create a raw buffer of a certain size.
+ * The function tries to find a buffer of the given size (or a bit bigger by a
+ * certain margin @ref fMargin) from the list of free buffers.
+ * If no buffer is available, a new one is created and added to the buffer handling.
+ * @param size min. size of the requested buffer
+ * @return pointer to raw buffer
*/
static AliHLTRawBuffer* CreateRawBuffer(AliHLTUInt32_t size);
- /* mark a buffer as free
+ /**
+ * Mark a buffer as free.
+ * After the Data Buffer has finnished using the raw buffer, it is released and
+ * added to the list of available buffers.
+ * @param pBuffer the raw buffer to release
+ * @return >=0 if succeeded, neg. error code if failed
*/
static int ReleaseRawBuffer(AliHLTRawBuffer* pBuffer);
- /* deletes all the raw buffers
+ /**
+ * Deletes all the raw buffers.
+ * When the last Data Buffer object is destructed, all raw data buffers are relesed.
*/
static int DeleteRawBuffers();
+ /**
+ * Number of instances of AliHLTDataBuffer.
+ * The statice variable is incremented and decremented in the constructor/destructor.
+ * All internal data structures are cleaned up when the last instance is exiting.
+ */
static int fNofInstances;
+ /** global list of free raw buffers */
static vector<AliHLTRawBuffer*> fFreeBuffers;
+ /** global list of currently active raw buffers */
static vector<AliHLTRawBuffer*> fActiveBuffers;
+ /** determines the raw buffer size margin at buffer requests */
static AliHLTUInt32_t fMargin;
- /*
- */
- AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer, AliHLTComponent_DataType datatype, vector<AliHLTConsumerDescriptor*> &pList);
+ /** global instance to HLT logging class for static methods */
+ static AliHLTLogging fgLogging;
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // internal helper functions
+
+ /**
+ * Find the consumer descriptor for a certain component and data type in
+ * a list of consumers.<br>
+ * <b>Note:</b> There are three lists which contain the consumers in the different states.
+ * @param pConsumer pointer to consumer component
+ * @param list list where to search for the consumer
+ */
+ AliHLTConsumerDescriptor* FindConsumer(const AliHLTComponent* pConsumer, vector<AliHLTConsumerDescriptor*> &list);
+
+ /**
+ * Change the state of a consumer.
+ * The state of a consumer is determined by the list it is strored in, the method moves a consumer from
+ * the source to the target list.
+ * @param pDesc pointer to consumer descriptor
+ * @param srcList list where the consumer is currently to be found
+ * @param tgtList list where to move the consumer
+ */
int ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, vector<AliHLTConsumerDescriptor*> &srcList, vector<AliHLTConsumerDescriptor*> &tgtList);
+ /**
+ * Cleanup a consumer list.
+ * Release all allocated data structures. <b>Note:</b> Not the component itself!
+ */
int CleanupConsumerList();
ClassDef(AliHLTDataBuffer, 0)
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif
// //
///////////////////////////////////////////////////////////////////////////////
-#if __GNUC__== 3
+#if __GNUC__>= 3
using namespace std;
#endif