DigitReaderPacket revived: uses AliRawReader and Stream (K. Aamodt)
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3/**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
f23a6e1a 8 * for The ALICE Off-line Project. *
9 * *
10 * Permission to use, copy, modify and distribute this software and its *
11 * documentation strictly for non-commercial purposes is hereby granted *
12 * without fee, provided that the above copyright notice appears in all *
13 * copies and that both the copyright notice and this permission notice *
14 * appear in the supporting documentation. The authors make no claims *
15 * about the suitability of this software for any purpose. It is *
16 * provided "as is" without express or implied warranty. *
17 **************************************************************************/
18
bfccbf68 19/** @file AliHLTComponent.cxx
20 @author Matthias Richter, Timm Steinbeck
21 @date
22 @brief Base class implementation for HLT components. */
f23a6e1a 23
0c0c9d99 24#if __GNUC__>= 3
f23a6e1a 25using namespace std;
26#endif
27
66043029 28//#include "AliHLTStdIncludes.h"
f23a6e1a 29#include "AliHLTComponent.h"
30#include "AliHLTComponentHandler.h"
a655eae3 31#include "AliHLTMessage.h"
70ed7d01 32#include "TString.h"
a655eae3 33#include "TObjArray.h"
34#include "TClass.h"
90ebac25 35#include "TStopwatch.h"
f23a6e1a 36
b22e91eb 37/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 38ClassImp(AliHLTComponent);
39
40/** stopwatch macro using the stopwatch guard */
41#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
42//#define ALIHLTCOMPONENT_STOPWATCH(type)
43
44/** stopwatch macro for operations of the base class */
45#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
46/** stopwatch macro for operations of the detector algorithm (DA) */
47#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 48
f23a6e1a 49AliHLTComponent::AliHLTComponent()
85869391 50 :
53feaef5 51 fEnvironment(),
3cde846d 52 fCurrentEvent(0),
a655eae3 53 fEventCount(-1),
54 fFailedEvents(0),
55 fCurrentEventData(),
56 fpInputBlocks(NULL),
57 fCurrentInputBlock(-1),
58 fSearchDataType(kAliHLTVoidDataType),
59 fClassName(),
60 fpInputObjects(NULL),
61 fpOutputBuffer(NULL),
62 fOutputBufferSize(0),
63 fOutputBufferFilled(0),
90ebac25 64 fOutputBlocks(),
65 fpStopwatches(new TObjArray(kSWTypeCount))
70ed7d01 66{
67 // see header file for class documentation
68 // or
69 // refer to README to build package
70 // or
71 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
f23a6e1a 72 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
70ed7d01 73 if (fgpComponentHandler)
74 fgpComponentHandler->ScheduleRegister(this);
8451168b 75 SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 76}
77
78AliHLTComponent::AliHLTComponent(const AliHLTComponent&)
79 :
9253e11b 80 AliHLTLogging(),
70ed7d01 81 fEnvironment(),
82 fCurrentEvent(0),
a655eae3 83 fEventCount(-1),
84 fFailedEvents(0),
85 fCurrentEventData(),
86 fpInputBlocks(NULL),
87 fCurrentInputBlock(-1),
88 fSearchDataType(kAliHLTVoidDataType),
89 fClassName(),
90 fpInputObjects(NULL),
91 fpOutputBuffer(NULL),
92 fOutputBufferSize(0),
93 fOutputBufferFilled(0),
90ebac25 94 fOutputBlocks(),
95 fpStopwatches(NULL)
70ed7d01 96{
97 // see header file for class documentation
98 HLTFatal("copy constructor untested");
99}
100
101AliHLTComponent& AliHLTComponent::operator=(const AliHLTComponent&)
102{
103 // see header file for class documentation
104 HLTFatal("assignment operator untested");
105 return *this;
f23a6e1a 106}
107
108AliHLTComponent::~AliHLTComponent()
109{
70ed7d01 110 // see header file for function documentation
8451168b 111 CleanupInputObjects();
4498d7d1 112 if (fpStopwatches!=NULL) delete fpStopwatches;
113 fpStopwatches=NULL;
f23a6e1a 114}
115
70ed7d01 116AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 117
85869391 118int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
119{
70ed7d01 120 // see header file for function documentation
85869391 121 int iResult=0;
70ed7d01 122 if (fgpComponentHandler==NULL || bOverwrite!=0)
123 fgpComponentHandler=pCH;
85869391 124 else
125 iResult=-EPERM;
126 return iResult;
127}
128
70ed7d01 129int AliHLTComponent::UnsetGlobalComponentHandler()
130{
131 // see header file for function documentation
85869391 132 return SetGlobalComponentHandler(NULL,1);
133}
134
70ed7d01 135int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv )
f23a6e1a 136{
70ed7d01 137 // see header file for function documentation
f23a6e1a 138 int iResult=0;
139 if (environ) {
140 memcpy(&fEnvironment, environ, sizeof(AliHLTComponentEnvironment));
70ed7d01 141 fEnvironment.fParam=environParam;
f23a6e1a 142 }
8451168b 143 const char** pArguments=NULL;
144 int iNofChildArgs=0;
145 TString argument="";
146 int bMissingParam=0;
147 if (argc>0) {
148 pArguments=new const char*[argc];
149 if (pArguments) {
150 for (int i=0; i<argc && iResult>=0; i++) {
151 argument=argv[i];
152 if (argument.IsNull()) continue;
153
154 // benchmark
155 if (argument.CompareTo("benchmark")==0) {
156
157 // loglevel
158 } else if (argument.CompareTo("loglevel")==0) {
159 if ((bMissingParam=(++i>=argc))) break;
160 TString parameter(argv[i]);
161 parameter.Remove(TString::kLeading, ' '); // remove all blanks
162 if (parameter.BeginsWith("0x") &&
163 parameter.Replace(0,2,"",0).IsHex()) {
164 AliHLTComponentLogSeverity loglevel=kHLTLogNone;
7a5ccd96 165 sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel);
8451168b 166 SetLocalLoggingLevel(loglevel);
167 } else {
168 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
169 iResult=-EINVAL;
170 }
171 } else {
172 pArguments[iNofChildArgs++]=argv[i];
173 }
174 }
175 } else {
176 iResult=-ENOMEM;
177 }
178 }
179 if (bMissingParam) {
180 HLTError("missing parameter for argument %s", argument.Data());
181 iResult=-EINVAL;
182 }
183 if (iResult>=0) {
184 iResult=DoInit(iNofChildArgs, pArguments);
185 }
3cde846d 186 if (iResult>=0) fEventCount=0;
8451168b 187 if (pArguments) delete [] pArguments;
f23a6e1a 188 return iResult;
189}
190
191int AliHLTComponent::Deinit()
192{
70ed7d01 193 // see header file for function documentation
f23a6e1a 194 int iResult=0;
195 iResult=DoDeinit();
196 return iResult;
197}
fa2e9b7c 198
53feaef5 199int AliHLTComponent::DoInit( int argc, const char** argv )
200{
70ed7d01 201 // see header file for function documentation
53feaef5 202 if (argc==0 && argv==NULL) {
203 // this is currently just to get rid of the warning "unused parameter"
204 }
66043029 205 fEventCount=0;
53feaef5 206 return 0;
207}
208
209int AliHLTComponent::DoDeinit()
210{
70ed7d01 211 // see header file for function documentation
66043029 212 fEventCount=0;
53feaef5 213 return 0;
214}
215
70ed7d01 216void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
217{
218 // see header file for function documentation
9ce4bf4a 219 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
220 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
221 strcat( output, ":" );
222 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 223}
224
9ce4bf4a 225string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type )
226{
70ed7d01 227 // see header file for function documentation
9ce4bf4a 228 string out("");
3cde846d 229
9ce4bf4a 230 if (type==kAliHLTVoidDataType) {
231 out="VOID:VOID";
232 } else {
3cde846d 233 // some gymnastics in order to avoid a '0' which is part of either or both
234 // ID and origin terminating the whole string. Unfortunately, string doesn't
235 // stop appending at the '0' if the number of elements to append was
236 // explicitely specified
237 string tmp("");
238 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
239 out.append(tmp.c_str());
9ce4bf4a 240 out.append(":");
3cde846d 241 tmp="";
242 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
243 out.append(tmp.c_str());
9ce4bf4a 244 }
245 return out;
246}
247
248
70ed7d01 249void* AliHLTComponent::AllocMemory( unsigned long size )
250{
251 // see header file for function documentation
85869391 252 if (fEnvironment.fAllocMemoryFunc)
253 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 254 HLTFatal("no memory allocation handler registered");
85869391 255 return NULL;
256}
257
8ede8717 258int AliHLTComponent::MakeOutputDataBlockList( const vector<AliHLTComponentBlockData>& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 259 AliHLTComponentBlockData** outputBlocks )
260{
261 // see header file for function documentation
9ce4bf4a 262 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 263 return -EFAULT;
fa2e9b7c 264 AliHLTUInt32_t count = blocks.size();
265 if ( !count )
266 {
267 *blockCount = 0;
268 *outputBlocks = NULL;
269 return 0;
270 }
8ede8717 271 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 272 if ( !*outputBlocks )
2d7ff710 273 return -ENOMEM;
ca8524df 274 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 275 (*outputBlocks)[i] = blocks[i];
ca8524df 276 if (blocks[i].fDataType==kAliHLTAnyDataType) {
5f5b708b 277 (*outputBlocks)[i].fDataType=GetOutputDataType();
278 /* data type was set to the output data type by the PubSub AliRoot
279 Wrapper component, if data type of the block was ********:****.
280 Now handled by the component base class in order to have same
281 behavior when running embedded in AliRoot
ca8524df 282 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
283 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 284 */
ca8524df 285 }
286 }
fa2e9b7c 287 *blockCount = count;
288 return 0;
289
290}
0c0c9d99 291
70ed7d01 292int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd )
293{
294 // see header file for function documentation
85869391 295 if (fEnvironment.fGetEventDoneDataFunc)
296 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
297 return -ENOSYS;
298}
299
8ede8717 300int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, vector<AliHLTComponentDataType>* tgtList)
0c0c9d99 301{
70ed7d01 302 // see header file for function documentation
0c0c9d99 303 int iResult=0;
304 if (pConsumer) {
8ede8717 305 vector<AliHLTComponentDataType> ctlist;
0c0c9d99 306 ((AliHLTComponent*)pConsumer)->GetInputDataTypes(ctlist);
8ede8717 307 vector<AliHLTComponentDataType>::iterator type=ctlist.begin();
5f5b708b 308 //AliHLTComponentDataType ouptdt=GetOutputDataType();
309 //PrintDataTypeContent(ouptdt, "publisher \'%s\'");
0c0c9d99 310 while (type!=ctlist.end() && iResult==0) {
5f5b708b 311 //PrintDataTypeContent((*type), "consumer \'%s\'");
9ce4bf4a 312 if ((*type)==GetOutputDataType() ||
313 (*type)==kAliHLTAnyDataType) {
0c0c9d99 314 if (tgtList) tgtList->push_back(*type);
315 iResult++;
9ce4bf4a 316 // this loop has to be changed in case of multiple output types
0c0c9d99 317 break;
318 }
319 type++;
320 }
321 } else {
322 iResult=-EINVAL;
323 }
324 return iResult;
325}
2d7ff710 326
5f5b708b 327void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format) const
328{
66043029 329 // see header file for function documentation
5f5b708b 330 const char* fmt="publisher \'%s\'";
331 if (format) fmt=format;
332 HLTMessage(fmt, (DataType2Text(dt)).c_str());
333 HLTMessage("%x %x %x %x %x %x %x %x : %x %x %x %x",
334 dt.fID[0],
335 dt.fID[1],
336 dt.fID[2],
337 dt.fID[3],
338 dt.fID[4],
339 dt.fID[5],
340 dt.fID[6],
341 dt.fID[7],
342 dt.fOrigin[0],
343 dt.fOrigin[1],
344 dt.fOrigin[2],
345 dt.fOrigin[3]);
346}
347
70ed7d01 348void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData ) const
349{
350 // see header file for function documentation
2d7ff710 351 blockData.fStructSize = sizeof(blockData);
352 FillShmData( blockData.fShmKey );
353 blockData.fOffset = ~(AliHLTUInt32_t)0;
354 blockData.fPtr = NULL;
355 blockData.fSize = 0;
356 FillDataType( blockData.fDataType );
a655eae3 357 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 358}
359
70ed7d01 360void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData ) const
361{
362 // see header file for function documentation
2d7ff710 363 shmData.fStructSize = sizeof(shmData);
364 shmData.fShmType = gkAliHLTComponentInvalidShmType;
365 shmData.fShmID = gkAliHLTComponentInvalidShmID;
366}
367
70ed7d01 368void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType ) const
369{
370 // see header file for function documentation
ca8524df 371 dataType=kAliHLTAnyDataType;
2d7ff710 372}
373
70ed7d01 374void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
375{
376 // see header file for function documentation
2d7ff710 377 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
378 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
379}
380
70ed7d01 381void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
382{
383 // see header file for function documentation
2d7ff710 384 tgtdt.fStructSize = sizeof(AliHLTComponentDataType);
385 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
386 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
387
9ce4bf4a 388 if ((int)strlen(id)>kAliHLTComponentDataTypefIDsize) {
2d7ff710 389 HLTWarning("data type id %s is too long, truncated to %d", id, kAliHLTComponentDataTypefIDsize);
390 }
391 strncpy(&tgtdt.fID[0], id, kAliHLTComponentDataTypefIDsize);
392
9ce4bf4a 393 if ((int)strlen(origin)>kAliHLTComponentDataTypefOriginSize) {
2d7ff710 394 HLTWarning("data type origin %s is too long, truncated to %d", origin, kAliHLTComponentDataTypefOriginSize);
395 }
396 strncpy(&tgtdt.fOrigin[0], origin, kAliHLTComponentDataTypefOriginSize);
397}
9ce4bf4a 398
399void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
400{
70ed7d01 401 // see header file for function documentation
9ce4bf4a 402 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
403 evtData.fStructSize=sizeof(AliHLTComponentEventData);
404}
405
70ed7d01 406void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
407{
408 // see header file for function documentation
9ce4bf4a 409 TString msg;
410 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
411 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
412 if (dt.fID[i]!=0) msg+=dt.fID[i];
413 else msg+="\\0";
414 }
415 msg+="\" Origin=\"";
416 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
417 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
418 else msg+="\\0";
419 }
420 msg+="\"";
3cde846d 421 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 422}
423
70ed7d01 424int AliHLTComponent::GetEventCount() const
3cde846d 425{
70ed7d01 426 // see header file for function documentation
3cde846d 427 return fEventCount;
428}
429
430int AliHLTComponent::IncrementEventCounter()
431{
70ed7d01 432 // see header file for function documentation
3cde846d 433 if (fEventCount>=0) fEventCount++;
434 return fEventCount;
435}
436
66043029 437int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 438{
439 // see header file for function documentation
440 if (fpInputBlocks!=NULL) {
441 return fCurrentEventData.fBlockCnt;
442 }
443 return 0;
444}
445
446const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
447 const char* classname,
448 int bForce)
449{
450 // see header file for function documentation
90ebac25 451 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 452 fSearchDataType=dt;
453 if (classname) fClassName=classname;
454 else fClassName.clear();
455 int idx=FindInputBlock(fSearchDataType, 0);
8451168b 456 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 457 TObject* pObj=NULL;
458 if (idx>=0) {
459 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
460 fCurrentInputBlock=idx;
461 } else {
462 }
463 }
464 return pObj;
465}
466
467const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
468 const char* dtOrigin,
469 const char* classname,
470 int bForce)
471{
472 // see header file for function documentation
90ebac25 473 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 474 AliHLTComponentDataType dt;
475 SetDataType(dt, dtID, dtOrigin);
476 return GetFirstInputObject(dt, classname, bForce);
477}
478
479const TObject* AliHLTComponent::GetNextInputObject(int bForce)
480{
481 // see header file for function documentation
90ebac25 482 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 483 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
484 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
485 TObject* pObj=NULL;
486 if (idx>=0) {
487 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
488 fCurrentInputBlock=idx;
489 }
490 }
491 return pObj;
492}
493
66043029 494int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx) const
a655eae3 495{
496 // see header file for function documentation
497 int iResult=-ENOENT;
498 if (fpInputBlocks!=NULL) {
499 int idx=startIdx<0?0:startIdx;
4b98eadb 500 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
a655eae3 501 if (dt == kAliHLTAnyDataType || fpInputBlocks[idx].fDataType == dt) {
502 iResult=idx;
503 }
504 }
505 }
506 return iResult;
507}
508
509TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
510{
511 // see header file for function documentation
512 TObject* pObj=NULL;
513 if (fpInputBlocks!=NULL) {
4b98eadb 514 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 515 if (fpInputBlocks[idx].fPtr) {
516 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
517 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 518 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
a655eae3 519 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 520 TClass* objclass=msg.GetClass();
521 pObj=msg.ReadObject(objclass);
522 if (pObj && objclass) {
523 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 524 } else {
525 }
526 } else {
527 // } else if (bForce!=0) {
528 HLTError("size missmatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
529 }
530 } else {
531 HLTFatal("block descriptor empty");
532 }
533 } else {
534 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
535 }
536 } else {
537 HLTError("no input blocks available");
538 }
539
540 return pObj;
541}
542
543TObject* AliHLTComponent::GetInputObject(int idx, const char* classname, int bForce)
544{
545 // see header file for function documentation
546 if (fpInputObjects==NULL) {
547 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
548 }
549 TObject* pObj=NULL;
550 if (fpInputObjects) {
551 pObj=fpInputObjects->At(idx);
552 if (pObj==NULL) {
553 pObj=CreateInputObject(idx, bForce);
554 if (pObj) {
555 fpInputObjects->AddAt(pObj, idx);
556 }
557 }
558 } else {
559 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
560 }
561 return pObj;
562}
563
8451168b 564int AliHLTComponent::CleanupInputObjects()
565{
66043029 566 // see header file for function documentation
8451168b 567 if (!fpInputObjects) return 0;
568 TObjArray* array=fpInputObjects;
569 fpInputObjects=NULL;
570 for (int i=0; i<array->GetEntries(); i++) {
571 TObject* pObj=array->At(i);
572 if (pObj) delete pObj;
573 }
574 delete array;
90ebac25 575 return 0;
8451168b 576}
577
a655eae3 578AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
579{
580 // see header file for function documentation
90ebac25 581 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 582 AliHLTComponentDataType dt=kAliHLTVoidDataType;
583 int idx=fCurrentInputBlock;
584 if (pObject) {
585 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
586 } else {
587 HLTError("unknown object %p", pObject);
588 }
589 }
590 if (idx>=0) {
4b98eadb 591 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 592 dt=fpInputBlocks[idx].fDataType;
593 } else {
594 HLTFatal("severe internal error, index out of range");
595 }
596 }
597 return dt;
598}
599
600AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
601{
602 // see header file for function documentation
90ebac25 603 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 604 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
605 int idx=fCurrentInputBlock;
606 if (pObject) {
607 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
608 } else {
609 HLTError("unknown object %p", pObject);
610 }
611 }
612 if (idx>=0) {
4b98eadb 613 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 614 iSpec=fpInputBlocks[idx].fSpecification;
615 } else {
616 HLTFatal("severe internal error, index out of range");
617 }
618 }
619 return iSpec;
620}
621
622const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
623{
624 // see header file for function documentation
90ebac25 625 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 626 fSearchDataType=dt;
627 fClassName.clear();
628 int idx=FindInputBlock(fSearchDataType, 0);
629 const AliHLTComponentBlockData* pBlock=NULL;
630 if (idx>=0) {
631 // check for fpInputBlocks pointer done in FindInputBlock
632 pBlock=&fpInputBlocks[idx];
633 }
634 return pBlock;
635}
636
637const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
638 const char* dtOrigin)
639{
640 // see header file for function documentation
90ebac25 641 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 642 AliHLTComponentDataType dt;
643 SetDataType(dt, dtID, dtOrigin);
644 return GetFirstInputBlock(dt);
645}
646
647const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
648{
649 // see header file for function documentation
90ebac25 650 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 651 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
652 const AliHLTComponentBlockData* pBlock=NULL;
653 if (idx>=0) {
654 // check for fpInputBlocks pointer done in FindInputBlock
655 pBlock=&fpInputBlocks[idx];
656 }
657 return pBlock;
658}
659
66043029 660int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 661{
662 // see header file for function documentation
663 int iResult=-ENOENT;
664 if (fpInputBlocks!=NULL) {
665 if (pBlock) {
666 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 667 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 668 }
669 } else {
670 iResult=-EINVAL;
671 }
672 }
673 return iResult;
674}
675
676AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
677{
678 // see header file for function documentation
90ebac25 679 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 680 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
681 int idx=fCurrentInputBlock;
682 if (pBlock) {
683 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
684 } else {
685 HLTError("unknown Block %p", pBlock);
686 }
687 }
688 if (idx>=0) {
689 // check for fpInputBlocks pointer done in FindInputBlock
690 iSpec=fpInputBlocks[idx].fSpecification;
691 }
692 return iSpec;
693}
694
695int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
696{
697 // see header file for function documentation
90ebac25 698 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 699 int iResult=0;
700 if (pObject) {
701 AliHLTMessage msg(kMESS_OBJECT);
702 msg.WriteObject(pObject);
703 Int_t iMsgLength=msg.Length();
704 if (iMsgLength>0) {
705 msg.SetLength(); // sets the length to the first (reserved) word
706 iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec);
707 if (iResult>=0) {
8451168b 708 HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
a655eae3 709 }
710 } else {
711 HLTError("object serialization failed for object %p", pObject);
712 iResult=-ENOMSG;
713 }
714 } else {
715 iResult=-EINVAL;
716 }
717 return iResult;
718}
719
720int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
721{
722 // see header file for function documentation
90ebac25 723 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 724 AliHLTComponentDataType dt;
725 SetDataType(dt, dtID, dtOrigin);
726 return PushBack(pObject, dt, spec);
727}
728
729int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
730{
731 // see header file for function documentation
90ebac25 732 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 733 return InsertOutputBlock(pBuffer, iSize, dt, spec);
734}
735
736int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
737{
738 // see header file for function documentation
90ebac25 739 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 740 AliHLTComponentDataType dt;
741 SetDataType(dt, dtID, dtOrigin);
742 return PushBack(pBuffer, iSize, dt, spec);
743}
744
745int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
746{
747 // see header file for function documentation
748 int iResult=0;
749 if (pBuffer) {
7a5ccd96 750 if (fpOutputBuffer && iSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 751 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
752 AliHLTComponentBlockData bd;
753 FillBlockData( bd );
754 bd.fOffset = fOutputBufferFilled;
755 bd.fPtr = pTgt;
756 bd.fSize = iSize;
757 bd.fDataType = dt;
758 bd.fSpecification = spec;
759 if (pBuffer!=NULL && pBuffer!=pTgt) {
760 memcpy(pTgt, pBuffer, iSize);
4b98eadb 761 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
a655eae3 762 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iSize, pBuffer, pTgt, firstWord);
763 }
764 fOutputBufferFilled+=bd.fSize;
765 fOutputBlocks.push_back( bd );
766 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iSize, DataType2Text(dt).c_str(), spec);
767 } else {
768 if (fpOutputBuffer) {
769 HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iSize);
770 } else {
771 HLTError("output buffer not available");
772 }
773 iResult=-ENOSPC;
774 }
775 } else {
776 iResult=-EINVAL;
777 }
778 return iResult;
779}
780
8451168b 781int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
782{
66043029 783 // see header file for function documentation
8451168b 784 if (!pObject) return -EINVAL;
785 AliHLTMessage msg(kMESS_OBJECT);
786 msg.WriteObject(pObject);
787 return msg.Length();
788}
789
a655eae3 790int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
791{
792 // see header file for function documentation
793 int iResult=-ENOSYS;
794 //#warning function not yet implemented
795 HLTWarning("function not yet implemented");
796 return iResult;
797}
798
3cde846d 799int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
800 const AliHLTComponentBlockData* blocks,
801 AliHLTComponentTriggerData& trigData,
802 AliHLTUInt8_t* outputPtr,
803 AliHLTUInt32_t& size,
804 AliHLTUInt32_t& outputBlockCnt,
805 AliHLTComponentBlockData*& outputBlocks,
806 AliHLTComponentEventDoneData*& edd )
807{
70ed7d01 808 // see header file for function documentation
90ebac25 809 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 810 int iResult=0;
811 fCurrentEvent=evtData.fEventID;
a655eae3 812 fCurrentEventData=evtData;
813 fpInputBlocks=blocks;
814 fCurrentInputBlock=-1;
815 fSearchDataType=kAliHLTAnyDataType;
816 fpOutputBuffer=outputPtr;
817 fOutputBufferSize=size;
818 fOutputBufferFilled=0;
819 fOutputBlocks.clear();
820
821 vector<AliHLTComponentBlockData> blockData;
90ebac25 822 { // dont delete, sets the scope for the stopwatch guard
823 ALIHLTCOMPONENT_DA_STOPWATCH();
824 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
825 } // end of the scope of the stopwatch guard
a655eae3 826 if (iResult>=0) {
827 if (fOutputBlocks.size()>0) {
828 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
829 if (blockData.size()>0) {
830 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
831 iResult=-EFAULT;
832 } else {
833 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
834 size=fOutputBufferFilled;
835 }
836 } else {
837 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
838 }
839 if (iResult<0) {
840 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
841 }
842 }
843 if (iResult<0) {
844 outputBlockCnt=0;
845 outputBlocks=NULL;
846 }
8451168b 847 CleanupInputObjects();
3cde846d 848 IncrementEventCounter();
849 return iResult;
850}
a655eae3 851
90ebac25 852AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
853 :
854 fpStopwatch(NULL),
855 fpPrec(NULL)
856{
857 // standard constructor (not for use)
858}
859
860AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
861 :
862 fpStopwatch(pStopwatch),
863 fpPrec(NULL)
864{
865 // constructor
866
867 // check for already existing guard
868 if (fgpCurrent) fpPrec=fgpCurrent;
869 fgpCurrent=this;
870
871 // stop the preceeding guard if it controls a different stopwatch
872 int bStart=1;
873 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
874
875 // start the stopwatch if the current guard controls a different one
876 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
877}
878
879AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(AliHLTStopwatchGuard&)
880 :
881 fpStopwatch(NULL),
882 fpPrec(NULL)
883{
884 // copy constructor (not for use)
885}
886
887AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
888
889AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
890{
891 // destructor
892
893 // resume the preceeding guard if it controls a different stopwatch
894 int bStop=1;
895 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
896
897 // stop the stopwatch if the current guard controls a different one
898 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
899
900 // resume to the preceeding guard
901 fgpCurrent=fpPrec;
902}
903
904int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
905{
906 // see header file for function documentation
907 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
908 return fpStopwatch!=pSucc?1:0;
909}
910
911int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
912{
913 // see header file for function documentation
914 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
915 return fpStopwatch!=pSucc?1:0;
916}
917
918int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
919{
920 // see header file for function documentation
921 int iResult=0;
922 if (pSW!=NULL && type<kSWTypeCount) {
923 if (fpStopwatches) {
924 TObject* pObj=fpStopwatches->At((int)type);
925 if (pSW==NULL // explicit reset
926 || pObj==NULL) { // explicit set
927 fpStopwatches->AddAt(pSW, (int)type);
928 } else if (pObj!=pSW) {
929 HLTWarning("stopwatch %d already set, reset first", (int)type);
930 iResult=-EBUSY;
931 }
932 }
933 } else {
934 iResult=-EINVAL;
935 }
936 return iResult;
937}
938
939int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
940{
941 // see header file for function documentation
942 if (pStopwatches==NULL) return -EINVAL;
943
944 int iResult=0;
945 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
946 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
947 return iResult;
948}