Improved Clusterizer and rawanalyzer
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3dd8541e 3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9//* for The ALICE HLT Project. *
10//* *
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//**************************************************************************
f23a6e1a 19
bfccbf68 20/** @file AliHLTComponent.cxx
21 @author Matthias Richter, Timm Steinbeck
22 @date
23 @brief Base class implementation for HLT components. */
f23a6e1a 24
0c0c9d99 25#if __GNUC__>= 3
f23a6e1a 26using namespace std;
27#endif
28
66043029 29//#include "AliHLTStdIncludes.h"
f23a6e1a 30#include "AliHLTComponent.h"
31#include "AliHLTComponentHandler.h"
a655eae3 32#include "AliHLTMessage.h"
70ed7d01 33#include "TString.h"
ed504011 34#include "TMath.h"
a655eae3 35#include "TObjArray.h"
79c114b5 36#include "TObjectTable.h"
a655eae3 37#include "TClass.h"
90ebac25 38#include "TStopwatch.h"
79c114b5 39#include "AliHLTMemoryFile.h"
579d9eb7 40#include "AliHLTMisc.h"
ec25e4ca 41#include <cassert>
0da432fa 42#include <stdint.h>
f23a6e1a 43
b22e91eb 44/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 45ClassImp(AliHLTComponent);
46
47/** stopwatch macro using the stopwatch guard */
48#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
49//#define ALIHLTCOMPONENT_STOPWATCH(type)
50
51/** stopwatch macro for operations of the base class */
52#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
53/** stopwatch macro for operations of the detector algorithm (DA) */
54#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 55
f23a6e1a 56AliHLTComponent::AliHLTComponent()
85869391 57 :
53feaef5 58 fEnvironment(),
3cde846d 59 fCurrentEvent(0),
a655eae3 60 fEventCount(-1),
61 fFailedEvents(0),
62 fCurrentEventData(),
63 fpInputBlocks(NULL),
64 fCurrentInputBlock(-1),
65 fSearchDataType(kAliHLTVoidDataType),
66 fClassName(),
67 fpInputObjects(NULL),
68 fpOutputBuffer(NULL),
69 fOutputBufferSize(0),
70 fOutputBufferFilled(0),
90ebac25 71 fOutputBlocks(),
79c114b5 72 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 73 fMemFiles(),
74 fpRunDesc(NULL),
579d9eb7 75 fpDDLList(NULL),
82c58a87 76 fCDBSetRunNoFunc(false),
a0aeb701 77 fChainId(),
48abe484 78 fChainIdCrc(0),
a0aeb701 79 fpBenchmark(NULL),
48abe484 80 fRequireSteeringBlocks(false),
abb52c8f 81 fEventType(gkAliEventTypeUnknown),
82 fComponentArgs()
70ed7d01 83{
84 // see header file for class documentation
85 // or
86 // refer to README to build package
87 // or
88 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
a3c9b745 89 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
70ed7d01 90 if (fgpComponentHandler)
91 fgpComponentHandler->ScheduleRegister(this);
7c781d33 92 //SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 93}
94
f23a6e1a 95AliHLTComponent::~AliHLTComponent()
96{
70ed7d01 97 // see header file for function documentation
a0aeb701 98 if (fpBenchmark) delete fpBenchmark;
99 fpBenchmark=NULL;
100
8451168b 101 CleanupInputObjects();
4498d7d1 102 if (fpStopwatches!=NULL) delete fpStopwatches;
103 fpStopwatches=NULL;
2be3f004 104 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 105 while (element!=fMemFiles.end()) {
106 if (*element) {
107 if ((*element)->IsClosed()==0) {
108 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
109 // close but do not flush as we dont know whether the buffer is still valid
29312178 110 (*element)->CloseMemoryFile(0);
79c114b5 111 }
112 delete *element;
113 *element=NULL;
114 }
115 element++;
116 }
45c0a780 117 if (fpRunDesc) {
118 delete fpRunDesc;
119 fpRunDesc=NULL;
120 }
f23a6e1a 121}
122
70ed7d01 123AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 124
85869391 125int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
126{
70ed7d01 127 // see header file for function documentation
85869391 128 int iResult=0;
70ed7d01 129 if (fgpComponentHandler==NULL || bOverwrite!=0)
130 fgpComponentHandler=pCH;
85869391 131 else
132 iResult=-EPERM;
133 return iResult;
134}
135
70ed7d01 136int AliHLTComponent::UnsetGlobalComponentHandler()
137{
138 // see header file for function documentation
85869391 139 return SetGlobalComponentHandler(NULL,1);
140}
141
a3c9b745 142int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
f23a6e1a 143{
70ed7d01 144 // see header file for function documentation
b2065764 145 HLTLogKeyword(GetComponentID());
f23a6e1a 146 int iResult=0;
f7561f8d 147 if (comenv) {
a3c9b745 148 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
149 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
150 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
70ed7d01 151 fEnvironment.fParam=environParam;
f23a6e1a 152 }
abb52c8f 153 fComponentArgs="";
8451168b 154 const char** pArguments=NULL;
155 int iNofChildArgs=0;
156 TString argument="";
157 int bMissingParam=0;
158 if (argc>0) {
159 pArguments=new const char*[argc];
160 if (pArguments) {
161 for (int i=0; i<argc && iResult>=0; i++) {
abb52c8f 162 if (fComponentArgs.size()>0) fComponentArgs+=" ";
163 fComponentArgs+=argv[i];
8451168b 164 argument=argv[i];
165 if (argument.IsNull()) continue;
166
167 // benchmark
168 if (argument.CompareTo("benchmark")==0) {
169
170 // loglevel
171 } else if (argument.CompareTo("loglevel")==0) {
172 if ((bMissingParam=(++i>=argc))) break;
173 TString parameter(argv[i]);
174 parameter.Remove(TString::kLeading, ' '); // remove all blanks
175 if (parameter.BeginsWith("0x") &&
176 parameter.Replace(0,2,"",0).IsHex()) {
bd6cac58 177 unsigned int loglevel=kHLTLogNone;
178 sscanf(parameter.Data(),"%x", &loglevel);
179 SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
8451168b 180 } else {
181 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
182 iResult=-EINVAL;
183 }
184 } else {
185 pArguments[iNofChildArgs++]=argv[i];
186 }
187 }
188 } else {
189 iResult=-ENOMEM;
190 }
191 }
192 if (bMissingParam) {
193 HLTError("missing parameter for argument %s", argument.Data());
194 iResult=-EINVAL;
195 }
196 if (iResult>=0) {
197 iResult=DoInit(iNofChildArgs, pArguments);
198 }
a0aeb701 199 if (iResult>=0) {
200 fEventCount=0;
201
202 // find out if the component wants to get the steering events
203 // explicitly
204 AliHLTComponentDataTypeList inputDt;
205 GetInputDataTypes(inputDt);
206 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
207 dt!=inputDt.end() && !fRequireSteeringBlocks;
208 dt++) {
209 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
210 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
211 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
212 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
213 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
214 }
215 }
8451168b 216 if (pArguments) delete [] pArguments;
a0aeb701 217
218#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
219 // benchmarking stopwatch for the component statistics
220 fpBenchmark=new TStopwatch;
221 if (fpBenchmark) {
222 fpBenchmark->Start();
223 }
224#endif
225
f23a6e1a 226 return iResult;
227}
228
229int AliHLTComponent::Deinit()
230{
70ed7d01 231 // see header file for function documentation
b2065764 232 HLTLogKeyword(GetComponentID());
f23a6e1a 233 int iResult=0;
234 iResult=DoDeinit();
559631d5 235 if (fpRunDesc) {
236 HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
237 AliHLTRunDesc* pRunDesc=fpRunDesc;
238 fpRunDesc=NULL;
239 delete pRunDesc;
240 }
579d9eb7 241 fEventCount=0;
f23a6e1a 242 return iResult;
243}
fa2e9b7c 244
82c58a87 245int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
53feaef5 246{
82c58a87 247 // see header file for function documentation
579d9eb7 248 int iResult=0;
703bcca6 249 if (pHandler) {
82c58a87 250 // I have to think about separating the library handling from the
251 // component handler. Requiring the component hanlder here is not
252 // the cleanest solution.
253 // We presume the library already to be loaded
579d9eb7 254 // find the symbol
82c58a87 255 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
579d9eb7 256 if (pFunc) {
703bcca6 257 TString path;
258 if (cdbPath && cdbPath[0]!=0) {
259 path=cdbPath;
260 // very temporary fix, have to check for other formats
261 if (!path.BeginsWith("local://")) {
262 path="local://";
263 path+=cdbPath;
264 }
8f30c1ea 265 }
266 if ((iResult=(*pFunc)(path.Data()))>=0) {
82c58a87 267 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
268 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
269 "can not find function to set CDB run no");
270 }
271 }
579d9eb7 272 } else {
273 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
274 "can not find initialization function");
275 iResult=-ENOSYS;
53feaef5 276 }
82c58a87 277 } else {
278 iResult=-EINVAL;
279 }
579d9eb7 280 return iResult;
281}
282
283int AliHLTComponent::SetCDBRunNo(int runNo)
284{
82c58a87 285 // see header file for function documentation
286 if (!fCDBSetRunNoFunc) return 0;
287 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
579d9eb7 288}
289
45c0a780 290int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
291{
292 // see header file for function documentation
293 if (!desc) return -EINVAL;
294 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
295 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
296 return -EINVAL;
297 }
298
299 if (!fpRunDesc) {
300 fpRunDesc=new AliHLTRunDesc;
301 if (!fpRunDesc) return -ENOMEM;
302 *fpRunDesc=kAliHLTVoidRunDesc;
303 }
304
305 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
306 HLTWarning("Run description has already been set");
307 }
308 *fpRunDesc=*desc;
309 SetCDBRunNo(fpRunDesc->fRunNo);
310 // TODO: we have to decide about the runType
311 return 0;
312}
313
9a0ef890 314int AliHLTComponent::SetComponentDescription(const char* desc)
315{
48abe484 316 // see header file for function documentation
9a0ef890 317 int iResult=0;
318 if (!desc) return 0;
319
320 TString descriptor=desc;
321 TObjArray* pTokens=descriptor.Tokenize(" ");
322 if (pTokens) {
323 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
324 TString argument=((TObjString*)pTokens->At(i++))->GetString();
325 if (!argument || argument.IsNull()) continue;
326
a3c9b745 327 // chainid
328 if (argument.BeginsWith("chainid")) {
329 argument.ReplaceAll("chainid", "");
9a0ef890 330 if (argument.BeginsWith("=")) {
331 fChainId=argument.Replace(0,1,"");
48abe484 332 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
333 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
9a0ef890 334 } else {
335 fChainId="";
336 }
337 } else {
48abe484 338 HLTWarning("unknown component description %s", argument.Data());
9a0ef890 339 }
340 }
341 }
342
343 return iResult;
344}
345
579d9eb7 346int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
347{
348 // default implementation, childs can overload
b543e186 349 HLTLogKeyword("dummy");
53feaef5 350 return 0;
351}
352
353int AliHLTComponent::DoDeinit()
354{
579d9eb7 355 // default implementation, childs can overload
b543e186 356 HLTLogKeyword("dummy");
579d9eb7 357 return 0;
358}
359
360int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
361{
362 // default implementation, childs can overload
b543e186 363 HLTLogKeyword("dummy");
364 return 0;
365}
366
367int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
368{
369 // default implementation, childs can overload
370 HLTLogKeyword("dummy");
53feaef5 371 return 0;
372}
373
45c0a780 374int AliHLTComponent::StartOfRun()
375{
376 // default implementation, childs can overload
377 HLTLogKeyword("dummy");
378 return 0;
379}
380
381int AliHLTComponent::EndOfRun()
382{
383 // default implementation, childs can overload
384 HLTLogKeyword("dummy");
385 return 0;
386}
387
388
2be3f004 389int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
de6593d0 390{
82c58a87 391 // default implementation, childs can overload
3a7c0444 392 HLTLogKeyword("dummy");
de6593d0 393 return 0;
394}
395
70ed7d01 396void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
397{
398 // see header file for function documentation
9ce4bf4a 399 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
400 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
401 strcat( output, ":" );
402 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 403}
404
fbdb63fd 405string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
9ce4bf4a 406{
70ed7d01 407 // see header file for function documentation
9ce4bf4a 408 string out("");
fbdb63fd 409
410 if (mode==2) {
411 int i=0;
412 char tmp[8];
413 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
414 sprintf(tmp, "'%d", type.fOrigin[i]);
415 out+=tmp;
416 }
417 out+="':'";
418 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
419 sprintf(tmp, "%d'", type.fID[i]);
420 out+=tmp;
421 }
422 return out;
423 }
424
425 if (mode==1) {
426 int i=0;
427 char tmp[8];
428 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
429 unsigned char* puc=(unsigned char*)type.fOrigin;
430 if ((puc[i])<32)
431 sprintf(tmp, "'\\%x", type.fOrigin[i]);
432 else
433 sprintf(tmp, "'%c", type.fOrigin[i]);
434 out+=tmp;
435 }
436 out+="':'";
437 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
438 unsigned char* puc=(unsigned char*)type.fID;
439 if (puc[i]<32)
440 sprintf(tmp, "\\%x'", type.fID[i]);
441 else
442 sprintf(tmp, "%c'", type.fID[i]);
443 out+=tmp;
444 }
445 return out;
446 }
447
9ce4bf4a 448 if (type==kAliHLTVoidDataType) {
449 out="VOID:VOID";
450 } else {
3cde846d 451 // some gymnastics in order to avoid a '0' which is part of either or both
452 // ID and origin terminating the whole string. Unfortunately, string doesn't
453 // stop appending at the '0' if the number of elements to append was
454 // explicitely specified
455 string tmp("");
456 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
457 out.append(tmp.c_str());
9ce4bf4a 458 out.append(":");
3cde846d 459 tmp="";
460 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
461 out.append(tmp.c_str());
9ce4bf4a 462 }
463 return out;
464}
465
466
70ed7d01 467void* AliHLTComponent::AllocMemory( unsigned long size )
468{
469 // see header file for function documentation
85869391 470 if (fEnvironment.fAllocMemoryFunc)
471 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 472 HLTFatal("no memory allocation handler registered");
85869391 473 return NULL;
474}
475
2be3f004 476int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 477 AliHLTComponentBlockData** outputBlocks )
478{
479 // see header file for function documentation
9ce4bf4a 480 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 481 return -EFAULT;
fa2e9b7c 482 AliHLTUInt32_t count = blocks.size();
483 if ( !count )
484 {
485 *blockCount = 0;
486 *outputBlocks = NULL;
487 return 0;
488 }
8ede8717 489 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 490 if ( !*outputBlocks )
2d7ff710 491 return -ENOMEM;
ca8524df 492 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 493 (*outputBlocks)[i] = blocks[i];
732e8f50 494 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
5f5b708b 495 (*outputBlocks)[i].fDataType=GetOutputDataType();
496 /* data type was set to the output data type by the PubSub AliRoot
497 Wrapper component, if data type of the block was ********:****.
498 Now handled by the component base class in order to have same
499 behavior when running embedded in AliRoot
ca8524df 500 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
501 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 502 */
ca8524df 503 }
504 }
fa2e9b7c 505 *blockCount = count;
506 return 0;
507
508}
0c0c9d99 509
70ed7d01 510int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd )
511{
512 // see header file for function documentation
85869391 513 if (fEnvironment.fGetEventDoneDataFunc)
514 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
515 return -ENOSYS;
516}
517
2be3f004 518int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
0c0c9d99 519{
70ed7d01 520 // see header file for function documentation
0c0c9d99 521 int iResult=0;
522 if (pConsumer) {
8a106878 523 AliHLTComponentDataTypeList itypes;
524 AliHLTComponentDataTypeList otypes;
525 otypes.push_back(GetOutputDataType());
526 if (otypes[0]==kAliHLTMultipleDataType) {
527 otypes.clear();
528 int count=0;
529 if ((count=GetOutputDataTypes(otypes))>0) {
530 } else if (GetComponentType()!=kSink) {
531 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
532 }
533 }
534 ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
48abe484 535 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
536 for (;otype!=otypes.end();otype++) {
537 //PrintDataTypeContent((*otype), "publisher \'%s\'");
538 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
539 if (tgtList) tgtList->push_back(*otype);
540 iResult++;
541 continue;
542 }
543
544 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
545 for (;itype!=itypes.end() && (*itype)!=(*otype); itype++);
546 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
547 if (itype!=itypes.end()) {
548 if (tgtList) tgtList->push_back(*otype);
0c0c9d99 549 iResult++;
0c0c9d99 550 }
0c0c9d99 551 }
552 } else {
553 iResult=-EINVAL;
554 }
555 return iResult;
556}
2d7ff710 557
8b97f4f1 558void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
5f5b708b 559{
66043029 560 // see header file for function documentation
8b97f4f1 561 const char* fmt="\'%s\'";
5f5b708b 562 if (format) fmt=format;
8b97f4f1 563 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
564 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
565 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
566 dt.fID[0],
567 dt.fID[1],
568 dt.fID[2],
569 dt.fID[3],
570 dt.fID[4],
571 dt.fID[5],
572 dt.fID[6],
573 dt.fID[7],
574 dt.fOrigin[0],
575 dt.fOrigin[1],
576 dt.fOrigin[2],
577 dt.fOrigin[3]));
5f5b708b 578}
579
fbdb63fd 580void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
70ed7d01 581{
582 // see header file for function documentation
2d7ff710 583 blockData.fStructSize = sizeof(blockData);
584 FillShmData( blockData.fShmKey );
585 blockData.fOffset = ~(AliHLTUInt32_t)0;
586 blockData.fPtr = NULL;
587 blockData.fSize = 0;
588 FillDataType( blockData.fDataType );
a655eae3 589 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 590}
591
fbdb63fd 592void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
70ed7d01 593{
594 // see header file for function documentation
2d7ff710 595 shmData.fStructSize = sizeof(shmData);
596 shmData.fShmType = gkAliHLTComponentInvalidShmType;
597 shmData.fShmID = gkAliHLTComponentInvalidShmID;
598}
599
fbdb63fd 600void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
70ed7d01 601{
602 // see header file for function documentation
ca8524df 603 dataType=kAliHLTAnyDataType;
2d7ff710 604}
605
70ed7d01 606void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
607{
608 // see header file for function documentation
2d7ff710 609 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
610 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
611}
612
70ed7d01 613void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
614{
615 // see header file for function documentation
7e3efc8f 616 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
617 if (id) {
618 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
d76bc02a 619 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
7e3efc8f 620 }
621 if (origin) {
622 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
d76bc02a 623 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
7e3efc8f 624 }
2d7ff710 625}
9ce4bf4a 626
18b56222 627void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
628{
629 // see header file for function documentation
630 dt.fStructSize=sizeof(AliHLTComponentDataType);
631 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
632 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
633 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
634 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
635}
636
9ce4bf4a 637void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
638{
70ed7d01 639 // see header file for function documentation
9ce4bf4a 640 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
641 evtData.fStructSize=sizeof(AliHLTComponentEventData);
48abe484 642 evtData.fEventID=kAliHLTVoidEventID;
9ce4bf4a 643}
644
70ed7d01 645void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
646{
647 // see header file for function documentation
9ce4bf4a 648 TString msg;
649 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
650 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
651 if (dt.fID[i]!=0) msg+=dt.fID[i];
652 else msg+="\\0";
653 }
654 msg+="\" Origin=\"";
655 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
656 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
657 else msg+="\\0";
658 }
659 msg+="\"";
3cde846d 660 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 661}
662
70ed7d01 663int AliHLTComponent::GetEventCount() const
3cde846d 664{
70ed7d01 665 // see header file for function documentation
3cde846d 666 return fEventCount;
667}
668
669int AliHLTComponent::IncrementEventCounter()
670{
70ed7d01 671 // see header file for function documentation
3cde846d 672 if (fEventCount>=0) fEventCount++;
673 return fEventCount;
674}
675
66043029 676int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 677{
678 // see header file for function documentation
679 if (fpInputBlocks!=NULL) {
680 return fCurrentEventData.fBlockCnt;
681 }
682 return 0;
683}
684
685const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
686 const char* classname,
687 int bForce)
688{
689 // see header file for function documentation
90ebac25 690 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 691 fSearchDataType=dt;
692 if (classname) fClassName=classname;
693 else fClassName.clear();
1edbbe49 694 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 695 TObject* pObj=NULL;
696 if (idx>=0) {
79c114b5 697 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 698 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
699 fCurrentInputBlock=idx;
700 } else {
701 }
702 }
703 return pObj;
704}
705
706const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
707 const char* dtOrigin,
708 const char* classname,
709 int bForce)
710{
711 // see header file for function documentation
90ebac25 712 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 713 AliHLTComponentDataType dt;
714 SetDataType(dt, dtID, dtOrigin);
715 return GetFirstInputObject(dt, classname, bForce);
716}
717
718const TObject* AliHLTComponent::GetNextInputObject(int bForce)
719{
720 // see header file for function documentation
90ebac25 721 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 722 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 723 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
724 TObject* pObj=NULL;
725 if (idx>=0) {
726 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
727 fCurrentInputBlock=idx;
728 }
729 }
730 return pObj;
731}
732
1edbbe49 733int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 734{
735 // see header file for function documentation
736 int iResult=-ENOENT;
737 if (fpInputBlocks!=NULL) {
738 int idx=startIdx<0?0:startIdx;
4b98eadb 739 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 740 if (dt!=fpInputBlocks[idx].fDataType) continue;
741
1edbbe49 742 if (bObject!=0) {
743 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 744 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
745 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 746 }
3dd8541e 747 iResult=idx;
a655eae3 748 }
749 }
750 return iResult;
751}
752
753TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
754{
755 // see header file for function documentation
756 TObject* pObj=NULL;
757 if (fpInputBlocks!=NULL) {
4b98eadb 758 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 759 if (fpInputBlocks[idx].fPtr) {
3294f81a 760 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 761 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 762 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 763 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 764 TClass* objclass=msg.GetClass();
765 pObj=msg.ReadObject(objclass);
766 if (pObj && objclass) {
767 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 768 } else {
769 }
1edbbe49 770 //} else {
771 } else if (bForce!=0) {
c5123824 772 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 773 }
774 } else {
775 HLTFatal("block descriptor empty");
776 }
777 } else {
778 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
779 }
780 } else {
781 HLTError("no input blocks available");
782 }
783
784 return pObj;
785}
786
298ef463 787TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 788{
789 // see header file for function documentation
790 if (fpInputObjects==NULL) {
791 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
792 }
793 TObject* pObj=NULL;
794 if (fpInputObjects) {
795 pObj=fpInputObjects->At(idx);
796 if (pObj==NULL) {
797 pObj=CreateInputObject(idx, bForce);
798 if (pObj) {
799 fpInputObjects->AddAt(pObj, idx);
800 }
801 }
802 } else {
803 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
804 }
805 return pObj;
806}
807
8451168b 808int AliHLTComponent::CleanupInputObjects()
809{
66043029 810 // see header file for function documentation
8451168b 811 if (!fpInputObjects) return 0;
812 TObjArray* array=fpInputObjects;
813 fpInputObjects=NULL;
814 for (int i=0; i<array->GetEntries(); i++) {
815 TObject* pObj=array->At(i);
79c114b5 816 // grrr, garbage collection strikes back: When read via AliHLTMessage
817 // (CreateInputObject), and written to a TFile afterwards, the
818 // TFile::Close calls ROOOT's garbage collection. No clue why the
819 // object ended up in the key list and needs to be deleted
820 if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
8451168b 821 }
822 delete array;
90ebac25 823 return 0;
8451168b 824}
825
a655eae3 826AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
827{
828 // see header file for function documentation
90ebac25 829 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 830 AliHLTComponentDataType dt=kAliHLTVoidDataType;
831 int idx=fCurrentInputBlock;
832 if (pObject) {
833 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
834 } else {
835 HLTError("unknown object %p", pObject);
836 }
837 }
838 if (idx>=0) {
4b98eadb 839 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 840 dt=fpInputBlocks[idx].fDataType;
841 } else {
842 HLTFatal("severe internal error, index out of range");
843 }
844 }
845 return dt;
846}
847
848AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
849{
850 // see header file for function documentation
90ebac25 851 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 852 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
853 int idx=fCurrentInputBlock;
854 if (pObject) {
855 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
856 } else {
857 HLTError("unknown object %p", pObject);
858 }
859 }
860 if (idx>=0) {
4b98eadb 861 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 862 iSpec=fpInputBlocks[idx].fSpecification;
863 } else {
864 HLTFatal("severe internal error, index out of range");
865 }
866 }
867 return iSpec;
868}
869
c7e9e2f2 870int AliHLTComponent::Forward(const TObject* pObject)
871{
872 // see header file for function documentation
873 int iResult=0;
874 int idx=fCurrentInputBlock;
875 if (pObject) {
876 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
877 } else {
878 HLTError("unknown object %p", pObject);
879 iResult=-ENOENT;
880 }
881 }
882 if (idx>=0) {
883 fOutputBlocks.push_back(fpInputBlocks[idx]);
884 }
885 return iResult;
886}
887
888int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
889{
890 // see header file for function documentation
891 int iResult=0;
892 int idx=fCurrentInputBlock;
893 if (pBlock) {
894 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
895 } else {
896 HLTError("unknown Block %p", pBlock);
897 iResult=-ENOENT;
898 }
899 }
900 if (idx>=0) {
901 // check for fpInputBlocks pointer done in FindInputBlock
902 fOutputBlocks.push_back(fpInputBlocks[idx]);
903 }
904 return iResult;
905}
906
a655eae3 907const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
908{
909 // see header file for function documentation
90ebac25 910 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 911 fSearchDataType=dt;
912 fClassName.clear();
913 int idx=FindInputBlock(fSearchDataType, 0);
914 const AliHLTComponentBlockData* pBlock=NULL;
915 if (idx>=0) {
916 // check for fpInputBlocks pointer done in FindInputBlock
917 pBlock=&fpInputBlocks[idx];
1edbbe49 918 fCurrentInputBlock=idx;
a655eae3 919 }
920 return pBlock;
921}
922
923const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
924 const char* dtOrigin)
925{
926 // see header file for function documentation
90ebac25 927 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 928 AliHLTComponentDataType dt;
929 SetDataType(dt, dtID, dtOrigin);
930 return GetFirstInputBlock(dt);
931}
932
10b9cbf9 933const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 934{
935 // see header file for function documentation
936 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 937 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 938 return &fpInputBlocks[index];
939}
940
a655eae3 941const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
942{
943 // see header file for function documentation
90ebac25 944 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 945 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
946 const AliHLTComponentBlockData* pBlock=NULL;
947 if (idx>=0) {
948 // check for fpInputBlocks pointer done in FindInputBlock
949 pBlock=&fpInputBlocks[idx];
1edbbe49 950 fCurrentInputBlock=idx;
a655eae3 951 }
952 return pBlock;
953}
954
66043029 955int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 956{
957 // see header file for function documentation
958 int iResult=-ENOENT;
959 if (fpInputBlocks!=NULL) {
960 if (pBlock) {
961 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 962 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 963 }
964 } else {
965 iResult=-EINVAL;
966 }
967 }
968 return iResult;
969}
970
971AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
972{
973 // see header file for function documentation
90ebac25 974 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 975 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
976 int idx=fCurrentInputBlock;
977 if (pBlock) {
978 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
979 } else {
980 HLTError("unknown Block %p", pBlock);
981 }
982 }
983 if (idx>=0) {
984 // check for fpInputBlocks pointer done in FindInputBlock
985 iSpec=fpInputBlocks[idx].fSpecification;
986 }
987 return iSpec;
988}
989
79c114b5 990int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
991 void* pHeader, int headerSize)
a655eae3 992{
993 // see header file for function documentation
90ebac25 994 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 995 int iResult=0;
996 if (pObject) {
997 AliHLTMessage msg(kMESS_OBJECT);
998 msg.WriteObject(pObject);
999 Int_t iMsgLength=msg.Length();
1000 if (iMsgLength>0) {
1001 msg.SetLength(); // sets the length to the first (reserved) word
438635e3 1002 assert(msg.Buffer()!=NULL);
79c114b5 1003 iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 1004 if (iResult>=0) {
8451168b 1005 HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
a655eae3 1006 }
1007 } else {
1008 HLTError("object serialization failed for object %p", pObject);
1009 iResult=-ENOMSG;
1010 }
1011 } else {
1012 iResult=-EINVAL;
1013 }
1014 return iResult;
1015}
1016
79c114b5 1017int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1018 void* pHeader, int headerSize)
a655eae3 1019{
1020 // see header file for function documentation
90ebac25 1021 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1022 AliHLTComponentDataType dt;
1023 SetDataType(dt, dtID, dtOrigin);
79c114b5 1024 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1025}
1026
438635e3 1027int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1028 const void* pHeader, int headerSize)
a655eae3 1029{
1030 // see header file for function documentation
90ebac25 1031 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d9ffd37 1032 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1033}
1034
438635e3 1035int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1036 const void* pHeader, int headerSize)
a655eae3 1037{
1038 // see header file for function documentation
90ebac25 1039 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1040 AliHLTComponentDataType dt;
1041 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1042 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1043}
1044
438635e3 1045int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1046 const void* pHeader, int iHeaderSize)
a655eae3 1047{
1048 // see header file for function documentation
1049 int iResult=0;
79c114b5 1050 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1051
1052 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1053 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1054 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1055
1056 // copy header if provided but skip if the header is the target location
1057 // in that case it has already been copied
79c114b5 1058 if (pHeader!=NULL && pHeader!=pTgt) {
1059 memcpy(pTgt, pHeader, iHeaderSize);
1060 }
1061
1062 pTgt += (AliHLTUInt8_t) iHeaderSize;
1063
438635e3 1064 // copy buffer if provided but skip if buffer is the target location
1065 // in that case it has already been copied
a655eae3 1066 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1067 memcpy(pTgt, pBuffer, iBufferSize);
1068
4b98eadb 1069 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1070 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1071 }
79c114b5 1072 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1073 } else {
1074 if (fpOutputBuffer) {
79c114b5 1075 HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
a655eae3 1076 } else {
1077 HLTError("output buffer not available");
1078 }
1079 iResult=-ENOSPC;
1080 }
a655eae3 1081 }
438635e3 1082 if (iResult>=0) {
1083 AliHLTComponentBlockData bd;
1084 FillBlockData( bd );
1085 bd.fOffset = fOutputBufferFilled;
1086 bd.fSize = iBlkSize;
1087 bd.fDataType = dt;
1088 bd.fSpecification = spec;
1089 fOutputBlocks.push_back( bd );
1090 fOutputBufferFilled+=bd.fSize;
1091 }
1092
a655eae3 1093 return iResult;
1094}
1095
8451168b 1096int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1097{
66043029 1098 // see header file for function documentation
8451168b 1099 if (!pObject) return -EINVAL;
1100 AliHLTMessage msg(kMESS_OBJECT);
1101 msg.WriteObject(pObject);
1102 return msg.Length();
1103}
1104
79c114b5 1105AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1106 const char* dtOrigin,
1107 AliHLTUInt32_t spec)
1108{
1109 // see header file for function documentation
1110 ALIHLTCOMPONENT_BASE_STOPWATCH();
1111 AliHLTComponentDataType dt;
1112 SetDataType(dt, dtID, dtOrigin);
1113 return CreateMemoryFile(capacity, dt, spec);
1114}
1115
1116AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1117 const AliHLTComponentDataType& dt,
1118 AliHLTUInt32_t spec)
1119{
1120 // see header file for function documentation
1121 ALIHLTCOMPONENT_BASE_STOPWATCH();
1122 AliHLTMemoryFile* pFile=NULL;
83fec083 1123 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1124 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1125 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1126 if (pFile) {
83fec083 1127 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1128 if (nofBlocks+1>fMemFiles.size()) {
1129 fMemFiles.resize(nofBlocks+1, NULL);
1130 }
1131 if (nofBlocks<fMemFiles.size()) {
1132 fMemFiles[nofBlocks]=pFile;
1133 AliHLTComponentBlockData bd;
1134 FillBlockData( bd );
1135 bd.fOffset = fOutputBufferFilled;
79c114b5 1136 bd.fSize = capacity;
1137 bd.fDataType = dt;
1138 bd.fSpecification = spec;
1139 fOutputBufferFilled+=bd.fSize;
1140 fOutputBlocks.push_back( bd );
1141 } else {
1142 HLTError("can not allocate/grow object array");
29312178 1143 pFile->CloseMemoryFile(0);
79c114b5 1144 delete pFile;
1145 pFile=NULL;
1146 }
1147 }
1148 } else {
1149 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1150 }
1151 return pFile;
1152}
1153
1154AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1155 const char* dtOrigin,
1156 AliHLTUInt32_t spec,
1157 float capacity)
1158{
1159 // see header file for function documentation
1160 ALIHLTCOMPONENT_BASE_STOPWATCH();
1161 AliHLTComponentDataType dt;
1162 SetDataType(dt, dtID, dtOrigin);
1163 int size=fOutputBufferSize-fOutputBufferFilled;
1164 if (capacity<0 || capacity>1.0) {
1165 HLTError("invalid parameter: capacity %f", capacity);
1166 return NULL;
1167 }
1168 size=(int)(size*capacity);
1169 return CreateMemoryFile(size, dt, spec);
1170}
1171
1172AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1173 AliHLTUInt32_t spec,
1174 float capacity)
1175{
1176 // see header file for function documentation
1177 ALIHLTCOMPONENT_BASE_STOPWATCH();
1178 int size=fOutputBufferSize-fOutputBufferFilled;
1179 if (capacity<0 || capacity>1.0) {
1180 HLTError("invalid parameter: capacity %f", capacity);
1181 return NULL;
1182 }
1183 size=(int)(size*capacity);
1184 return CreateMemoryFile(size, dt, spec);
1185}
1186
1187int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1188 const char* key, int option)
1189{
3a7c0444 1190 // see header file for function documentation
79c114b5 1191 int iResult=0;
1192 if (pFile && pObject) {
1193 pFile->cd();
1194 iResult=pObject->Write(key, option);
1195 if (iResult>0) {
1196 // success
1197 } else {
1198 iResult=-pFile->GetErrno();
1199 if (iResult==-ENOSPC) {
1200 HLTError("error writing memory file, buffer too small");
1201 }
1202 }
1203 } else {
1204 iResult=-EINVAL;
1205 }
1206 return iResult;
1207}
1208
1209int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1210{
3a7c0444 1211 // see header file for function documentation
79c114b5 1212 int iResult=0;
1213 if (pFile) {
2be3f004 1214 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1215 int i=0;
1216 while (element!=fMemFiles.end() && iResult>=0) {
1217 if (*element && *element==pFile) {
29312178 1218 iResult=pFile->CloseMemoryFile();
79c114b5 1219
1220 // sync memory files and descriptors
1221 if (iResult>=0) {
1222 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1223 }
1224 delete *element;
1225 *element=NULL;
1226 return iResult;
1227 }
1228 element++; i++;
1229 }
1230 HLTError("can not find memory file %p", pFile);
1231 iResult=-ENOENT;
1232 } else {
1233 iResult=-EINVAL;
1234 }
1235 return iResult;
1236}
1237
29312178 1238int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData /*edd*/)
a655eae3 1239{
1240 // see header file for function documentation
1241 int iResult=-ENOSYS;
1242 //#warning function not yet implemented
1243 HLTWarning("function not yet implemented");
1244 return iResult;
1245}
1246
3cde846d 1247int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1248 const AliHLTComponentBlockData* blocks,
1249 AliHLTComponentTriggerData& trigData,
1250 AliHLTUInt8_t* outputPtr,
1251 AliHLTUInt32_t& size,
1252 AliHLTUInt32_t& outputBlockCnt,
1253 AliHLTComponentBlockData*& outputBlocks,
1254 AliHLTComponentEventDoneData*& edd )
1255{
70ed7d01 1256 // see header file for function documentation
b2065764 1257 HLTLogKeyword(GetComponentID());
90ebac25 1258 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1259 int iResult=0;
1260 fCurrentEvent=evtData.fEventID;
a655eae3 1261 fCurrentEventData=evtData;
1262 fpInputBlocks=blocks;
1263 fCurrentInputBlock=-1;
1264 fSearchDataType=kAliHLTAnyDataType;
1265 fpOutputBuffer=outputPtr;
1266 fOutputBufferSize=size;
1267 fOutputBufferFilled=0;
1268 fOutputBlocks.clear();
96f9673a 1269 outputBlockCnt=0;
1270 outputBlocks=NULL;
438635e3 1271
1272 AliHLTComponentBlockDataList forwardedBlocks;
1273
1274 // optional component statistics
a0aeb701 1275 AliHLTComponentStatisticsList compStats;
438635e3 1276 bool bAddComponentTableEntry=false;
abb52c8f 1277 vector<AliHLTUInt32_t> parentComponentTables;
a0aeb701 1278#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1279 AliHLTComponentStatistics outputStat;
1280 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
48abe484 1281 outputStat.fId=fChainIdCrc;
a0aeb701 1282 compStats.push_back(outputStat);
1283 if (fpBenchmark) {
1284 fpBenchmark->Reset();
1285 fpBenchmark->Start();
1286 }
1287#endif
559631d5 1288
48abe484 1289 // data processing is skipped
1290 // - if there are only steering events in the block list.
1291 // For the sake of data source components data processing
1292 // is not skipped if there is no block list at all or if it
1293 // just contains the eventType block
1294 // - always skipped if the event is of type
1295 // - gkAliEventTypeConfiguration
1296 // - gkAliEventTypeReadPreprocessor
45c0a780 1297 const unsigned int skipModeDefault=0x1;
1298 const unsigned int skipModeForce=0x2;
1299 unsigned int bSkipDataProcessing=skipModeDefault;
1300
559631d5 1301 // find special events
45c0a780 1302 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1303 // first look for all special events and execute in the appropriate
1304 // sequence afterwords
1305 int indexComConfEvent=-1;
b543e186 1306 int indexUpdtDCSEvent=-1;
579d9eb7 1307 int indexSOREvent=-1;
1308 int indexEOREvent=-1;
83fec083 1309 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1310 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1311 indexSOREvent=i;
45c0a780 1312 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1313 bSkipDataProcessing&=~skipModeDefault;
1314 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1315 // run type string
1316 // handling is not clear yet
1317 if (fpInputBlocks[i].fPtr) {
1318 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1319 }
579d9eb7 1320 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1321 indexEOREvent=i;
45c0a780 1322 // the calibration processor relies on the SOR and EOR events
1323 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1324 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1325 // DDL list
1326 // this event is most likely deprecated
1327 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1328 indexComConfEvent=i;
b543e186 1329 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1330 indexUpdtDCSEvent=i;
1331 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1332 fEventType=fpInputBlocks[i].fSpecification;
1333
1334 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1335 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1336
1337 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1338 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1339
1340 // never skip if the event type block is the only block
1341 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1342
a0aeb701 1343 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1344 if (compStats.size()>0) {
1345 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1346 for (AliHLTUInt32_t offset=0;
1347 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1348 offset+=sizeof(AliHLTComponentStatistics)) {
1349 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1350 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1351 compStats[0].fLevel=pStat->fLevel+1;
1352 }
1353 compStats.push_back(*pStat);
1354 }
1355 }
438635e3 1356 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1357 forwardedBlocks.push_back(fpInputBlocks[i]);
abb52c8f 1358 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
45c0a780 1359 } else {
1360 // the processing function is called if there is at least one
1361 // non-steering data block. Steering blocks are not filtered out
1362 // for sake of performance
1363 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1364 if (compStats.size()>0) {
1365 compStats[0].fInputBlockCount++;
1366 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1367 }
579d9eb7 1368 }
1369 }
45c0a780 1370
579d9eb7 1371 if (indexSOREvent>=0) {
1372 // start of run
438635e3 1373 bAddComponentTableEntry=true;
579d9eb7 1374 if (fpRunDesc==NULL) {
1375 fpRunDesc=new AliHLTRunDesc;
48abe484 1376 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1377 }
1378 if (fpRunDesc) {
1379 AliHLTRunDesc rundesc;
1380 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1381 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1382 *fpRunDesc=rundesc;
579d9eb7 1383 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1384 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1385 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1386 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1387 }
559631d5 1388 }
579d9eb7 1389 } else {
45c0a780 1390 iResult=-ENOMEM;
579d9eb7 1391 }
1392 }
1393 if (indexEOREvent>=0) {
438635e3 1394 bAddComponentTableEntry=true;
579d9eb7 1395 if (fpRunDesc!=NULL) {
1396 if (fpRunDesc) {
1397 AliHLTRunDesc rundesc;
1398 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1399 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1400 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1401 } else {
1402 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1403 }
559631d5 1404 }
579d9eb7 1405 AliHLTRunDesc* pRunDesc=fpRunDesc;
1406 fpRunDesc=NULL;
1407 delete pRunDesc;
559631d5 1408 }
579d9eb7 1409 } else {
1410 HLTWarning("did not receive SOR, ignoring EOR");
1411 }
1412 }
48abe484 1413 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1414 TString cdbEntry;
b543e186 1415 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1416 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1417 }
1418 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1419 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1420 if (tmpResult<0) {
1421 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1422 }
1423 }
48abe484 1424 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1425 TString modules;
1426 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1427 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1428 }
d6b69874 1429 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1430 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1431 if (tmpResult<0) {
1432 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1433 }
1434 }
45c0a780 1435 } else {
1436 // processing function needs to be called if there are no input data
1437 // blocks in order to make data source components working.
1438 bSkipDataProcessing&=~skipModeDefault;
559631d5 1439 }
a0aeb701 1440
1441 // data processing is not skipped if the component explicitly asks
1442 // for the private blocks
1443 if (fRequireSteeringBlocks) bSkipDataProcessing=0;
1444
2be3f004 1445 AliHLTComponentBlockDataList blockData;
45c0a780 1446 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1447 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1448 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1449 // in order to avoid 'shadowed variable' warning
1450 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1451 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1452 } // end of the scope of the stopwatch guard
b543e186 1453 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1454 if (fOutputBlocks.size()>0) {
df61f928 1455 // High Level interface
1456
1457 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1458 // sync memory files and descriptors
2be3f004 1459 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1460 int i=0;
1461 while (element!=fMemFiles.end() && iResult>=0) {
1462 if (*element) {
1463 if ((*element)->IsClosed()==0) {
1464 HLTWarning("memory file has not been closed, force flush");
1465 iResult=CloseMemoryFile(*element);
1466 }
1467 }
1468 element++; i++;
1469 }
1470
1471 if (iResult>=0) {
1472 // create the descriptor list
1473 if (blockData.size()>0) {
1474 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1475 iResult=-EFAULT;
1476 } else {
abb52c8f 1477 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 1478 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1479 if (offset>0) fOutputBufferFilled+=offset;
1480 }
438635e3 1481 if (bAddComponentTableEntry) {
abb52c8f 1482 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
438635e3 1483 if (offset>0) size+=offset;
1484 }
1485 if (forwardedBlocks.size()>0) {
1486 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1487 }
79c114b5 1488 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1489 size=fOutputBufferFilled;
1490 }
a655eae3 1491 }
1492 } else {
df61f928 1493 // Low Level interface
a0aeb701 1494 if (compStats.size()>0) {
1495 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1496 if (offset>0) size+=offset;
1497 }
438635e3 1498 if (bAddComponentTableEntry) {
abb52c8f 1499 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
438635e3 1500 if (offset>0) size+=offset;
1501 }
1502 if (forwardedBlocks.size()>0) {
1503 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1504 }
a655eae3 1505 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1506 }
1507 if (iResult<0) {
1508 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1509 }
1510 }
b543e186 1511 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1512 outputBlockCnt=0;
1513 outputBlocks=NULL;
1514 }
8451168b 1515 CleanupInputObjects();
48abe484 1516 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1517 IncrementEventCounter();
1518 }
96f9673a 1519 if (outputBlockCnt==0) {
1520 // no output blocks, set size to 0
1521 size=0;
1522 }
3cde846d 1523 return iResult;
1524}
a655eae3 1525
a0aeb701 1526int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1527 AliHLTUInt8_t* buffer,
1528 AliHLTUInt32_t bufferSize,
1529 AliHLTUInt32_t offset,
1530 AliHLTComponentStatisticsList& stats) const
1531{
1532 // see header file for function documentation
1533 int iResult=0;
438635e3 1534#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
a0aeb701 1535 if (stats.size()==0) return -ENOENT;
1536 stats[0].fTotalOutputSize=offset;
1537 stats[0].fOutputBlockCount=blocks.size();
1538 if (fpBenchmark) {
1539 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*1000000);
1540 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*1000000);
1541 }
1542 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1543 AliHLTComponentBlockData bd;
1544 FillBlockData( bd );
1545 bd.fOffset = offset;
1546 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1547 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1548 bd.fSpecification = kAliHLTVoidDataSpec;
1549 unsigned int master=0;
1550 for (unsigned int i=1; i<blocks.size(); i++) {
1551 if (blocks[i].fSize>blocks[master].fSize &&
1552 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1553 master=i;
1554 }
1555 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1556 // take the data origin of the biggest block as specification
1557 // this is similar to the treatment in the HOMER interface. For traditional
1558 // reasons, the bytes are swapped there on a little endian architecture, so
1559 // we do it as well.
1560 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1561#ifdef R__BYTESWAP // set on little endian architectures
1562 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1563 ((bd.fSpecification & 0xFF00ULL) << 8) |
1564 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1565 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1566#endif
1567 }
1568 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1569 blocks.push_back(bd);
1570 iResult=bd.fSize;
1571 }
bd6cac58 1572#else
1573 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
1574 // get rid of warning
1575 }
438635e3 1576#endif
1577 return iResult;
1578}
1579
1580int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1581 AliHLTUInt8_t* buffer,
1582 AliHLTUInt32_t bufferSize,
abb52c8f 1583 AliHLTUInt32_t offset,
1584 const vector<AliHLTUInt32_t>& parents) const
438635e3 1585{
1586 // see header file for function documentation
1587 int iResult=0;
1588#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
abb52c8f 1589 // the payload consists of the AliHLTComponentTableEntry struct,
1590 // followed by a an array of 32bit crc chain ids and the component
1591 // description string
1592 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
1593 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
1594
1595 // the component description has the following format:
1596 // chain-id{component-id:arguments}
1597 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
1598 unsigned int descriptionSize=fChainId.size()+1;
1599 descriptionSize+=2; // the '{}' around the component id
1600 descriptionSize+=strlen(componentId);
1601 descriptionSize+=1; // the ':' between component id and arguments
1602 descriptionSize+=fComponentArgs.size();
1603
1604 payloadSize+=descriptionSize;
1605 if (buffer && (offset+payloadSize<=bufferSize)) {
1606 AliHLTUInt8_t* pTgt=buffer+offset;
1607 memset(pTgt, 0, payloadSize);
1608
1609 // write entry
1610 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
1611 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
1612 pEntry->fNofParents=parents.size();
1613 pEntry->fSizeDescription=descriptionSize;
1614 pTgt=pEntry->fBuffer;
1615
1616 // write array of parents
1617 if (parents.size()>0) {
1618 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
1619 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
1620 pTgt+=copy;
1621 }
1622
1623 // write component description
1624 memcpy(pTgt, fChainId.c_str(), fChainId.size());
1625 pTgt+=fChainId.size();
1626 *pTgt++='{';
1627 memcpy(pTgt, componentId, strlen(componentId));
1628 pTgt+=strlen(componentId);
1629 *pTgt++=':';
1630 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
1631 pTgt+=fComponentArgs.size();
1632 *pTgt++='}';
1633 *pTgt++=0;
1634
438635e3 1635 AliHLTComponentBlockData bd;
1636 FillBlockData( bd );
1637 bd.fOffset = offset;
abb52c8f 1638 bd.fSize = payloadSize;
438635e3 1639 bd.fDataType = kAliHLTDataTypeComponentTable;
1640 bd.fSpecification = fChainIdCrc;
438635e3 1641 blocks.push_back(bd);
1642 iResult=bd.fSize;
1643 }
bd6cac58 1644#else
1645 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
1646 // get rid of warning
1647 }
438635e3 1648 #endif
a0aeb701 1649 return iResult;
1650}
1651
90ebac25 1652AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1653 :
1654 fpStopwatch(NULL),
1655 fpPrec(NULL)
1656{
1657 // standard constructor (not for use)
1658}
1659
1660AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1661 :
1662 fpStopwatch(pStopwatch),
1663 fpPrec(NULL)
1664{
1665 // constructor
1666
1667 // check for already existing guard
1668 if (fgpCurrent) fpPrec=fgpCurrent;
1669 fgpCurrent=this;
1670
1671 // stop the preceeding guard if it controls a different stopwatch
1672 int bStart=1;
1673 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1674
1675 // start the stopwatch if the current guard controls a different one
1676 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1677}
1678
e419b223 1679AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 1680 :
1681 fpStopwatch(NULL),
1682 fpPrec(NULL)
1683{
e419b223 1684 //
1685 // copy constructor not for use
1686 //
1687}
1688
1689AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1690{
1691 //
1692 // assignment operator not for use
1693 //
1694 fpStopwatch=NULL;
1695 fpPrec=NULL;
1696 return *this;
90ebac25 1697}
1698
1699AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1700
1701AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1702{
1703 // destructor
1704
1705 // resume the preceeding guard if it controls a different stopwatch
1706 int bStop=1;
1707 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1708
1709 // stop the stopwatch if the current guard controls a different one
1710 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1711
1712 // resume to the preceeding guard
1713 fgpCurrent=fpPrec;
1714}
1715
1716int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1717{
1718 // see header file for function documentation
1719 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1720 return fpStopwatch!=pSucc?1:0;
1721}
1722
1723int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1724{
1725 // see header file for function documentation
1726 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1727 return fpStopwatch!=pSucc?1:0;
1728}
1729
1730int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
1731{
1732 // see header file for function documentation
1733 int iResult=0;
1734 if (pSW!=NULL && type<kSWTypeCount) {
1735 if (fpStopwatches) {
1736 TObject* pObj=fpStopwatches->At((int)type);
1737 if (pSW==NULL // explicit reset
1738 || pObj==NULL) { // explicit set
1739 fpStopwatches->AddAt(pSW, (int)type);
1740 } else if (pObj!=pSW) {
1741 HLTWarning("stopwatch %d already set, reset first", (int)type);
1742 iResult=-EBUSY;
1743 }
1744 }
1745 } else {
1746 iResult=-EINVAL;
1747 }
1748 return iResult;
1749}
1750
1751int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1752{
1753 // see header file for function documentation
1754 if (pStopwatches==NULL) return -EINVAL;
1755
1756 int iResult=0;
1757 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1758 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1759 return iResult;
1760}
559631d5 1761
1762AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1763{
29312178 1764 // see header file for function documentation
45c0a780 1765 if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
559631d5 1766 return fpRunDesc->fRunNo;
1767}
1768
1769AliHLTUInt32_t AliHLTComponent::GetRunType() const
1770{
29312178 1771 // see header file for function documentation
45c0a780 1772 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 1773 return fpRunDesc->fRunType;
1774}
1775
48abe484 1776bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
1777{
1778 // see header file for function documentation
1779 if (pTgt) *pTgt=fEventType;
1780 return (fEventType==gkAliEventTypeData ||
1781 fEventType==gkAliEventTypeDataReplay ||
1782 fEventType==gkAliEventTypeCalibration);
1783}
1784
83fec083 1785int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 1786 const char* structname, const char* eventname)
1787{
29312178 1788 // see header file for function documentation
559631d5 1789 int iResult=0;
1790 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1791 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1792 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1793 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 1794 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 1795 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 1796 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 1797 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1798 }
1799 if (copy!=iStructSize) {
c5123824 1800 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 1801 if (copy>iStructSize) {
1802 copy=iStructSize;
1803 } else {
1804 memset(pTgt, 0, iStructSize);
1805 }
1806 }
3294f81a 1807 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 1808 *pTgt=iStructSize;
1809 iResult=copy;
1810 } else {
1811 HLTWarning("%s event: missing data block", eventname);
1812 }
1813 } else {
1814 iResult=-ENODATA;
1815 }
1816 } else {
1817 HLTError("invalid struct");
1818 iResult=-EINVAL;
1819 }
1820 return iResult;
1821}
ed504011 1822
1823void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1824{
1825 // see header file for function documentation
1826
1827 // -- Detector offset
1828 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
1829
1830 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
1831 Int_t wordBase = 0;
1832
1833 if ( ddlIdBase <= 3 )
1834 wordBase = ddlIdBase;
1835 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1836 wordBase = ddlIdBase + 7;
1837 else
1838 wordBase = ddlIdBase + 9;
1839
1840 // -- Bit index in Word
1841 Int_t bitIdx = ddlId % 32;
1842
1843 // -- Index of word
1844 Int_t wordIdx = wordBase;
1845
1846 // -- if TPC (3) or TOD (5) add word idx
1847 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1848 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1849 }
1850
1851 // -- Set -- 'OR' word with bit mask;
1852 if ( state )
1853 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1854 // -- Unset -- 'AND' word with bit mask;
1855 else
1856 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1857}
1858
1859Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1860{
1861 // see header file for function documentation
1862
1863 Int_t iResult = -1;
1864
1865 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1866
1867 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1868 // check for special cases TPC and TOF
1869 if ( wordNdx > 3 && wordNdx <= 10 ) {
1870 wordNdx = 10;
1871 iResult = 3;
1872 }
1873 else if ( wordNdx > 12 && wordNdx <= 14 ) {
1874 wordNdx = 14;
1875 iResult = 12;
1876 }
1877 else
1878 iResult = wordNdx;
1879 }
1880 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
1881 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
1882 iResult = -1;
1883 break;
1884 }
1885 }
1886
1887 return iResult;
1888}
48abe484 1889
1890AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
1891{
1892 // see header file for function documentation
1893 AliHLTUInt32_t remainder = 0;
1894 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
1895 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
1896 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
1897
1898 // code from
1899 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
1900
1901 /*
1902 * Perform modulo-2 division, a byte at a time.
1903 */
1904 for (int byte = 0; byte < size; ++byte)
1905 {
1906 /*
1907 * Bring the next byte into the remainder.
1908 */
1909 remainder ^= (buffer[byte] << (crcwidth - 8));
1910
1911 /*
1912 * Perform modulo-2 division, a bit at a time.
1913 */
1914 for (uint8_t bit = 8; bit > 0; --bit)
1915 {
1916 /*
1917 * Try to divide the current data bit.
1918 */
1919 if (remainder & topbit)
1920 {
1921 remainder = (remainder << 1) ^ polynomial;
1922 }
1923 else
1924 {
1925 remainder = (remainder << 1);
1926 }
1927 }
1928 }
1929
1930 /*
1931 * The final remainder is the CRC result.
1932 */
1933 return (remainder);
1934}
abb52c8f 1935
1936int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
1937 string& retChainId, string& retCompId, string& retCompArgs,
1938 vector<AliHLTUInt32_t>& parents)
1939{
1940 // see header file for function documentation
1941 retChainId.clear();
1942 retCompId.clear();
1943 retCompArgs.clear();
1944 parents.clear();
1945 if (!pBuffer || size==0) return 0;
1946
1947 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
1948 if (size<8/* the initial size of the structure*/ ||
1949 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
1950 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
1951 const AliHLTUInt8_t* pEnd=pBuffer+size;
1952
1953 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
1954 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
1955 parents.push_back(*pParents);
1956 }
1957
1958 const char* pDescription=reinterpret_cast<const char*>(pParents);
1959 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
1960 *(pDescription+pEntry->fSizeDescription)!=0) {
1961 return -EBADF;
1962 }
1963
1964 TString descriptor=reinterpret_cast<const char*>(pDescription);
1965 TString chainId;
1966 TString compId;
1967 TString compArgs;
1968 TObjArray* pTokens=descriptor.Tokenize("{");
1969 if (pTokens) {
1970 int n=0;
1971 if (pTokens->GetEntries()>n) {
1972 retChainId=((TObjString*)pTokens->At(n++))->GetString();
1973 }
1974 if (pTokens->GetEntries()>n) {
1975 compId=((TObjString*)pTokens->At(n++))->GetString();
1976 }
1977 delete pTokens;
1978 }
1979 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
1980 int n=0;
1981 if (pTokens->GetEntries()>n) {
1982 compId=((TObjString*)pTokens->At(n++))->GetString();
1983 }
1984 if (pTokens->GetEntries()>n) {
1985 compArgs=((TObjString*)pTokens->At(n++))->GetString();
1986 }
1987 delete pTokens;
1988 }
1989 compId.ReplaceAll("}", "");
1990 compArgs.ReplaceAll("}", "");
1991
1992 retCompId=compId;
1993 retCompArgs=compArgs;
1994
1995 if (retChainId.size()==0) return -ENODATA;
1996
1997 return 1;
1998}