fpDDLList(NULL),
fCDBSetRunNoFunc(false),
fChainId(),
+ fChainIdCrc(0),
fpBenchmark(NULL),
- fRequireSteeringBlocks(false)
+ fRequireSteeringBlocks(false),
+ fEventType(gkAliEventTypeUnknown)
{
// see header file for class documentation
// or
int AliHLTComponent::SetComponentDescription(const char* desc)
{
- // default implementation, childs can overload
+ // see header file for function documentation
int iResult=0;
if (!desc) return 0;
argument.ReplaceAll("chainid", "");
if (argument.BeginsWith("=")) {
fChainId=argument.Replace(0,1,"");
+ fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
+ HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
} else {
fChainId="";
}
} else {
- HLTWarning("unknown component discription %s", argument.Data());
+ HLTWarning("unknown component description %s", argument.Data());
}
}
}
}
}
((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
- AliHLTComponentDataTypeList::iterator itype=itypes.begin();
- while (itype!=itypes.end()) {
- //PrintDataTypeContent((*itype), "consumer \'%s\'");
- AliHLTComponentDataTypeList::iterator otype=otypes.begin();
- while (otype!=otypes.end() && (*itype)!=(*otype)) otype++;
- //if (otype!=otypes.end()) PrintDataTypeContent(*otype, "publisher \'%s\'");
- if (otype!=otypes.end()) {
- if (tgtList) tgtList->push_back(*itype);
+ AliHLTComponentDataTypeList::iterator otype=otypes.begin();
+ for (;otype!=otypes.end();otype++) {
+ //PrintDataTypeContent((*otype), "publisher \'%s\'");
+ if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
+ if (tgtList) tgtList->push_back(*otype);
+ iResult++;
+ continue;
+ }
+
+ AliHLTComponentDataTypeList::iterator itype=itypes.begin();
+ for (;itype!=itypes.end() && (*itype)!=(*otype); itype++);
+ //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
+ if (itype!=itypes.end()) {
+ if (tgtList) tgtList->push_back(*otype);
iResult++;
}
- itype++;
}
} else {
iResult=-EINVAL;
// see header file for function documentation
memset(&evtData, 0, sizeof(AliHLTComponentEventData));
evtData.fStructSize=sizeof(AliHLTComponentEventData);
+ evtData.fEventID=kAliHLTVoidEventID;
}
void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
AliHLTComponentStatistics outputStat;
memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
+ outputStat.fId=fChainIdCrc;
compStats.push_back(outputStat);
if (fpBenchmark) {
fpBenchmark->Reset();
}
#endif
- // data processing is skipped if there are only steering events
- // in the block list. It is not skipped if there is no block list
- // at all for the sake of data source components. Data processing
- // is always skipped if the event is of type
- // - gkAliEventTypeConfiguration
- // - gkAliEventTypeReadPreprocessor
+ // data processing is skipped
+ // - if there are only steering events in the block list.
+ // For the sake of data source components data processing
+ // is not skipped if there is no block list at all or if it
+ // just contains the eventType block
+ // - always skipped if the event is of type
+ // - gkAliEventTypeConfiguration
+ // - gkAliEventTypeReadPreprocessor
const unsigned int skipModeDefault=0x1;
const unsigned int skipModeForce=0x2;
unsigned int bSkipDataProcessing=skipModeDefault;
if (fpInputBlocks && evtData.fBlockCnt>0) {
// first look for all special events and execute in the appropriate
// sequence afterwords
- AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
int indexComConfEvent=-1;
int indexUpdtDCSEvent=-1;
int indexSOREvent=-1;
} else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
indexUpdtDCSEvent=i;
} else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
- eventType=fpInputBlocks[i].fSpecification;
+ fEventType=fpInputBlocks[i].fSpecification;
+
+ // skip always in case of gkAliEventTypeConfiguration
if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
+
+ // skip always in case of gkAliEventTypeReadPreprocessor
if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
+
+ // never skip if the event type block is the only block
+ if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
+
} else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
if (compStats.size()>0) {
AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
// start of run
if (fpRunDesc==NULL) {
fpRunDesc=new AliHLTRunDesc;
+ if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
}
if (fpRunDesc) {
AliHLTRunDesc rundesc;
HLTWarning("did not receive SOR, ignoring EOR");
}
}
- if (indexComConfEvent>=0 || eventType==gkAliEventTypeConfiguration) {
+ if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
TString cdbEntry;
if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
}
}
- if (indexUpdtDCSEvent>=0 || eventType==gkAliEventTypeReadPreprocessor) {
+ if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
TString modules;
if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
outputBlocks=NULL;
}
CleanupInputObjects();
- if (iResult>=0 && !bSkipDataProcessing) {
+ if (iResult>=0 && IsDataEvent()) {
IncrementEventCounter();
}
if (outputBlockCnt==0) {
return fpRunDesc->fRunType;
}
+bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
+{
+ // see header file for function documentation
+ if (pTgt) *pTgt=fEventType;
+ return (fEventType==gkAliEventTypeData ||
+ fEventType==gkAliEventTypeDataReplay ||
+ fEventType==gkAliEventTypeCalibration);
+}
+
int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
const char* structname, const char* eventname)
{
return iResult;
}
+
+AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
+{
+ // see header file for function documentation
+ AliHLTUInt32_t remainder = 0;
+ const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
+ const AliHLTUInt32_t topbit=1 << (crcwidth-1);
+ const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
+
+ // code from
+ // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
+
+ /*
+ * Perform modulo-2 division, a byte at a time.
+ */
+ for (int byte = 0; byte < size; ++byte)
+ {
+ /*
+ * Bring the next byte into the remainder.
+ */
+ remainder ^= (buffer[byte] << (crcwidth - 8));
+
+ /*
+ * Perform modulo-2 division, a bit at a time.
+ */
+ for (uint8_t bit = 8; bit > 0; --bit)
+ {
+ /*
+ * Try to divide the current data bit.
+ */
+ if (remainder & topbit)
+ {
+ remainder = (remainder << 1) ^ polynomial;
+ }
+ else
+ {
+ remainder = (remainder << 1);
+ }
+ }
+ }
+
+ /*
+ * The final remainder is the CRC result.
+ */
+ return (remainder);
+}
* also implements a standard method for @ref GetInputDataTypes.
*
* - AliHLTProcessor for components of type @ref kProcessor <br>
- * All types of data processors can inherit from AliHLTDataSource and must
+ * All types of data processors can inherit from AliHLTProcessor and must
* implement the @ref AliHLTProcessor::DoEvent method.
*
* - AliHLTDataSink for components of type @ref kSink <br>
- * All types of data processors can inherit from AliHLTDataSource and must
+ * All types of data processors can inherit from AliHLTDataSink and must
* implement the @ref AliHLTDataSink::DumpEvent method. The class
* also implements a standard method for @ref GetOutputDataType and @ref
* GetOutputDataSize.
* and AliHLTDataSink provides it's own processing method (see
* @ref alihltcomponent-type-std), which splits into a high and a low-level
* method. For the @ref alihltcomponent-low-level-interface, all parameters are
- * shipped as function arguments, the component is supposed to dump data to the
+ * shipped as function arguments, the component is supposed to write data to the
* output buffer and handle all block descriptors.
* The @ref alihltcomponent-high-level-interface is the standard processing
* method and will be used whenever the low-level method is not overloaded.
* For that reason the @ref GetOutputDataSize function should return a rough
* estimatian of the data to be produced by the component. The component is
* responsible for checking the memory size and must return -ENOSPC if the
- * available buffer is to small, and update the estimator respectively. The
+ * available buffer is too small, and update the estimator respectively. The
* framework will allocate a buffer of appropriate size and call the processing
* again.
*
*/
static string DataType2Text( const AliHLTComponentDataType& type, int mode=0);
+ /**
+ * Calculate a CRC checksum of a data buffer.
+ * Polynomial for the calculation is 0xD8.
+ */
+ static AliHLTUInt32_t CalculateChecksum(const AliHLTUInt8_t* buffer, int size);
+
/**
* Helper function to print content of data type.
*/
*/
virtual int EndOfRun();
+ /**
+ * Check whether a component requires all steering blocks.
+ * Childs can overload in order to indicate that they want to
+ * receive also the steering data blocks. There is also the
+ * possibility to add the required data types to the input
+ * data type list in GetInputDataTypes().
+ */
+ virtual bool RequireSteeringBlocks() const {return false;}
+
/**
* General memory allocation method.
* All memory which is going to be used 'outside' of the interface must
*/
const char* GetChainId() const {return fChainId.c_str();}
+ /**
+ * Check whether the current event is a valid data event.
+ * @param pTgt optional pointer to get the event type
+ * @return true if the current event is a real data event
+ */
+ bool IsDataEvent(AliHLTUInt32_t* pTgt=NULL);
+
/**
* Set a bit to 1 in a readout list ( = AliHLTEventDDL )
* -> enable DDL for readout
/** id of the component in the analysis chain */
string fChainId; //! transient
+ /** crc value of the chainid, used as a 32bit id */
+ AliHLTUInt32_t fChainIdCrc; //! transient
+
/** optional benchmarking for the component statistics */
TStopwatch* fpBenchmark; //! transient
/** component requires steering data blocks */
bool fRequireSteeringBlocks; //! transient
- ClassDef(AliHLTComponent, 7)
+ /** current event type */
+ AliHLTUInt32_t fEventType; //! transient
+
+ ClassDef(AliHLTComponent, 8)
};
#endif
desc=fActiveConsumers.begin();
while (desc!=fActiveConsumers.end()) {
AliHLTConsumerDescriptor* pDesc=*desc;
- HLTWarning("consumer %p was not released", pDesc);
+ HLTWarning("consumer %p (%s) was not released", pDesc, pDesc->GetComponent()?pDesc->GetComponent()->GetComponentID():"### invalid component ###");
fActiveConsumers.erase(desc);
desc=fActiveConsumers.begin();
fConsumers.push_back(pDesc);
// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
}
-void* AliHLTDataSource::fgpSpecialEvent=NULL;
-int AliHLTDataSource::fgSpecialEventSize=0;
-AliHLTComponentDataType AliHLTDataSource::fgSpecialEventDataType=kAliHLTVoidDataType;
-AliHLTUInt32_t AliHLTDataSource::fgSpecialEventSpecification=kAliHLTVoidDataSpec;
-
AliHLTDataSource::~AliHLTDataSource()
{
// see header file for class documentation
int AliHLTDataSource::DoProcessing( const AliHLTComponentEventData& evtData,
- const AliHLTComponentBlockData* /*blocks*/,
+ const AliHLTComponentBlockData* blocks,
AliHLTComponentTriggerData& trigData,
AliHLTUInt8_t* outputPtr,
AliHLTUInt32_t& size,
// see header file for class documentation
int iResult=0;
if (evtData.fBlockCnt > 0) {
- HLTWarning("Data source component skips input data blocks");
- }
- if (fgpSpecialEvent==NULL || fgSpecialEventSize==0) {
- // normal event publishing
- iResult=GetEvent(evtData, trigData, outputPtr, size, outputBlocks);
- HLTDebug("component %s (%p) GetEvent finished (%d)", GetComponentID(), this, iResult);
- } else {
- // publish special event
- if (size>=(unsigned)fgSpecialEventSize) {
- memcpy(outputPtr, fgpSpecialEvent, fgSpecialEventSize);
- AliHLTComponentBlockData bd;
- FillBlockData(bd);
- bd.fOffset=0;
- bd.fSize=fgSpecialEventSize;
- bd.fDataType=fgSpecialEventDataType;
- bd.fSpecification=fgSpecialEventSpecification;
- outputBlocks.push_back(bd);
- size=bd.fSize;
- } else {
- iResult=-ENOSPC;
+ int unknown=-1;
+ for (unsigned int block; block<evtData.fBlockCnt; block++) {
+ if (blocks[block].fDataType==kAliHLTDataTypeSOR ||
+ blocks[block].fDataType==kAliHLTDataTypeEOR) {
+ continue;
+ }
+ unknown=block;
+ break;
+ }
+ if (unknown>=0) {
+ HLTWarning("Data source component skips input data blocks: first unknown block %s",
+ DataType2Text(blocks[unknown].fDataType).c_str());
}
}
+ iResult=GetEvent(evtData, trigData, outputPtr, size, outputBlocks);
+ HLTDebug("component %s (%p) GetEvent finished (%d)", GetComponentID(), this, iResult);
edd = NULL;
return iResult;
}
HLTFatal("no processing method implemented");
return -ENOSYS;
}
-
-AliHLTDataSource::AliSpecialEventGuard::AliSpecialEventGuard(AliHLTRunDesc* pDesc, AliHLTComponentDataType dt, AliHLTUInt32_t spec)
-{
- AliHLTDataSource::fgpSpecialEvent=pDesc;
- AliHLTDataSource::fgSpecialEventSize=sizeof(AliHLTRunDesc);
- AliHLTDataSource::fgSpecialEventDataType=dt;
- AliHLTDataSource::fgSpecialEventSpecification=spec;
-}
-
-AliHLTDataSource::AliSpecialEventGuard::~AliSpecialEventGuard()
-{
- AliHLTDataSource::fgpSpecialEvent=NULL;
- AliHLTDataSource::fgSpecialEventSize=0;
- AliHLTDataSource::fgSpecialEventDataType=kAliHLTVoidDataType;
- AliHLTDataSource::fgSpecialEventSpecification=kAliHLTVoidDataSpec;
-}
*/
void GetInputDataTypes( vector<AliHLTComponentDataType>& list);
- /**
- * @class AliSpecialEventGuard
- * Guard structure to set the data sources into 'special event publishing'
- * mode. The SOR and EOR events are generated by all the data sources and
- * perculated through the chain as normal events. The AliSpecialEventGuard
- * is a back-door mechansim to trigger publishing of the special event
- * described by the run descriptor instead of the publishing of real data.
- *
- * The descriptor has to be valid throughout the lifetime of the guard.
- */
- class AliSpecialEventGuard {
- public:
- /** constructor, set run descriptor */
- AliSpecialEventGuard(AliHLTRunDesc* pDesc, AliHLTComponentDataType dt, AliHLTUInt32_t spec);
- /** destructor, reset run descriptor */
- ~AliSpecialEventGuard();
- };
-
protected:
/**
virtual int GetEvent( const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData);
private:
- /** pointer to the special event going to be published */
- static void* fgpSpecialEvent; //! transient
- /** data size of the special event going to be published */
- static int fgSpecialEventSize; //! transient
- /** data type of the special event going to be published */
- static AliHLTComponentDataType fgSpecialEventDataType; //! transient
- /** data specification of the special event going to be published */
- static AliHLTUInt32_t fgSpecialEventSpecification; //! transient
- ClassDef(AliHLTDataSource, 2)
+ ClassDef(AliHLTDataSource, 3)
};
#endif
AliHLTRunDesc runDesc;
memset(&runDesc, 0, sizeof(AliHLTRunDesc));
runDesc.fStructSize=sizeof(AliHLTRunDesc);
- AliHLTDataSource::AliSpecialEventGuard g(&runDesc, dt, kAliHLTVoidDataSpec);
HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
TObjLink *lnk=fTaskList.FirstLink();
while (lnk && iResult>=0) {
fpConfiguration, GetName(), pConf);
}
if (pConf!=NULL) fpConfiguration=pConf;
- if (fpConfiguration) {
+ iResult=CreateComponent(fpConfiguration, pCH, fpComponent);
+ if (iResult>=0) {
+ iResult=CustomInit(pCH);
+ }
+ return iResult;
+}
+
+int AliHLTTask::CreateComponent(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const
+{
+ // see header file for class documentation
+ int iResult=0;
+ if (pConf) {
if (pCH) {
int argc=0;
const char** argv=NULL;
- if ((iResult=fpConfiguration->GetArguments(&argv))>=0) {
+ if ((iResult=pConf->GetArguments(&argv))>=0) {
argc=iResult; // just to make it clear
// TODO: we have to think about the optional environment parameter,
- // currently just set to NULL.
- iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
- if (fpComponent && iResult>=0) {
- //HLTDebug("component %s (%p) created", fpComponent->GetComponentID(), fpComponent);
+ // currently just set to NULL.
+ iResult=pCH->CreateComponent(pConf->GetComponentID(), pComponent);
+ if (pComponent && iResult>=0) {
+ TString description;
+ description.Form("chainid=%s", GetName());
+ pComponent->SetComponentDescription(description.Data());
+ const AliHLTAnalysisEnvironment* pEnv=pCH->GetEnvironment();
+ if ((iResult=pComponent->Init(pEnv, NULL, argc, argv))>=0) {
+ //HLTDebug("component %s (%p) created", pComponent->GetComponentID(), pComponent);
+ } else {
+ HLTError("Initialization of component \"%s\" failed with error %d", pComponent->GetComponentID(), iResult);
+ }
} else {
- //HLTError("can not find component \"%s\" (%d)", fpConfiguration->GetComponentID(), iResult);
+ //HLTError("can not find component \"%s\" (%d)", pConf->GetComponentID(), iResult);
}
} else {
- HLTError("can not get argument list for configuration %s (%s)", fpConfiguration->GetName(), fpConfiguration->GetComponentID());
+ HLTError("can not get argument list for configuration %s (%s)", pConf->GetName(), pConf->GetComponentID());
iResult=-EINVAL;
}
} else {
HLTError("configuration object instance needed for task initialization");
iResult=-EINVAL;
}
- if (iResult>=0) {
- iResult=CustomInit(pCH);
- }
return iResult;
}
return iResult;
}
-int AliHLTTask::ProcessTask(Int_t eventNo)
+int AliHLTTask::ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType)
{
// see header file for function documentation
int iResult=0;
do {
long unsigned int iOutputDataSize=0;
AliHLTConfiguration* pConf=GetConf();
- assert(pConf);
// check if there was a buffer size specified, query output size
// estimator from component otherwize
if (pConf && pConf->GetOutputBufferSize()>=0) {
//HLTDebug("provided raw buffer %p", pTgtBuffer);
AliHLTComponentEventData evtData;
AliHLTComponent::FillEventData(evtData);
- evtData.fEventID=(AliHLTEventID_t)eventNo;
- evtData.fBlockCnt=iSourceDataBlock;
+ if (eventNo>=0)
+ evtData.fEventID=(AliHLTEventID_t)eventNo;
AliHLTComponentTriggerData trigData;
trigData.fStructSize=sizeof(trigData);
trigData.fDataSize=0;
AliHLTComponentBlockData* outputBlocks=NULL;
AliHLTComponentEventDoneData* edd=NULL;
if (pTgtBuffer!=NULL || iOutputDataSize==0) {
+ // add event type data block
+ AliHLTComponentBlockData eventTypeBlock;
+ AliHLTComponent::FillBlockData(eventTypeBlock);
+ // Note: no payload!
+ eventTypeBlock.fDataType=kAliHLTDataTypeEvent;
+ eventTypeBlock.fSpecification=eventType;
+ fBlockDataArray.push_back(eventTypeBlock);
+
+ // process
+ evtData.fBlockCnt=fBlockDataArray.size();
iResult=pComponent->ProcessEvent(evtData, &fBlockDataArray[0], trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
+
+ // remove event data block
+ fBlockDataArray.pop_back();
+
if (iResult>=0 && outputBlocks) {
if (fListTargets.First()!=NULL) {
AliHLTComponentBlockDataList segments;
for (AliHLTUInt32_t oblock=0; oblock<outputBlockCnt; oblock++) {
AliHLTUInt32_t iblock=0;
- for (; iblock<evtData.fBlockCnt; iblock++) {
+ for (; iblock<fBlockDataArray.size(); iblock++) {
if (fBlockDataArray[iblock].fPtr==outputBlocks[oblock].fPtr) {
assert(subscribedTaskList[iblock]!=NULL);
if (subscribedTaskList[iblock]==NULL) continue;
break;
}
}
- if (iblock==evtData.fBlockCnt) segments.push_back(outputBlocks[oblock]);
+ if (iblock==fBlockDataArray.size()) segments.push_back(outputBlocks[oblock]);
}
if (pTgtBuffer && segments.size()>0) {
iResult=fpDataBuffer->SetSegments(pTgtBuffer, &segments[0], segments.size());
*/
int Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH);
+ /**
+ * Create the component.
+ * @param pConf configuration descritption
+ * @param pCH component handler
+ * @return component instance
+ */
+ virtual int CreateComponent(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH, AliHLTComponent*& pComponent) const;
+
/**
* De-Initialize the task.
* Final cleanup after the run. The @ref AliHLTComponent::Deinit method of
* processing, the data blocks are released. <br>
* The @ref StartRun method must be called before.
*/
- int ProcessTask(Int_t eventNo);
+ int ProcessTask(Int_t eventNo, AliHLTUInt32_t eventType=gkAliEventTypeData);
/**
* Determine the number of matching data block between the component and the