3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9 //* for The ALICE HLT Project. *
11 //* Permission to use, copy, modify and distribute this software and its *
12 //* documentation strictly for non-commercial purposes is hereby granted *
13 //* without fee, provided that the above copyright notice appears in all *
14 //* copies and that both the copyright notice and this permission notice *
15 //* appear in the supporting documentation. The authors make no claims *
16 //* about the suitability of this software for any purpose. It is *
17 //* provided "as is" without express or implied warranty. *
18 //**************************************************************************
20 /** @file AliHLTComponent.cxx
21 @author Matthias Richter, Timm Steinbeck
23 @brief Base class implementation for HLT components. */
29 //#include "AliHLTStdIncludes.h"
30 #include "AliHLTComponent.h"
31 #include "AliHLTComponentHandler.h"
32 #include "AliHLTMessage.h"
35 #include "TObjArray.h"
36 #include "TObjectTable.h"
38 #include "TStopwatch.h"
39 #include "AliHLTMemoryFile.h"
40 #include "AliHLTMisc.h"
45 * default compression level for ROOT objects
47 #define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
48 #define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
50 /** ROOT macro for the implementation of ROOT specific class methods */
51 ClassImp(AliHLTComponent);
53 /** stopwatch macro using the stopwatch guard */
54 #define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
55 //#define ALIHLTCOMPONENT_STOPWATCH(type)
57 /** stopwatch macro for operations of the base class */
58 #define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
59 /** stopwatch macro for operations of the detector algorithm (DA) */
60 #define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
62 AliHLTComponent::AliHLTComponent()
70 fCurrentInputBlock(-1),
71 fSearchDataType(kAliHLTVoidDataType),
76 fOutputBufferFilled(0),
78 fpStopwatches(new TObjArray(kSWTypeCount)),
82 fCDBSetRunNoFunc(false),
86 fRequireSteeringBlocks(false),
87 fEventType(gkAliEventTypeUnknown),
90 fEventDoneDataSize(0),
91 fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION)
94 // see header file for class documentation
96 // refer to README to build package
98 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
99 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
100 if (fgpComponentHandler)
101 fgpComponentHandler->ScheduleRegister(this);
102 //SetLocalLoggingLevel(kHLTLogDefault);
105 AliHLTComponent::~AliHLTComponent()
107 // see header file for function documentation
108 if (fpBenchmark) delete fpBenchmark;
111 CleanupInputObjects();
112 if (fpStopwatches!=NULL) delete fpStopwatches;
114 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
115 while (element!=fMemFiles.end()) {
117 if ((*element)->IsClosed()==0) {
118 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
119 // close but do not flush as we dont know whether the buffer is still valid
120 (*element)->CloseMemoryFile(0);
132 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
135 AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
137 int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
139 // see header file for function documentation
141 if (fgpComponentHandler==NULL || bOverwrite!=0)
142 fgpComponentHandler=pCH;
148 int AliHLTComponent::UnsetGlobalComponentHandler()
150 // see header file for function documentation
151 return SetGlobalComponentHandler(NULL,1);
154 int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
156 // see header file for function documentation
157 HLTLogKeyword(fChainId.c_str());
160 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
161 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
162 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
163 fEnvironment.fParam=environParam;
166 const char** pArguments=NULL;
171 pArguments=new const char*[argc];
173 for (int i=0; i<argc && iResult>=0; i++) {
174 if (fComponentArgs.size()>0) fComponentArgs+=" ";
175 fComponentArgs+=argv[i];
177 if (argument.IsNull()) continue;
180 if (argument.CompareTo("-benchmark")==0) {
183 } else if (argument.BeginsWith("-loglevel=")) {
184 TString parameter=argument.ReplaceAll("-loglevel=", "");
185 parameter.Remove(TString::kLeading, ' '); // remove all blanks
186 if (parameter.BeginsWith("0x") &&
187 parameter.Replace(0,2,"",0).IsHex()) {
188 unsigned int loglevel=kHLTLogNone;
189 sscanf(parameter.Data(),"%x", &loglevel);
190 SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
192 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
195 // -object-compression=
196 } else if (argument.BeginsWith("-object-compression=")) {
197 argument.ReplaceAll("-object-compression=", "");
198 if (argument.IsDigit()) {
199 fCompressionLevel=argument.Atoi();
200 if (fCompressionLevel<0 || fCompressionLevel>9) {
201 HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION);
202 fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION;
205 HLTError("wrong parameter for argument -object-compression, number expected");
208 pArguments[iNofChildArgs++]=argv[i];
216 HLTError("missing parameter for argument %s", argument.Data());
220 iResult=DoInit(iNofChildArgs, pArguments);
225 // find out if the component wants to get the steering events
227 AliHLTComponentDataTypeList inputDt;
228 GetInputDataTypes(inputDt);
229 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
230 dt!=inputDt.end() && !fRequireSteeringBlocks;
232 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
233 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
234 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
235 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
236 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
239 if (pArguments) delete [] pArguments;
241 #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
242 // benchmarking stopwatch for the component statistics
243 fpBenchmark=new TStopwatch;
249 int AliHLTComponent::Deinit()
251 // see header file for function documentation
252 HLTLogKeyword(fChainId.c_str());
256 HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
257 AliHLTRunDesc* pRunDesc=fpRunDesc;
265 int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
267 // see header file for function documentation
270 // I have to think about separating the library handling from the
271 // component handler. Requiring the component hanlder here is not
272 // the cleanest solution.
273 // We presume the library already to be loaded
275 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
278 if (cdbPath && cdbPath[0]!=0) {
280 // very temporary fix, have to check for other formats
281 if (!path.BeginsWith("local://")) {
286 if ((iResult=(*pFunc)(path.Data()))>=0) {
287 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
288 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
289 "can not find function to set CDB run no");
293 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
294 "can not find initialization function");
303 int AliHLTComponent::SetCDBRunNo(int runNo)
305 // see header file for function documentation
306 if (!fCDBSetRunNoFunc) return 0;
307 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
310 int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
312 // see header file for function documentation
313 if (!desc) return -EINVAL;
314 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
315 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
320 fpRunDesc=new AliHLTRunDesc;
321 if (!fpRunDesc) return -ENOMEM;
322 *fpRunDesc=kAliHLTVoidRunDesc;
325 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
326 HLTWarning("Run description has already been set");
329 SetCDBRunNo(fpRunDesc->fRunNo);
330 // TODO: we have to decide about the runType
334 int AliHLTComponent::SetComponentDescription(const char* desc)
336 // see header file for function documentation
340 TString descriptor=desc;
341 TObjArray* pTokens=descriptor.Tokenize(" ");
343 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
344 TString argument=((TObjString*)pTokens->At(i++))->GetString();
345 if (!argument || argument.IsNull()) continue;
348 if (argument.BeginsWith("chainid")) {
349 argument.ReplaceAll("chainid", "");
350 if (argument.BeginsWith("=")) {
351 fChainId=argument.Replace(0,1,"");
352 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
353 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
358 HLTWarning("unknown component description %s", argument.Data());
366 int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
368 // default implementation, childs can overload
369 HLTLogKeyword("dummy");
373 int AliHLTComponent::DoDeinit()
375 // default implementation, childs can overload
376 HLTLogKeyword("dummy");
380 int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
382 // default implementation, childs can overload
383 HLTLogKeyword("dummy");
387 int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
389 // default implementation, childs can overload
390 HLTLogKeyword("dummy");
394 int AliHLTComponent::StartOfRun()
396 // default implementation, childs can overload
397 HLTLogKeyword("dummy");
401 int AliHLTComponent::EndOfRun()
403 // default implementation, childs can overload
404 HLTLogKeyword("dummy");
409 int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
411 // default implementation, childs can overload
412 HLTLogKeyword("dummy");
416 void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
418 // see header file for function documentation
419 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
420 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
421 strcat( output, ":" );
422 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
425 string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
427 // see header file for function documentation
433 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
434 sprintf(tmp, "'%d", type.fOrigin[i]);
438 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
439 sprintf(tmp, "%d'", type.fID[i]);
448 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
449 unsigned char* puc=(unsigned char*)type.fOrigin;
451 sprintf(tmp, "'\\%x", type.fOrigin[i]);
453 sprintf(tmp, "'%c", type.fOrigin[i]);
457 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
458 unsigned char* puc=(unsigned char*)type.fID;
460 sprintf(tmp, "\\%x'", type.fID[i]);
462 sprintf(tmp, "%c'", type.fID[i]);
468 if (type==kAliHLTVoidDataType) {
471 // some gymnastics in order to avoid a '0' which is part of either or both
472 // ID and origin terminating the whole string. Unfortunately, string doesn't
473 // stop appending at the '0' if the number of elements to append was
474 // explicitely specified
476 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
477 out.append(tmp.c_str());
480 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
481 out.append(tmp.c_str());
487 void* AliHLTComponent::AllocMemory( unsigned long size )
489 // see header file for function documentation
490 if (fEnvironment.fAllocMemoryFunc)
491 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
492 HLTFatal("no memory allocation handler registered");
496 int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
497 AliHLTComponentBlockData** outputBlocks )
499 // see header file for function documentation
500 if ( blockCount==NULL || outputBlocks==NULL )
502 AliHLTUInt32_t count = blocks.size();
506 *outputBlocks = NULL;
509 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
510 if ( !*outputBlocks )
512 for ( unsigned long i = 0; i < count; i++ ) {
513 (*outputBlocks)[i] = blocks[i];
514 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
515 (*outputBlocks)[i].fDataType=GetOutputDataType();
516 /* data type was set to the output data type by the PubSub AliRoot
517 Wrapper component, if data type of the block was ********:****.
518 Now handled by the component base class in order to have same
519 behavior when running embedded in AliRoot
520 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
521 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
530 int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd )
532 // see header file for function documentation
533 if (fEnvironment.fGetEventDoneDataFunc)
534 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
538 int AliHLTComponent::ReserveEventDoneData( unsigned long size )
540 // see header file for function documentation
544 if (size>fEventDoneDataSize) {
545 AliHLTComponentEventDoneData* newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+size ] );
548 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
549 newEDD->fDataSize = 0;
550 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
551 if (fEventDoneData) {
552 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
553 newEDD->fDataSize = fEventDoneData->fDataSize;
554 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
556 fEventDoneData = newEDD;
557 fEventDoneDataSize = size;
563 int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord )
567 if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize)
569 *reinterpret_cast<AliHLTUInt32_t*>((reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord;
570 fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t);
574 void AliHLTComponent::ReleaseEventDoneData()
577 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
578 fEventDoneData = NULL;
579 fEventDoneDataSize = 0;
583 int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
585 // see header file for function documentation
588 AliHLTComponentDataTypeList itypes;
589 AliHLTComponentDataTypeList otypes;
590 otypes.push_back(GetOutputDataType());
591 if (otypes[0]==kAliHLTMultipleDataType) {
594 if ((count=GetOutputDataTypes(otypes))>0) {
595 } else if (GetComponentType()!=kSink) {
596 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
599 ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
600 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
601 for (;otype!=otypes.end();otype++) {
602 //PrintDataTypeContent((*otype), "publisher \'%s\'");
603 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
604 if (tgtList) tgtList->push_back(*otype);
609 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
610 for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */};
611 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
612 if (itype!=itypes.end()) {
613 if (tgtList) tgtList->push_back(*otype);
623 void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
625 // see header file for function documentation
626 const char* fmt="\'%s\'";
627 if (format) fmt=format;
628 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
629 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
630 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
645 void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
647 // see header file for function documentation
648 blockData.fStructSize = sizeof(blockData);
649 FillShmData( blockData.fShmKey );
650 blockData.fOffset = ~(AliHLTUInt32_t)0;
651 blockData.fPtr = NULL;
653 FillDataType( blockData.fDataType );
654 blockData.fSpecification = kAliHLTVoidDataSpec;
657 void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
659 // see header file for function documentation
660 shmData.fStructSize = sizeof(shmData);
661 shmData.fShmType = gkAliHLTComponentInvalidShmType;
662 shmData.fShmID = gkAliHLTComponentInvalidShmID;
665 void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
667 // see header file for function documentation
668 dataType=kAliHLTAnyDataType;
671 void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
673 // see header file for function documentation
674 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
675 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
678 void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
680 // see header file for function documentation
681 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
683 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
684 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
687 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
688 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
692 void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
694 // see header file for function documentation
695 dt.fStructSize=sizeof(AliHLTComponentDataType);
696 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
697 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
698 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
699 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
702 void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
704 // see header file for function documentation
705 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
706 evtData.fStructSize=sizeof(AliHLTComponentEventData);
707 evtData.fEventID=kAliHLTVoidEventID;
710 void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
712 // see header file for function documentation
714 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
715 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
716 if (dt.fID[i]!=0) msg+=dt.fID[i];
720 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
721 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
725 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
728 int AliHLTComponent::GetEventCount() const
730 // see header file for function documentation
734 int AliHLTComponent::IncrementEventCounter()
736 // see header file for function documentation
737 if (fEventCount>=0) fEventCount++;
741 int AliHLTComponent::GetNumberOfInputBlocks() const
743 // see header file for function documentation
744 if (fpInputBlocks!=NULL) {
745 return fCurrentEventData.fBlockCnt;
750 AliHLTEventID_t AliHLTComponent::GetEventId() const
752 // see header file for function documentation
753 if (fpInputBlocks!=NULL) {
754 return fCurrentEventData.fEventID;
759 const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
760 const char* classname,
763 // see header file for function documentation
764 ALIHLTCOMPONENT_BASE_STOPWATCH();
766 if (classname) fClassName=classname;
767 else fClassName.clear();
768 int idx=FindInputBlock(fSearchDataType, 0, 1);
771 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
772 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
773 fCurrentInputBlock=idx;
780 const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
781 const char* dtOrigin,
782 const char* classname,
785 // see header file for function documentation
786 ALIHLTCOMPONENT_BASE_STOPWATCH();
787 AliHLTComponentDataType dt;
788 SetDataType(dt, dtID, dtOrigin);
789 return GetFirstInputObject(dt, classname, bForce);
792 const TObject* AliHLTComponent::GetNextInputObject(int bForce)
794 // see header file for function documentation
795 ALIHLTCOMPONENT_BASE_STOPWATCH();
796 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
797 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
800 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
801 fCurrentInputBlock=idx;
807 int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
809 // see header file for function documentation
811 if (fpInputBlocks!=NULL) {
812 int idx=startIdx<0?0:startIdx;
813 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
814 if (dt!=fpInputBlocks[idx].fDataType) continue;
817 if (fpInputBlocks[idx].fPtr==NULL) continue;
818 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
819 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
827 TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
829 // see header file for function documentation
831 if (fpInputBlocks!=NULL) {
832 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
833 if (fpInputBlocks[idx].fPtr) {
834 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
835 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
836 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
837 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
838 TClass* objclass=msg.GetClass();
839 pObj=msg.ReadObject(objclass);
840 if (pObj && objclass) {
841 HLTDebug("object %p type %s created", pObj, objclass->GetName());
845 } else if (bForce!=0) {
846 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
849 HLTFatal("block descriptor empty");
852 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
855 HLTError("no input blocks available");
861 TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
863 // see header file for function documentation
864 if (fpInputObjects==NULL) {
865 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
868 if (fpInputObjects) {
869 pObj=fpInputObjects->At(idx);
871 pObj=CreateInputObject(idx, bForce);
873 fpInputObjects->AddAt(pObj, idx);
877 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
882 int AliHLTComponent::CleanupInputObjects()
884 // see header file for function documentation
885 if (!fpInputObjects) return 0;
886 TObjArray* array=fpInputObjects;
888 for (int i=0; i<array->GetEntries(); i++) {
889 TObject* pObj=array->At(i);
890 // grrr, garbage collection strikes back: When read via AliHLTMessage
891 // (CreateInputObject), and written to a TFile afterwards, the
892 // TFile::Close calls ROOOT's garbage collection. No clue why the
893 // object ended up in the key list and needs to be deleted
895 // Matthias 09.11.2008 follow up
896 // This approach doesn't actually work in all cases: the object table
897 // can be switched off globally, the flag needs to be checked here as
898 // well in order to avoid memory leaks.
899 // This means we have to find another solution for the problem if it
902 (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) {
910 AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
912 // see header file for function documentation
913 ALIHLTCOMPONENT_BASE_STOPWATCH();
914 AliHLTComponentDataType dt=kAliHLTVoidDataType;
915 int idx=fCurrentInputBlock;
917 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
919 HLTError("unknown object %p", pObject);
923 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
924 dt=fpInputBlocks[idx].fDataType;
926 HLTFatal("severe internal error, index out of range");
932 AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
934 // see header file for function documentation
935 ALIHLTCOMPONENT_BASE_STOPWATCH();
936 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
937 int idx=fCurrentInputBlock;
939 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
941 HLTError("unknown object %p", pObject);
945 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
946 iSpec=fpInputBlocks[idx].fSpecification;
948 HLTFatal("severe internal error, index out of range");
954 int AliHLTComponent::Forward(const TObject* pObject)
956 // see header file for function documentation
958 int idx=fCurrentInputBlock;
960 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
962 HLTError("unknown object %p", pObject);
967 fOutputBlocks.push_back(fpInputBlocks[idx]);
972 int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
974 // see header file for function documentation
976 int idx=fCurrentInputBlock;
978 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
980 HLTError("unknown Block %p", pBlock);
985 // check for fpInputBlocks pointer done in FindInputBlock
986 fOutputBlocks.push_back(fpInputBlocks[idx]);
991 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
993 // see header file for function documentation
994 ALIHLTCOMPONENT_BASE_STOPWATCH();
997 int idx=FindInputBlock(fSearchDataType, 0);
998 const AliHLTComponentBlockData* pBlock=NULL;
1000 // check for fpInputBlocks pointer done in FindInputBlock
1001 pBlock=&fpInputBlocks[idx];
1002 fCurrentInputBlock=idx;
1007 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1008 const char* dtOrigin)
1010 // see header file for function documentation
1011 ALIHLTCOMPONENT_BASE_STOPWATCH();
1012 AliHLTComponentDataType dt;
1013 SetDataType(dt, dtID, dtOrigin);
1014 return GetFirstInputBlock(dt);
1017 const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
1019 // see header file for function documentation
1020 ALIHLTCOMPONENT_BASE_STOPWATCH();
1021 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
1022 return &fpInputBlocks[index];
1025 const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1027 // see header file for function documentation
1028 ALIHLTCOMPONENT_BASE_STOPWATCH();
1029 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1030 const AliHLTComponentBlockData* pBlock=NULL;
1032 // check for fpInputBlocks pointer done in FindInputBlock
1033 pBlock=&fpInputBlocks[idx];
1034 fCurrentInputBlock=idx;
1039 int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
1041 // see header file for function documentation
1042 int iResult=-ENOENT;
1043 if (fpInputBlocks!=NULL) {
1045 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
1046 iResult=(int)(pBlock-fpInputBlocks);
1055 AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1057 // see header file for function documentation
1058 ALIHLTCOMPONENT_BASE_STOPWATCH();
1059 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1060 int idx=fCurrentInputBlock;
1062 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1064 HLTError("unknown Block %p", pBlock);
1068 // check for fpInputBlocks pointer done in FindInputBlock
1069 iSpec=fpInputBlocks[idx].fSpecification;
1074 int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1075 void* pHeader, int headerSize)
1077 // see header file for function documentation
1078 ALIHLTCOMPONENT_BASE_STOPWATCH();
1082 AliHLTMessage msg(kMESS_OBJECT);
1083 msg.SetCompressionLevel(fCompressionLevel);
1084 msg.WriteObject(pObject);
1085 Int_t iMsgLength=msg.Length();
1087 // Matthias Sep 2008
1088 // NOTE: AliHLTMessage does implement it's own SetLength method
1089 // which is not architecture independent. The original SetLength
1090 // stores the size always in network byte order.
1091 // I'm trying to remember the rational for that, might be that
1092 // it was just some lack of knowledge. Want to change this, but
1093 // has to be done carefullt to be backward compatible.
1094 msg.SetLength(); // sets the length to the first (reserved) word
1096 // does nothing if the level is 0
1099 char *mbuf = msg.Buffer();
1100 if (msg.CompBuffer()) {
1101 msg.SetLength(); // set once more to have to byte order
1102 mbuf = msg.CompBuffer();
1103 iMsgLength = msg.CompLength();
1106 iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
1108 HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
1110 fLastObjectSize=iMsgLength;
1112 HLTError("object serialization failed for object %p", pObject);
1121 int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1122 void* pHeader, int headerSize)
1124 // see header file for function documentation
1125 ALIHLTCOMPONENT_BASE_STOPWATCH();
1126 AliHLTComponentDataType dt;
1127 SetDataType(dt, dtID, dtOrigin);
1128 return PushBack(pObject, dt, spec, pHeader, headerSize);
1131 int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1132 const void* pHeader, int headerSize)
1134 // see header file for function documentation
1135 ALIHLTCOMPONENT_BASE_STOPWATCH();
1136 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
1139 int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1140 const void* pHeader, int headerSize)
1142 // see header file for function documentation
1143 ALIHLTCOMPONENT_BASE_STOPWATCH();
1144 AliHLTComponentDataType dt;
1145 SetDataType(dt, dtID, dtOrigin);
1146 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
1149 int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1150 const void* pHeader, int iHeaderSize)
1152 // see header file for function documentation
1154 int iBlkSize = iBufferSize + iHeaderSize;
1156 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
1157 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
1158 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1160 // copy header if provided but skip if the header is the target location
1161 // in that case it has already been copied
1162 if (pHeader!=NULL && pHeader!=pTgt) {
1163 memcpy(pTgt, pHeader, iHeaderSize);
1166 pTgt += (AliHLTUInt8_t) iHeaderSize;
1168 // copy buffer if provided but skip if buffer is the target location
1169 // in that case it has already been copied
1170 if (pBuffer!=NULL && pBuffer!=pTgt) {
1171 memcpy(pTgt, pBuffer, iBufferSize);
1173 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
1174 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
1176 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
1178 if (fpOutputBuffer) {
1179 HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize);
1181 HLTError("output buffer not available");
1187 AliHLTComponentBlockData bd;
1188 FillBlockData( bd );
1189 bd.fOffset = fOutputBufferFilled;
1190 bd.fSize = iBlkSize;
1192 bd.fSpecification = spec;
1193 fOutputBlocks.push_back( bd );
1194 fOutputBufferFilled+=bd.fSize;
1200 int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1202 // see header file for function documentation
1203 if (!pObject) return -EINVAL;
1204 AliHLTMessage msg(kMESS_OBJECT);
1205 msg.WriteObject(pObject);
1206 return msg.Length();
1209 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1210 const char* dtOrigin,
1211 AliHLTUInt32_t spec)
1213 // see header file for function documentation
1214 ALIHLTCOMPONENT_BASE_STOPWATCH();
1215 AliHLTComponentDataType dt;
1216 SetDataType(dt, dtID, dtOrigin);
1217 return CreateMemoryFile(capacity, dt, spec);
1220 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1221 const AliHLTComponentDataType& dt,
1222 AliHLTUInt32_t spec)
1224 // see header file for function documentation
1225 ALIHLTCOMPONENT_BASE_STOPWATCH();
1226 AliHLTMemoryFile* pFile=NULL;
1227 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
1228 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1229 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1231 unsigned int nofBlocks=fOutputBlocks.size();
1232 if (nofBlocks+1>fMemFiles.size()) {
1233 fMemFiles.resize(nofBlocks+1, NULL);
1235 if (nofBlocks<fMemFiles.size()) {
1236 fMemFiles[nofBlocks]=pFile;
1237 AliHLTComponentBlockData bd;
1238 FillBlockData( bd );
1239 bd.fOffset = fOutputBufferFilled;
1240 bd.fSize = capacity;
1242 bd.fSpecification = spec;
1243 fOutputBufferFilled+=bd.fSize;
1244 fOutputBlocks.push_back( bd );
1246 HLTError("can not allocate/grow object array");
1247 pFile->CloseMemoryFile(0);
1253 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1258 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1259 const char* dtOrigin,
1260 AliHLTUInt32_t spec,
1263 // see header file for function documentation
1264 ALIHLTCOMPONENT_BASE_STOPWATCH();
1265 AliHLTComponentDataType dt;
1266 SetDataType(dt, dtID, dtOrigin);
1267 int size=fOutputBufferSize-fOutputBufferFilled;
1268 if (capacity<0 || capacity>1.0) {
1269 HLTError("invalid parameter: capacity %f", capacity);
1272 size=(int)(size*capacity);
1273 return CreateMemoryFile(size, dt, spec);
1276 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1277 AliHLTUInt32_t spec,
1280 // see header file for function documentation
1281 ALIHLTCOMPONENT_BASE_STOPWATCH();
1282 int size=fOutputBufferSize-fOutputBufferFilled;
1283 if (capacity<0 || capacity>1.0) {
1284 HLTError("invalid parameter: capacity %f", capacity);
1287 size=(int)(size*capacity);
1288 return CreateMemoryFile(size, dt, spec);
1291 int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1292 const char* key, int option)
1294 // see header file for function documentation
1296 if (pFile && pObject) {
1298 iResult=pObject->Write(key, option);
1302 iResult=-pFile->GetErrno();
1303 if (iResult==-ENOSPC) {
1304 HLTError("error writing memory file, buffer too small");
1313 int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1315 // see header file for function documentation
1318 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1320 while (element!=fMemFiles.end() && iResult>=0) {
1321 if (*element && *element==pFile) {
1322 iResult=pFile->CloseMemoryFile();
1324 // sync memory files and descriptors
1326 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1334 HLTError("can not find memory file %p", pFile);
1342 int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
1344 // see header file for function documentation
1347 AliHLTComponentEventDoneData* newEDD = NULL;
1349 unsigned long newSize=edd.fDataSize;
1351 newSize += fEventDoneData->fDataSize;
1353 if (newSize>fEventDoneDataSize) {
1354 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1357 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1358 newEDD->fDataSize = newSize;
1359 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1360 unsigned long long offset = 0;
1361 if (fEventDoneData) {
1362 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1363 offset += fEventDoneData->fDataSize;
1365 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1367 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1368 fEventDoneData = newEDD;
1369 fEventDoneDataSize = newSize;
1372 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1373 fEventDoneData->fDataSize += edd.fDataSize;
1378 int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1379 const AliHLTComponentBlockData* blocks,
1380 AliHLTComponentTriggerData& trigData,
1381 AliHLTUInt8_t* outputPtr,
1382 AliHLTUInt32_t& size,
1383 AliHLTUInt32_t& outputBlockCnt,
1384 AliHLTComponentBlockData*& outputBlocks,
1385 AliHLTComponentEventDoneData*& edd )
1387 // see header file for function documentation
1388 HLTLogKeyword(fChainId.c_str());
1389 ALIHLTCOMPONENT_BASE_STOPWATCH();
1391 fCurrentEvent=evtData.fEventID;
1392 fCurrentEventData=evtData;
1393 fpInputBlocks=blocks;
1394 fCurrentInputBlock=-1;
1395 fSearchDataType=kAliHLTAnyDataType;
1396 fpOutputBuffer=outputPtr;
1397 fOutputBufferSize=size;
1398 fOutputBufferFilled=0;
1399 fOutputBlocks.clear();
1403 AliHLTComponentBlockDataList forwardedBlocks;
1405 // optional component statistics
1406 AliHLTComponentStatisticsList compStats;
1407 bool bAddComponentTableEntry=false;
1408 vector<AliHLTUInt32_t> parentComponentTables;
1409 #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1410 AliHLTComponentStatistics outputStat;
1411 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1412 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1413 outputStat.fId=fChainIdCrc;
1415 fpBenchmark->Stop();
1416 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1417 fpBenchmark->Reset();
1418 fpBenchmark->Start();
1420 compStats.push_back(outputStat);
1423 // data processing is skipped
1424 // - if there are only steering events in the block list.
1425 // For the sake of data source components data processing
1426 // is not skipped if there is no block list at all or if it
1427 // just contains the eventType block
1428 // - always skipped if the event is of type
1429 // - gkAliEventTypeConfiguration
1430 // - gkAliEventTypeReadPreprocessor
1431 const unsigned int skipModeDefault=0x1;
1432 const unsigned int skipModeForce=0x2;
1433 unsigned int bSkipDataProcessing=skipModeDefault;
1435 // find special events
1436 if (fpInputBlocks && evtData.fBlockCnt>0) {
1437 // first look for all special events and execute in the appropriate
1438 // sequence afterwords
1439 int indexComConfEvent=-1;
1440 int indexUpdtDCSEvent=-1;
1441 int indexSOREvent=-1;
1442 int indexEOREvent=-1;
1443 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
1444 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
1446 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1447 bSkipDataProcessing&=~skipModeDefault;
1448 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1450 // handling is not clear yet
1451 if (fpInputBlocks[i].fPtr) {
1452 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1454 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1456 // the calibration processor relies on the SOR and EOR events
1457 bSkipDataProcessing&=~skipModeDefault;
1458 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1460 // this event is most likely deprecated
1461 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1462 indexComConfEvent=i;
1463 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1464 indexUpdtDCSEvent=i;
1465 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
1466 fEventType=fpInputBlocks[i].fSpecification;
1468 // skip always in case of gkAliEventTypeConfiguration
1469 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
1471 // skip always in case of gkAliEventTypeReadPreprocessor
1472 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
1474 // never skip if the event type block is the only block
1475 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1477 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1478 if (compStats.size()>0) {
1479 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1480 for (AliHLTUInt32_t offset=0;
1481 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1482 offset+=sizeof(AliHLTComponentStatistics)) {
1483 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1484 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1485 compStats[0].fLevel=pStat->fLevel+1;
1487 compStats.push_back(*pStat);
1490 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1491 forwardedBlocks.push_back(fpInputBlocks[i]);
1492 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
1494 // the processing function is called if there is at least one
1495 // non-steering data block. Steering blocks are not filtered out
1496 // for sake of performance
1497 bSkipDataProcessing&=~skipModeDefault;
1498 if (compStats.size()>0) {
1499 compStats[0].fInputBlockCount++;
1500 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1505 if (indexSOREvent>=0) {
1507 bAddComponentTableEntry=true;
1508 if (fpRunDesc==NULL) {
1509 fpRunDesc=new AliHLTRunDesc;
1510 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
1513 AliHLTRunDesc rundesc;
1514 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1515 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1517 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1518 SetCDBRunNo(fpRunDesc->fRunNo);
1519 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1520 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
1527 if (indexEOREvent>=0) {
1528 bAddComponentTableEntry=true;
1529 if (fpRunDesc!=NULL) {
1531 AliHLTRunDesc rundesc;
1532 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1533 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1534 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
1536 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
1539 AliHLTRunDesc* pRunDesc=fpRunDesc;
1544 HLTWarning("did not receive SOR, ignoring EOR");
1547 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
1549 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
1550 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1552 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1553 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1555 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1558 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
1560 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1561 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1563 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1564 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
1566 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1570 // processing function needs to be called if there are no input data
1571 // blocks in order to make data source components working.
1572 bSkipDataProcessing&=~skipModeDefault;
1575 // data processing is not skipped if the component explicitly asks
1576 // for the private blocks
1577 if (fRequireSteeringBlocks) bSkipDataProcessing=0;
1579 AliHLTComponentBlockDataList blockData;
1580 if (iResult>=0 && !bSkipDataProcessing)
1581 { // dont delete, sets the scope for the stopwatch guard
1582 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1583 // in order to avoid 'shadowed variable' warning
1584 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
1585 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1586 } // end of the scope of the stopwatch guard
1587 if (iResult>=0 && !bSkipDataProcessing) {
1588 if (fOutputBlocks.size()>0) {
1589 // High Level interface
1591 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
1592 // sync memory files and descriptors
1593 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1595 while (element!=fMemFiles.end() && iResult>=0) {
1597 if ((*element)->IsClosed()==0) {
1598 HLTWarning("memory file has not been closed, force flush");
1599 iResult=CloseMemoryFile(*element);
1606 // create the descriptor list
1607 if (blockData.size()>0) {
1608 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1611 if (compStats.size()>0 && IsDataEvent()) {
1612 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1613 if (offset>0) fOutputBufferFilled+=offset;
1615 if (bAddComponentTableEntry) {
1616 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
1617 if (offset>0) size+=offset;
1619 if (forwardedBlocks.size()>0) {
1620 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1622 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1623 size=fOutputBufferFilled;
1627 // Low Level interface
1628 if (compStats.size()>0) {
1629 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1630 if (offset>0) size+=offset;
1632 if (bAddComponentTableEntry) {
1633 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
1634 if (offset>0) size+=offset;
1636 if (forwardedBlocks.size()>0) {
1637 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1639 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1642 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1645 if (iResult<0 || bSkipDataProcessing) {
1649 CleanupInputObjects();
1650 if (iResult>=0 && IsDataEvent()) {
1651 IncrementEventCounter();
1653 if (outputBlockCnt==0) {
1654 // no output blocks, set size to 0
1657 FillEventData(fCurrentEventData);
1661 int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1662 AliHLTUInt8_t* buffer,
1663 AliHLTUInt32_t bufferSize,
1664 AliHLTUInt32_t offset,
1665 AliHLTComponentStatisticsList& stats) const
1667 // see header file for function documentation
1669 #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1670 if (stats.size()==0) return -ENOENT;
1671 // check if there is space for at least one entry
1672 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
1673 stats[0].fTotalOutputSize=offset;
1674 stats[0].fOutputBlockCount=blocks.size();
1676 fpBenchmark->Stop();
1677 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1678 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1679 fpBenchmark->Continue();
1681 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
1682 AliHLTUInt32_t removedLevel=0;
1684 // remove all entries of the level of the last entry
1685 removedLevel=stats.back().fLevel;
1686 AliHLTComponentStatisticsList::iterator element=stats.begin();
1688 while (element!=stats.end()) {
1689 if (element->fLevel<=removedLevel) {
1690 element=stats.erase(element);
1695 } while (stats.size()>1 &&
1696 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
1698 assert(stats.size()>0);
1699 if (stats.size()==0) return 0;
1701 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1702 AliHLTComponentBlockData bd;
1703 FillBlockData( bd );
1704 bd.fOffset = offset;
1705 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1706 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1707 bd.fSpecification = kAliHLTVoidDataSpec;
1708 unsigned int master=0;
1709 for (unsigned int i=1; i<blocks.size(); i++) {
1710 if (blocks[i].fSize>blocks[master].fSize &&
1711 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1714 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1715 // take the data origin of the biggest block as specification
1716 // this is similar to the treatment in the HOMER interface. For traditional
1717 // reasons, the bytes are swapped there on a little endian architecture, so
1718 // we do it as well.
1719 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1720 #ifdef R__BYTESWAP // set on little endian architectures
1721 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1722 ((bd.fSpecification & 0xFF00ULL) << 8) |
1723 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1724 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1727 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1728 blocks.push_back(bd);
1732 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
1733 // get rid of warning
1739 int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1740 AliHLTUInt8_t* buffer,
1741 AliHLTUInt32_t bufferSize,
1742 AliHLTUInt32_t offset,
1743 const vector<AliHLTUInt32_t>& parents) const
1745 // see header file for function documentation
1747 #if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1748 // the payload consists of the AliHLTComponentTableEntry struct,
1749 // followed by a an array of 32bit crc chain ids and the component
1750 // description string
1751 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
1752 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
1754 // the component description has the following format:
1755 // chain-id{component-id:arguments}
1756 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
1757 unsigned int descriptionSize=fChainId.size()+1;
1758 descriptionSize+=2; // the '{}' around the component id
1759 descriptionSize+=strlen(componentId);
1760 descriptionSize+=1; // the ':' between component id and arguments
1761 descriptionSize+=fComponentArgs.size();
1763 payloadSize+=descriptionSize;
1764 if (buffer && (offset+payloadSize<=bufferSize)) {
1765 AliHLTUInt8_t* pTgt=buffer+offset;
1766 memset(pTgt, 0, payloadSize);
1769 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
1770 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
1771 pEntry->fNofParents=parents.size();
1772 pEntry->fSizeDescription=descriptionSize;
1773 pTgt=pEntry->fBuffer;
1775 // write array of parents
1776 if (parents.size()>0) {
1777 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
1778 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
1782 // write component description
1783 memcpy(pTgt, fChainId.c_str(), fChainId.size());
1784 pTgt+=fChainId.size();
1786 memcpy(pTgt, componentId, strlen(componentId));
1787 pTgt+=strlen(componentId);
1789 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
1790 pTgt+=fComponentArgs.size();
1794 AliHLTComponentBlockData bd;
1795 FillBlockData( bd );
1796 bd.fOffset = offset;
1797 bd.fSize = payloadSize;
1798 bd.fDataType = kAliHLTDataTypeComponentTable;
1799 bd.fSpecification = fChainIdCrc;
1800 blocks.push_back(bd);
1804 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
1805 // get rid of warning
1811 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1816 // standard constructor (not for use)
1819 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1821 fpStopwatch(pStopwatch),
1826 // check for already existing guard
1827 if (fgpCurrent) fpPrec=fgpCurrent;
1830 // stop the preceeding guard if it controls a different stopwatch
1832 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1834 // start the stopwatch if the current guard controls a different one
1835 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1838 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
1844 // copy constructor not for use
1848 AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1851 // assignment operator not for use
1858 AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1860 AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1864 // resume the preceeding guard if it controls a different stopwatch
1866 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1868 // stop the stopwatch if the current guard controls a different one
1869 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1871 // resume to the preceeding guard
1875 int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1877 // see header file for function documentation
1878 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1879 return fpStopwatch!=pSucc?1:0;
1882 int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1884 // see header file for function documentation
1885 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1886 return fpStopwatch!=pSucc?1:0;
1889 int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
1891 // see header file for function documentation
1893 if (pSW!=NULL && type<kSWTypeCount) {
1894 if (fpStopwatches) {
1895 TObject* pObj=fpStopwatches->At((int)type);
1896 if (pSW==NULL // explicit reset
1897 || pObj==NULL) { // explicit set
1898 fpStopwatches->AddAt(pSW, (int)type);
1899 } else if (pObj!=pSW) {
1900 HLTWarning("stopwatch %d already set, reset first", (int)type);
1910 int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1912 // see header file for function documentation
1913 if (pStopwatches==NULL) return -EINVAL;
1916 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1917 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1921 AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1923 // see header file for function documentation
1924 if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
1925 return fpRunDesc->fRunNo;
1928 AliHLTUInt32_t AliHLTComponent::GetRunType() const
1930 // see header file for function documentation
1931 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
1932 return fpRunDesc->fRunType;
1935 bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
1937 // see header file for function documentation
1938 if (pTgt) *pTgt=fEventType;
1939 return (fEventType==gkAliEventTypeData ||
1940 fEventType==gkAliEventTypeDataReplay ||
1941 fEventType==gkAliEventTypeCalibration);
1944 int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
1945 const char* structname, const char* eventname)
1947 // see header file for function documentation
1949 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1950 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1951 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1952 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
1953 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
1954 if (fpInputBlocks[iBlockNo].fSize!=copy) {
1955 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
1956 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1958 if (copy!=iStructSize) {
1959 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
1960 if (copy>iStructSize) {
1963 memset(pTgt, 0, iStructSize);
1966 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
1970 HLTWarning("%s event: missing data block", eventname);
1976 HLTError("invalid struct");
1982 void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1984 // see header file for function documentation
1986 // -- Detector offset
1987 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
1989 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
1992 if ( ddlIdBase <= 3 )
1993 wordBase = ddlIdBase;
1994 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1995 wordBase = ddlIdBase + 7;
1997 wordBase = ddlIdBase + 9;
1999 // -- Bit index in Word
2000 Int_t bitIdx = ddlId % 32;
2003 Int_t wordIdx = wordBase;
2005 // -- if TPC (3) or TOD (5) add word idx
2006 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
2007 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
2010 // -- Set -- 'OR' word with bit mask;
2012 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
2013 // -- Unset -- 'AND' word with bit mask;
2015 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
2018 Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
2020 // see header file for function documentation
2024 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
2026 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
2027 // check for special cases TPC and TOF
2028 if ( wordNdx > 3 && wordNdx <= 10 ) {
2032 else if ( wordNdx > 12 && wordNdx <= 14 ) {
2039 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
2040 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
2049 AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2051 // see header file for function documentation
2052 AliHLTUInt32_t remainder = 0;
2053 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2054 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2055 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2058 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2061 * Perform modulo-2 division, a byte at a time.
2063 for (int byte = 0; byte < size; ++byte)
2066 * Bring the next byte into the remainder.
2068 remainder ^= (buffer[byte] << (crcwidth - 8));
2071 * Perform modulo-2 division, a bit at a time.
2073 for (uint8_t bit = 8; bit > 0; --bit)
2076 * Try to divide the current data bit.
2078 if (remainder & topbit)
2080 remainder = (remainder << 1) ^ polynomial;
2084 remainder = (remainder << 1);
2090 * The final remainder is the CRC result.
2095 int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2096 string& retChainId, string& retCompId, string& retCompArgs,
2097 vector<AliHLTUInt32_t>& parents)
2099 // see header file for function documentation
2102 retCompArgs.clear();
2104 if (!pBuffer || size==0) return 0;
2106 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2107 if (size<8/* the initial size of the structure*/ ||
2108 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2109 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2110 const AliHLTUInt8_t* pEnd=pBuffer+size;
2112 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2113 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2114 parents.push_back(*pParents);
2117 const char* pDescription=reinterpret_cast<const char*>(pParents);
2118 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2119 *(pDescription+pEntry->fSizeDescription)!=0) {
2123 TString descriptor=reinterpret_cast<const char*>(pDescription);
2127 TObjArray* pTokens=descriptor.Tokenize("{");
2130 if (pTokens->GetEntries()>n) {
2131 retChainId=((TObjString*)pTokens->At(n++))->GetString();
2133 if (pTokens->GetEntries()>n) {
2134 compId=((TObjString*)pTokens->At(n++))->GetString();
2138 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2140 if (pTokens->GetEntries()>n) {
2141 compId=((TObjString*)pTokens->At(n++))->GetString();
2143 if (pTokens->GetEntries()>n) {
2144 compArgs=((TObjString*)pTokens->At(n++))->GetString();
2148 compId.ReplaceAll("}", "");
2149 compArgs.ReplaceAll("}", "");
2152 retCompArgs=compArgs;
2154 if (retChainId.size()==0) return -ENODATA;
2159 int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2160 const char* originClass, const char* originFunc,
2161 const char* file, int line, ... ) const
2163 // see header file for function documentation
2167 va_start(args, line);
2169 // logging function needs to be const in order to be called from const member functions
2170 // without problems. But at this point we face the problem with virtual members which
2171 // are not necessarily const.
2172 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
2173 AliHLTLogging::SetLogString("%s (%s, %p): ",
2174 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
2175 nonconst->GetComponentID(), this);
2176 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));