]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponent.cxx
added default constructor needed for AliEn plugin (Markus)
[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
0007ed52 20// @file AliHLTComponent.cxx
21// @author Matthias Richter, Timm Steinbeck
22// @date
23// @brief Base class implementation for HLT components. */
24// @note The class is both used in Online (PubSub) and Offline (AliRoot)
25// context
26
f23a6e1a 27
0c0c9d99 28#if __GNUC__>= 3
f23a6e1a 29using namespace std;
30#endif
31
66043029 32//#include "AliHLTStdIncludes.h"
f23a6e1a 33#include "AliHLTComponent.h"
34#include "AliHLTComponentHandler.h"
a655eae3 35#include "AliHLTMessage.h"
adb91bc3 36#include "AliHLTCTPData.h"
70ed7d01 37#include "TString.h"
ed504011 38#include "TMath.h"
a655eae3 39#include "TObjArray.h"
79c114b5 40#include "TObjectTable.h"
a655eae3 41#include "TClass.h"
90ebac25 42#include "TStopwatch.h"
cf9cf07e 43#include "TFormula.h"
79c114b5 44#include "AliHLTMemoryFile.h"
579d9eb7 45#include "AliHLTMisc.h"
ec25e4ca 46#include <cassert>
bee8f777 47#include <ctime>
0da432fa 48#include <stdint.h>
f23a6e1a 49
9ace7282 50/**
51 * default compression level for ROOT objects
52 */
53#define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
2e3fd14f 54#define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
9ace7282 55
b22e91eb 56/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 57ClassImp(AliHLTComponent);
58
59/** stopwatch macro using the stopwatch guard */
60#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
61//#define ALIHLTCOMPONENT_STOPWATCH(type)
62
63/** stopwatch macro for operations of the base class */
64#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
65/** stopwatch macro for operations of the detector algorithm (DA) */
66#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 67
f23a6e1a 68AliHLTComponent::AliHLTComponent()
85869391 69 :
53feaef5 70 fEnvironment(),
3cde846d 71 fCurrentEvent(0),
a655eae3 72 fEventCount(-1),
73 fFailedEvents(0),
74 fCurrentEventData(),
75 fpInputBlocks(NULL),
76 fCurrentInputBlock(-1),
77 fSearchDataType(kAliHLTVoidDataType),
78 fClassName(),
79 fpInputObjects(NULL),
80 fpOutputBuffer(NULL),
81 fOutputBufferSize(0),
82 fOutputBufferFilled(0),
90ebac25 83 fOutputBlocks(),
79c114b5 84 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 85 fMemFiles(),
86 fpRunDesc(NULL),
579d9eb7 87 fpDDLList(NULL),
82c58a87 88 fCDBSetRunNoFunc(false),
a0aeb701 89 fChainId(),
48abe484 90 fChainIdCrc(0),
a0aeb701 91 fpBenchmark(NULL),
78d29060 92 fFlags(0),
abb52c8f 93 fEventType(gkAliEventTypeUnknown),
eafbc306 94 fComponentArgs(),
95 fEventDoneData(NULL),
9ace7282 96 fEventDoneDataSize(0),
97 fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION)
b3f4766b 98 , fLastObjectSize(0)
adb91bc3 99 , fpCTPData(NULL)
9d4d4b02 100 , fPushbackPeriod(0)
101 , fLastPushBackTime(-1)
70ed7d01 102{
103 // see header file for class documentation
104 // or
105 // refer to README to build package
106 // or
107 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
a3c9b745 108 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
70ed7d01 109 if (fgpComponentHandler)
110 fgpComponentHandler->ScheduleRegister(this);
7c781d33 111 //SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 112}
113
f23a6e1a 114AliHLTComponent::~AliHLTComponent()
115{
70ed7d01 116 // see header file for function documentation
a0aeb701 117 if (fpBenchmark) delete fpBenchmark;
118 fpBenchmark=NULL;
119
8451168b 120 CleanupInputObjects();
4498d7d1 121 if (fpStopwatches!=NULL) delete fpStopwatches;
122 fpStopwatches=NULL;
2be3f004 123 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 124 while (element!=fMemFiles.end()) {
125 if (*element) {
126 if ((*element)->IsClosed()==0) {
127 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
128 // close but do not flush as we dont know whether the buffer is still valid
29312178 129 (*element)->CloseMemoryFile(0);
79c114b5 130 }
131 delete *element;
132 *element=NULL;
133 }
134 element++;
135 }
45c0a780 136 if (fpRunDesc) {
137 delete fpRunDesc;
138 fpRunDesc=NULL;
139 }
eafbc306 140 if (fEventDoneData)
141 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
cf9cf07e 142 fEventDoneData=NULL;
143
adb91bc3 144 if (fpCTPData) {
145 delete fpCTPData;
cf9cf07e 146 }
adb91bc3 147 fpCTPData=NULL;
f23a6e1a 148}
149
70ed7d01 150AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 151
85869391 152int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
153{
70ed7d01 154 // see header file for function documentation
85869391 155 int iResult=0;
70ed7d01 156 if (fgpComponentHandler==NULL || bOverwrite!=0)
157 fgpComponentHandler=pCH;
85869391 158 else
159 iResult=-EPERM;
160 return iResult;
161}
162
70ed7d01 163int AliHLTComponent::UnsetGlobalComponentHandler()
164{
165 // see header file for function documentation
85869391 166 return SetGlobalComponentHandler(NULL,1);
167}
168
c528fdc6 169int AliHLTComponent::SetComponentEnvironment(const AliHLTAnalysisEnvironment* comenv, void* environParam)
f23a6e1a 170{
70ed7d01 171 // see header file for function documentation
66108417 172 HLTLogKeyword(fChainId.c_str());
f23a6e1a 173 int iResult=0;
f7561f8d 174 if (comenv) {
a3c9b745 175 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
176 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
177 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
70ed7d01 178 fEnvironment.fParam=environParam;
f23a6e1a 179 }
c528fdc6 180 return iResult;
181}
182
183int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
184{
185 // see header file for function documentation
186 HLTLogKeyword(fChainId.c_str());
187 int iResult=0;
188 if (comenv) {
189 SetComponentEnvironment(comenv, environParam);
190 }
9d4d4b02 191 fPushbackPeriod=0;
192 fLastPushBackTime=-1;
193
abb52c8f 194 fComponentArgs="";
8451168b 195 const char** pArguments=NULL;
196 int iNofChildArgs=0;
197 TString argument="";
198 int bMissingParam=0;
199 if (argc>0) {
200 pArguments=new const char*[argc];
201 if (pArguments) {
202 for (int i=0; i<argc && iResult>=0; i++) {
abb52c8f 203 if (fComponentArgs.size()>0) fComponentArgs+=" ";
204 fComponentArgs+=argv[i];
8451168b 205 argument=argv[i];
206 if (argument.IsNull()) continue;
207
208 // benchmark
66108417 209 if (argument.CompareTo("-benchmark")==0) {
8451168b 210
66108417 211 // -loglevel=
212 } else if (argument.BeginsWith("-loglevel=")) {
213 TString parameter=argument.ReplaceAll("-loglevel=", "");
8451168b 214 parameter.Remove(TString::kLeading, ' '); // remove all blanks
215 if (parameter.BeginsWith("0x") &&
216 parameter.Replace(0,2,"",0).IsHex()) {
bd6cac58 217 unsigned int loglevel=kHLTLogNone;
218 sscanf(parameter.Data(),"%x", &loglevel);
219 SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
8451168b 220 } else {
221 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
222 iResult=-EINVAL;
223 }
9ace7282 224 // -object-compression=
225 } else if (argument.BeginsWith("-object-compression=")) {
226 argument.ReplaceAll("-object-compression=", "");
227 if (argument.IsDigit()) {
228 fCompressionLevel=argument.Atoi();
229 if (fCompressionLevel<0 || fCompressionLevel>9) {
230 HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION);
231 fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION;
232 }
233 } else {
234 HLTError("wrong parameter for argument -object-compression, number expected");
235 }
9d4d4b02 236 // -pushback-period=
237 } else if (argument.BeginsWith("-pushback-period=")) {
238 argument.ReplaceAll("-pushback-period=", "");
239 if (argument.IsDigit()) {
240 fPushbackPeriod=argument.Atoi();
241 } else {
242 HLTError("wrong parameter for argument -pushback-period, number expected");
243 }
78d29060 244 // -disable-component-stat
245 } else if (argument.CompareTo("-disable-component-stat")==0) {
246 fFlags|=kDisableComponentStat;
8451168b 247 } else {
248 pArguments[iNofChildArgs++]=argv[i];
249 }
250 }
251 } else {
252 iResult=-ENOMEM;
253 }
254 }
255 if (bMissingParam) {
256 HLTError("missing parameter for argument %s", argument.Data());
257 iResult=-EINVAL;
258 }
5ef2a37b 259 if (iResult>=0) {
260 iResult=CheckOCDBEntries();
261 }
8451168b 262 if (iResult>=0) {
263 iResult=DoInit(iNofChildArgs, pArguments);
264 }
a0aeb701 265 if (iResult>=0) {
266 fEventCount=0;
267
268 // find out if the component wants to get the steering events
269 // explicitly
270 AliHLTComponentDataTypeList inputDt;
271 GetInputDataTypes(inputDt);
78d29060 272 bool bRequireSteeringBlocks=false;
a0aeb701 273 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
78d29060 274 dt!=inputDt.end() && !bRequireSteeringBlocks;
a0aeb701 275 dt++) {
78d29060 276 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
277 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
278 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
279 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
280 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
a0aeb701 281 }
78d29060 282 if (bRequireSteeringBlocks) fFlags|=kRequireSteeringBlocks;
a0aeb701 283 }
8451168b 284 if (pArguments) delete [] pArguments;
a0aeb701 285
78d29060 286#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 287 // benchmarking stopwatch for the component statistics
288 fpBenchmark=new TStopwatch;
78d29060 289#endif // HLT_COMPONENT_STATISTICS
a0aeb701 290
f23a6e1a 291 return iResult;
292}
293
294int AliHLTComponent::Deinit()
295{
70ed7d01 296 // see header file for function documentation
66108417 297 HLTLogKeyword(fChainId.c_str());
f23a6e1a 298 int iResult=0;
299 iResult=DoDeinit();
559631d5 300 if (fpRunDesc) {
cf9cf07e 301 // TODO: the warning should be kept, but the condition is wrong since the
302 // AliHLTRunDesc is set before the SOR event in the SetRunDescription
303 // method. A couple of state flags should be defined but that is a bit more
304 // work to do. For the moment disable the warning (2009-07-01)
bee8f777 305 // 2009-09-08: now, the info is not cleared in the ProcessEvent, because it
306 // might be needed by components during the event processing.
cf9cf07e 307 //HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
559631d5 308 AliHLTRunDesc* pRunDesc=fpRunDesc;
309 fpRunDesc=NULL;
310 delete pRunDesc;
311 }
adb91bc3 312 if (fpCTPData) {
313 delete fpCTPData;
cf9cf07e 314 }
adb91bc3 315 fpCTPData=NULL;
cf9cf07e 316
579d9eb7 317 fEventCount=0;
78d29060 318 fFlags=0;
f23a6e1a 319 return iResult;
320}
fa2e9b7c 321
82c58a87 322int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
53feaef5 323{
82c58a87 324 // see header file for function documentation
579d9eb7 325 int iResult=0;
c528fdc6 326 HLTInfo("Using CDB: %s", cdbPath);
703bcca6 327 if (pHandler) {
82c58a87 328 // I have to think about separating the library handling from the
c528fdc6 329 // component handler. Requiring the component handler here is not
82c58a87 330 // the cleanest solution.
c528fdc6 331 // We presume the library already to be loaded, which is the case
332 // because it is loaded in the initialization of the logging functionality
333 //
579d9eb7 334 // find the symbol
82c58a87 335 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
579d9eb7 336 if (pFunc) {
703bcca6 337 TString path;
338 if (cdbPath && cdbPath[0]!=0) {
339 path=cdbPath;
340 // very temporary fix, have to check for other formats
341 if (!path.BeginsWith("local://")) {
342 path="local://";
343 path+=cdbPath;
344 }
8f30c1ea 345 }
346 if ((iResult=(*pFunc)(path.Data()))>=0) {
82c58a87 347 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
348 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
349 "can not find function to set CDB run no");
350 }
351 }
579d9eb7 352 } else {
353 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
354 "can not find initialization function");
355 iResult=-ENOSYS;
53feaef5 356 }
82c58a87 357 } else {
358 iResult=-EINVAL;
359 }
579d9eb7 360 return iResult;
361}
362
363int AliHLTComponent::SetCDBRunNo(int runNo)
364{
82c58a87 365 // see header file for function documentation
366 if (!fCDBSetRunNoFunc) return 0;
367 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
579d9eb7 368}
369
45c0a780 370int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
371{
372 // see header file for function documentation
373 if (!desc) return -EINVAL;
374 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
375 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
376 return -EINVAL;
377 }
378
379 if (!fpRunDesc) {
380 fpRunDesc=new AliHLTRunDesc;
381 if (!fpRunDesc) return -ENOMEM;
382 *fpRunDesc=kAliHLTVoidRunDesc;
383 }
384
385 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
386 HLTWarning("Run description has already been set");
387 }
388 *fpRunDesc=*desc;
389 SetCDBRunNo(fpRunDesc->fRunNo);
390 // TODO: we have to decide about the runType
391 return 0;
392}
393
9a0ef890 394int AliHLTComponent::SetComponentDescription(const char* desc)
395{
48abe484 396 // see header file for function documentation
9a0ef890 397 int iResult=0;
398 if (!desc) return 0;
399
400 TString descriptor=desc;
401 TObjArray* pTokens=descriptor.Tokenize(" ");
402 if (pTokens) {
77fd699f 403 for (int i=0; i<pTokens->GetEntriesFast() && iResult>=0; i++) {
9a0ef890 404 TString argument=((TObjString*)pTokens->At(i++))->GetString();
405 if (!argument || argument.IsNull()) continue;
406
a3c9b745 407 // chainid
408 if (argument.BeginsWith("chainid")) {
409 argument.ReplaceAll("chainid", "");
9a0ef890 410 if (argument.BeginsWith("=")) {
411 fChainId=argument.Replace(0,1,"");
48abe484 412 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
413 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
9a0ef890 414 } else {
415 fChainId="";
416 }
417 } else {
48abe484 418 HLTWarning("unknown component description %s", argument.Data());
9a0ef890 419 }
420 }
b09d01b5 421 delete pTokens;
9a0ef890 422 }
423
424 return iResult;
425}
426
02bc7a5f 427int AliHLTComponent::ConfigureFromArgumentString(int argc, const char** argv)
428{
429 // see header file for function documentation
430 int iResult=0;
431 vector<const char*> array;
432 TObjArray choppedArguments;
433 TString argument="";
434 int i=0;
435 for (i=0; i<argc && iResult>=0; i++) {
436 argument=argv[i];
437 if (argument.IsNull()) continue;
438 TObjArray* pTokens=argument.Tokenize(" ");
439 if (pTokens) {
44869670 440 if (pTokens->GetEntriesFast()>0) {
02bc7a5f 441 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
442 choppedArguments.AddLast(pTokens->At(n));
44869670 443 TString data=((TObjString*)pTokens->At(n))->GetString();
444 if (!data.IsNull()) {
445 array.push_back(data.Data());
446 }
02bc7a5f 447 }
448 pTokens->SetOwner(kFALSE);
449 }
450 delete pTokens;
451 }
452 }
453
454 for (i=0; (unsigned)i<array.size() && iResult>=0;) {
455 int result=ScanConfigurationArgument(array.size()-i, &array[i]);
456 if (result==0) {
457 HLTWarning("unknown component argument %s", array[i]);
458 i++;
459 } else if (result>0) {
460 i+=result;
461 } else {
462 iResult=result;
463 if (iResult==-EINVAL) {
464 HLTError("unknown argument %s", array[i]);
465 } else if (iResult==-EPROTO) {
44869670 466 HLTError("missing/wrong parameter for argument %s (%s)", array[i], (array.size()>(unsigned)i+1)?array[i+1]:"missing");
02bc7a5f 467 } else {
468 HLTError("scan of argument %s failed (%d)", array[i], iResult);
469 }
470 }
471 }
472
473 return iResult;
474}
475
476int AliHLTComponent::ConfigureFromCDBTObjString(const char* entries)
477{
478 // see header file for function documentation
479 int iResult=0;
480 TString arguments;
481 TString confEntries=entries;
482 TObjArray* pTokens=confEntries.Tokenize(" ");
483 if (pTokens) {
484 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
485 const char* path=((TObjString*)pTokens->At(n))->GetString().Data();
486 const char* chainId=GetChainId();
487 HLTInfo("configure from entry %s, chain id %s", path, (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
488 TObject* pOCDBObject = LoadAndExtractOCDBObject(path);
489 if (pOCDBObject) {
490 TObjString* pString=dynamic_cast<TObjString*>(pOCDBObject);
491 if (pString) {
492 HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
493 arguments+=pString->GetString().Data();
494 arguments+=" ";
495 } else {
496 HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
497 iResult=-EINVAL;
498 }
499 } else {
500 HLTError("can not fetch object \"%s\" from OCDB", path);
501 iResult=-ENOENT;
502 }
503 }
504 delete pTokens;
505 }
506 if (iResult>=0 && !arguments.IsNull()) {
507 const char* array=arguments.Data();
508 iResult=ConfigureFromArgumentString(1, &array);
509 }
510 return iResult;
511}
512
513TObject* AliHLTComponent::LoadAndExtractOCDBObject(const char* path, int version, int subVersion)
514{
515 // see header file for function documentation
516 AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(path, GetRunNo(), version, subVersion);
517 if (!pEntry) return NULL;
518 return AliHLTMisc::Instance().ExtractObject(pEntry);
519}
520
579d9eb7 521int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
522{
523 // default implementation, childs can overload
b543e186 524 HLTLogKeyword("dummy");
53feaef5 525 return 0;
526}
527
528int AliHLTComponent::DoDeinit()
529{
579d9eb7 530 // default implementation, childs can overload
b543e186 531 HLTLogKeyword("dummy");
579d9eb7 532 return 0;
533}
534
535int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
536{
537 // default implementation, childs can overload
b543e186 538 HLTLogKeyword("dummy");
539 return 0;
540}
541
542int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
543{
544 // default implementation, childs can overload
545 HLTLogKeyword("dummy");
53feaef5 546 return 0;
547}
548
02bc7a5f 549int AliHLTComponent::ScanConfigurationArgument(int /*argc*/, const char** /*argv*/)
550{
551 // default implementation, childs can overload
552 HLTLogKeyword("dummy");
553 HLTWarning("The function needs to be implemented by the component");
554 return 0;
555}
556
45c0a780 557int AliHLTComponent::StartOfRun()
558{
559 // default implementation, childs can overload
560 HLTLogKeyword("dummy");
561 return 0;
562}
563
564int AliHLTComponent::EndOfRun()
565{
566 // default implementation, childs can overload
567 HLTLogKeyword("dummy");
568 return 0;
569}
570
571
2be3f004 572int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
de6593d0 573{
82c58a87 574 // default implementation, childs can overload
3a7c0444 575 HLTLogKeyword("dummy");
de6593d0 576 return 0;
577}
578
5ef2a37b 579void AliHLTComponent::GetOCDBObjectDescription( TMap* const /*targetArray*/)
580{
581 // default implementation, childs can overload
582 HLTLogKeyword("dummy");
583}
584
585int AliHLTComponent::CheckOCDBEntries(const TMap* const externList)
586{
587 // check the availability of the OCDB entry descriptions in the TMap
588 // key : complete OCDB path of the entry
589 // value : auxiliary object - short description
590 // if the external map was not provided the function invokes
591 // interface function GetOCDBObjectDescription() to retrieve the list.
592 int iResult=0;
593 if (externList) {
594 iResult=AliHLTMisc::Instance().CheckOCDBEntries(externList);
595 } else {
596 TMap* pMap=new TMap;
597 if (pMap) {
598 pMap->SetOwnerKeyValue(kTRUE);
599 GetOCDBObjectDescription(pMap);
600 iResult=AliHLTMisc::Instance().CheckOCDBEntries(pMap);
601 delete pMap;
602 pMap=NULL;
603 }
604 }
605
606 return iResult;
607}
608
70ed7d01 609void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
610{
611 // see header file for function documentation
9ce4bf4a 612 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
613 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
614 strcat( output, ":" );
615 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 616}
617
fbdb63fd 618string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
9ce4bf4a 619{
70ed7d01 620 // see header file for function documentation
9ce4bf4a 621 string out("");
fbdb63fd 622
623 if (mode==2) {
624 int i=0;
625 char tmp[8];
626 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
627 sprintf(tmp, "'%d", type.fOrigin[i]);
628 out+=tmp;
629 }
630 out+="':'";
631 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
632 sprintf(tmp, "%d'", type.fID[i]);
633 out+=tmp;
634 }
635 return out;
636 }
637
638 if (mode==1) {
639 int i=0;
640 char tmp[8];
641 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
642 unsigned char* puc=(unsigned char*)type.fOrigin;
643 if ((puc[i])<32)
644 sprintf(tmp, "'\\%x", type.fOrigin[i]);
645 else
646 sprintf(tmp, "'%c", type.fOrigin[i]);
647 out+=tmp;
648 }
649 out+="':'";
650 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
651 unsigned char* puc=(unsigned char*)type.fID;
652 if (puc[i]<32)
653 sprintf(tmp, "\\%x'", type.fID[i]);
654 else
655 sprintf(tmp, "%c'", type.fID[i]);
656 out+=tmp;
657 }
658 return out;
659 }
660
9ce4bf4a 661 if (type==kAliHLTVoidDataType) {
662 out="VOID:VOID";
663 } else {
3cde846d 664 // some gymnastics in order to avoid a '0' which is part of either or both
665 // ID and origin terminating the whole string. Unfortunately, string doesn't
666 // stop appending at the '0' if the number of elements to append was
667 // explicitely specified
668 string tmp("");
669 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
670 out.append(tmp.c_str());
9ce4bf4a 671 out.append(":");
3cde846d 672 tmp="";
673 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
674 out.append(tmp.c_str());
9ce4bf4a 675 }
676 return out;
677}
678
679
70ed7d01 680void* AliHLTComponent::AllocMemory( unsigned long size )
681{
682 // see header file for function documentation
85869391 683 if (fEnvironment.fAllocMemoryFunc)
684 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 685 HLTFatal("no memory allocation handler registered");
85869391 686 return NULL;
687}
688
2be3f004 689int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 690 AliHLTComponentBlockData** outputBlocks )
691{
692 // see header file for function documentation
9ce4bf4a 693 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 694 return -EFAULT;
fa2e9b7c 695 AliHLTUInt32_t count = blocks.size();
696 if ( !count )
697 {
698 *blockCount = 0;
699 *outputBlocks = NULL;
700 return 0;
701 }
8ede8717 702 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 703 if ( !*outputBlocks )
2d7ff710 704 return -ENOMEM;
ca8524df 705 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 706 (*outputBlocks)[i] = blocks[i];
732e8f50 707 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
5f5b708b 708 (*outputBlocks)[i].fDataType=GetOutputDataType();
709 /* data type was set to the output data type by the PubSub AliRoot
710 Wrapper component, if data type of the block was ********:****.
711 Now handled by the component base class in order to have same
712 behavior when running embedded in AliRoot
ca8524df 713 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
714 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 715 */
ca8524df 716 }
717 }
fa2e9b7c 718 *blockCount = count;
719 return 0;
720
721}
0c0c9d99 722
0007ed52 723int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) const
70ed7d01 724{
725 // see header file for function documentation
85869391 726 if (fEnvironment.fGetEventDoneDataFunc)
727 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
728 return -ENOSYS;
729}
730
eafbc306 731int AliHLTComponent::ReserveEventDoneData( unsigned long size )
732{
733 // see header file for function documentation
734 int iResult=0;
735
6f4231a1 736 unsigned long capacity=fEventDoneDataSize;
737 if (fEventDoneData) capacity-=sizeof(AliHLTComponentEventDoneData)+fEventDoneData->fDataSize;
738 if (size>capacity) {
739 unsigned long newSize=sizeof(AliHLTComponentEventDoneData)+size+(fEventDoneDataSize-capacity);
740 AliHLTComponentEventDoneData* newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[newSize] );
eafbc306 741 if (!newEDD)
742 return -ENOMEM;
743 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
744 newEDD->fDataSize = 0;
745 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
746 if (fEventDoneData) {
747 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
748 newEDD->fDataSize = fEventDoneData->fDataSize;
749 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
750 }
751 fEventDoneData = newEDD;
6f4231a1 752 fEventDoneDataSize = newSize;
eafbc306 753 }
754 return iResult;
755
756}
757
758int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord )
759{
0007ed52 760 // see header file for function documentation
eafbc306 761 if (!fEventDoneData)
762 return -ENOMEM;
763 if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize)
764 return -ENOSPC;
765 *reinterpret_cast<AliHLTUInt32_t*>((reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord;
766 fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t);
767 return 0;
768}
769
770void AliHLTComponent::ReleaseEventDoneData()
771{
0007ed52 772 // see header file for function documentation
773 if (fEventDoneData)
eafbc306 774 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
775 fEventDoneData = NULL;
776 fEventDoneDataSize = 0;
777}
778
779
2be3f004 780int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
0c0c9d99 781{
70ed7d01 782 // see header file for function documentation
0c0c9d99 783 int iResult=0;
784 if (pConsumer) {
8a106878 785 AliHLTComponentDataTypeList itypes;
786 AliHLTComponentDataTypeList otypes;
787 otypes.push_back(GetOutputDataType());
c57201be 788 if (MatchExactly(otypes[0],kAliHLTMultipleDataType)) {
8a106878 789 otypes.clear();
790 int count=0;
791 if ((count=GetOutputDataTypes(otypes))>0) {
792 } else if (GetComponentType()!=kSink) {
793 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
794 }
795 }
0007ed52 796 pConsumer->GetInputDataTypes(itypes);
48abe484 797 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
798 for (;otype!=otypes.end();otype++) {
799 //PrintDataTypeContent((*otype), "publisher \'%s\'");
800 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
801 if (tgtList) tgtList->push_back(*otype);
802 iResult++;
803 continue;
804 }
805
806 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
32f88fc5 807 for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */};
48abe484 808 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
809 if (itype!=itypes.end()) {
810 if (tgtList) tgtList->push_back(*otype);
0c0c9d99 811 iResult++;
0c0c9d99 812 }
0c0c9d99 813 }
814 } else {
815 iResult=-EINVAL;
816 }
817 return iResult;
818}
2d7ff710 819
8b97f4f1 820void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
5f5b708b 821{
66043029 822 // see header file for function documentation
8b97f4f1 823 const char* fmt="\'%s\'";
5f5b708b 824 if (format) fmt=format;
8b97f4f1 825 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
826 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
827 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
828 dt.fID[0],
829 dt.fID[1],
830 dt.fID[2],
831 dt.fID[3],
832 dt.fID[4],
833 dt.fID[5],
834 dt.fID[6],
835 dt.fID[7],
836 dt.fOrigin[0],
837 dt.fOrigin[1],
838 dt.fOrigin[2],
839 dt.fOrigin[3]));
5f5b708b 840}
841
fbdb63fd 842void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
70ed7d01 843{
844 // see header file for function documentation
2d7ff710 845 blockData.fStructSize = sizeof(blockData);
846 FillShmData( blockData.fShmKey );
847 blockData.fOffset = ~(AliHLTUInt32_t)0;
848 blockData.fPtr = NULL;
849 blockData.fSize = 0;
850 FillDataType( blockData.fDataType );
a655eae3 851 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 852}
853
fbdb63fd 854void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
70ed7d01 855{
856 // see header file for function documentation
2d7ff710 857 shmData.fStructSize = sizeof(shmData);
858 shmData.fShmType = gkAliHLTComponentInvalidShmType;
859 shmData.fShmID = gkAliHLTComponentInvalidShmID;
860}
861
fbdb63fd 862void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
70ed7d01 863{
864 // see header file for function documentation
ca8524df 865 dataType=kAliHLTAnyDataType;
2d7ff710 866}
867
70ed7d01 868void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
869{
870 // see header file for function documentation
2d7ff710 871 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
872 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
873}
874
70ed7d01 875void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
876{
877 // see header file for function documentation
7e3efc8f 878 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
879 if (id) {
880 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
d76bc02a 881 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
7e3efc8f 882 }
883 if (origin) {
884 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
d76bc02a 885 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
7e3efc8f 886 }
2d7ff710 887}
9ce4bf4a 888
18b56222 889void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
890{
891 // see header file for function documentation
892 dt.fStructSize=sizeof(AliHLTComponentDataType);
893 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
894 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
895 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
896 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
897}
898
9ce4bf4a 899void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
900{
70ed7d01 901 // see header file for function documentation
9ce4bf4a 902 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
903 evtData.fStructSize=sizeof(AliHLTComponentEventData);
48abe484 904 evtData.fEventID=kAliHLTVoidEventID;
9ce4bf4a 905}
906
70ed7d01 907void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
908{
909 // see header file for function documentation
9ce4bf4a 910 TString msg;
911 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
912 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
913 if (dt.fID[i]!=0) msg+=dt.fID[i];
914 else msg+="\\0";
915 }
916 msg+="\" Origin=\"";
917 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
918 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
919 else msg+="\\0";
920 }
921 msg+="\"";
3cde846d 922 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 923}
924
70ed7d01 925int AliHLTComponent::GetEventCount() const
3cde846d 926{
70ed7d01 927 // see header file for function documentation
3cde846d 928 return fEventCount;
929}
930
931int AliHLTComponent::IncrementEventCounter()
932{
70ed7d01 933 // see header file for function documentation
3cde846d 934 if (fEventCount>=0) fEventCount++;
935 return fEventCount;
936}
937
66043029 938int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 939{
940 // see header file for function documentation
941 if (fpInputBlocks!=NULL) {
942 return fCurrentEventData.fBlockCnt;
943 }
944 return 0;
945}
946
4646c6e3 947AliHLTEventID_t AliHLTComponent::GetEventId() const
948{
949 // see header file for function documentation
950 if (fpInputBlocks!=NULL) {
951 return fCurrentEventData.fEventID;
952 }
953 return 0;
954}
955
a655eae3 956const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
957 const char* classname,
958 int bForce)
959{
960 // see header file for function documentation
90ebac25 961 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 962 fSearchDataType=dt;
963 if (classname) fClassName=classname;
964 else fClassName.clear();
1edbbe49 965 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 966 TObject* pObj=NULL;
967 if (idx>=0) {
79c114b5 968 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 969 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
970 fCurrentInputBlock=idx;
971 } else {
972 }
973 }
974 return pObj;
975}
976
977const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
978 const char* dtOrigin,
979 const char* classname,
980 int bForce)
981{
982 // see header file for function documentation
90ebac25 983 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 984 AliHLTComponentDataType dt;
985 SetDataType(dt, dtID, dtOrigin);
986 return GetFirstInputObject(dt, classname, bForce);
987}
988
989const TObject* AliHLTComponent::GetNextInputObject(int bForce)
990{
991 // see header file for function documentation
90ebac25 992 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 993 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 994 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
995 TObject* pObj=NULL;
996 if (idx>=0) {
997 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
998 fCurrentInputBlock=idx;
999 }
1000 }
1001 return pObj;
1002}
1003
1edbbe49 1004int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 1005{
1006 // see header file for function documentation
1007 int iResult=-ENOENT;
1008 if (fpInputBlocks!=NULL) {
1009 int idx=startIdx<0?0:startIdx;
4b98eadb 1010 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 1011 if (dt!=fpInputBlocks[idx].fDataType) continue;
1012
1edbbe49 1013 if (bObject!=0) {
1014 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 1015 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
1016 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 1017 }
3dd8541e 1018 iResult=idx;
a655eae3 1019 }
1020 }
1021 return iResult;
1022}
1023
1024TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
1025{
1026 // see header file for function documentation
1027 TObject* pObj=NULL;
1028 if (fpInputBlocks!=NULL) {
4b98eadb 1029 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1030 if (fpInputBlocks[idx].fPtr) {
3294f81a 1031 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 1032 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 1033 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 1034 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 1035 TClass* objclass=msg.GetClass();
1036 pObj=msg.ReadObject(objclass);
1037 if (pObj && objclass) {
1038 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 1039 } else {
1040 }
1edbbe49 1041 //} else {
1042 } else if (bForce!=0) {
c5123824 1043 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 1044 }
1045 } else {
1046 HLTFatal("block descriptor empty");
1047 }
1048 } else {
1049 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
1050 }
1051 } else {
1052 HLTError("no input blocks available");
1053 }
1054
1055 return pObj;
1056}
1057
298ef463 1058TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 1059{
1060 // see header file for function documentation
1061 if (fpInputObjects==NULL) {
1062 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
1063 }
1064 TObject* pObj=NULL;
1065 if (fpInputObjects) {
1066 pObj=fpInputObjects->At(idx);
1067 if (pObj==NULL) {
1068 pObj=CreateInputObject(idx, bForce);
1069 if (pObj) {
1070 fpInputObjects->AddAt(pObj, idx);
1071 }
1072 }
1073 } else {
1074 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
1075 }
1076 return pObj;
1077}
1078
8451168b 1079int AliHLTComponent::CleanupInputObjects()
1080{
66043029 1081 // see header file for function documentation
8451168b 1082 if (!fpInputObjects) return 0;
1083 TObjArray* array=fpInputObjects;
1084 fpInputObjects=NULL;
3ecb06e2 1085 for (int i=0; i<array->GetEntriesFast(); i++) {
8451168b 1086 TObject* pObj=array->At(i);
79c114b5 1087 // grrr, garbage collection strikes back: When read via AliHLTMessage
1088 // (CreateInputObject), and written to a TFile afterwards, the
1089 // TFile::Close calls ROOOT's garbage collection. No clue why the
1090 // object ended up in the key list and needs to be deleted
a6c7a8bc 1091 //
1092 // Matthias 09.11.2008 follow up
1093 // This approach doesn't actually work in all cases: the object table
1094 // can be switched off globally, the flag needs to be checked here as
1095 // well in order to avoid memory leaks.
1096 // This means we have to find another solution for the problem if it
1097 // pops up again.
1098 if (pObj &&
1099 (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) {
1100 delete pObj;
1101 }
8451168b 1102 }
1103 delete array;
90ebac25 1104 return 0;
8451168b 1105}
1106
a655eae3 1107AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
1108{
1109 // see header file for function documentation
90ebac25 1110 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1111 AliHLTComponentDataType dt=kAliHLTVoidDataType;
1112 int idx=fCurrentInputBlock;
1113 if (pObject) {
1114 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1115 } else {
1116 HLTError("unknown object %p", pObject);
1117 }
1118 }
1119 if (idx>=0) {
4b98eadb 1120 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1121 dt=fpInputBlocks[idx].fDataType;
1122 } else {
1123 HLTFatal("severe internal error, index out of range");
1124 }
1125 }
1126 return dt;
1127}
1128
1129AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
1130{
1131 // see header file for function documentation
90ebac25 1132 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1133 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1134 int idx=fCurrentInputBlock;
1135 if (pObject) {
1136 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1137 } else {
1138 HLTError("unknown object %p", pObject);
1139 }
1140 }
1141 if (idx>=0) {
4b98eadb 1142 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1143 iSpec=fpInputBlocks[idx].fSpecification;
1144 } else {
1145 HLTFatal("severe internal error, index out of range");
1146 }
1147 }
1148 return iSpec;
1149}
1150
c7e9e2f2 1151int AliHLTComponent::Forward(const TObject* pObject)
1152{
1153 // see header file for function documentation
1154 int iResult=0;
1155 int idx=fCurrentInputBlock;
1156 if (pObject) {
1157 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1158 } else {
1159 HLTError("unknown object %p", pObject);
1160 iResult=-ENOENT;
1161 }
1162 }
1163 if (idx>=0) {
1164 fOutputBlocks.push_back(fpInputBlocks[idx]);
1165 }
1166 return iResult;
1167}
1168
1169int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
1170{
1171 // see header file for function documentation
1172 int iResult=0;
1173 int idx=fCurrentInputBlock;
1174 if (pBlock) {
1175 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1176 } else {
1177 HLTError("unknown Block %p", pBlock);
1178 iResult=-ENOENT;
1179 }
1180 }
1181 if (idx>=0) {
1182 // check for fpInputBlocks pointer done in FindInputBlock
1183 fOutputBlocks.push_back(fpInputBlocks[idx]);
1184 }
1185 return iResult;
1186}
1187
a655eae3 1188const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
1189{
1190 // see header file for function documentation
90ebac25 1191 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1192 fSearchDataType=dt;
1193 fClassName.clear();
1194 int idx=FindInputBlock(fSearchDataType, 0);
1195 const AliHLTComponentBlockData* pBlock=NULL;
1196 if (idx>=0) {
1197 // check for fpInputBlocks pointer done in FindInputBlock
1198 pBlock=&fpInputBlocks[idx];
1edbbe49 1199 fCurrentInputBlock=idx;
a655eae3 1200 }
1201 return pBlock;
1202}
1203
1204const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1205 const char* dtOrigin)
1206{
1207 // see header file for function documentation
90ebac25 1208 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1209 AliHLTComponentDataType dt;
1210 SetDataType(dt, dtID, dtOrigin);
1211 return GetFirstInputBlock(dt);
1212}
1213
10b9cbf9 1214const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 1215{
1216 // see header file for function documentation
1217 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 1218 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 1219 return &fpInputBlocks[index];
1220}
1221
a655eae3 1222const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1223{
1224 // see header file for function documentation
90ebac25 1225 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1226 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1227 const AliHLTComponentBlockData* pBlock=NULL;
1228 if (idx>=0) {
1229 // check for fpInputBlocks pointer done in FindInputBlock
1230 pBlock=&fpInputBlocks[idx];
1edbbe49 1231 fCurrentInputBlock=idx;
a655eae3 1232 }
1233 return pBlock;
1234}
1235
66043029 1236int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 1237{
1238 // see header file for function documentation
1239 int iResult=-ENOENT;
1240 if (fpInputBlocks!=NULL) {
1241 if (pBlock) {
1242 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 1243 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 1244 }
1245 } else {
1246 iResult=-EINVAL;
1247 }
1248 }
1249 return iResult;
1250}
1251
1252AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1253{
1254 // see header file for function documentation
90ebac25 1255 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1256 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1257 int idx=fCurrentInputBlock;
1258 if (pBlock) {
1259 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1260 } else {
1261 HLTError("unknown Block %p", pBlock);
1262 }
1263 }
1264 if (idx>=0) {
1265 // check for fpInputBlocks pointer done in FindInputBlock
1266 iSpec=fpInputBlocks[idx].fSpecification;
1267 }
1268 return iSpec;
1269}
1270
79c114b5 1271int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1272 void* pHeader, int headerSize)
a655eae3 1273{
1274 // see header file for function documentation
90ebac25 1275 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1276 int iResult=0;
b3f4766b 1277 fLastObjectSize=0;
9d4d4b02 1278 if (fPushbackPeriod>0) {
1279 // suppress the output
1280 TDatime time;
1281 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime<fPushbackPeriod) return 0;
1282 }
a655eae3 1283 if (pObject) {
1284 AliHLTMessage msg(kMESS_OBJECT);
9ace7282 1285 msg.SetCompressionLevel(fCompressionLevel);
a655eae3 1286 msg.WriteObject(pObject);
1287 Int_t iMsgLength=msg.Length();
1288 if (iMsgLength>0) {
9ace7282 1289 // Matthias Sep 2008
1290 // NOTE: AliHLTMessage does implement it's own SetLength method
1291 // which is not architecture independent. The original SetLength
1292 // stores the size always in network byte order.
1293 // I'm trying to remember the rational for that, might be that
1294 // it was just some lack of knowledge. Want to change this, but
1295 // has to be done carefullt to be backward compatible.
a655eae3 1296 msg.SetLength(); // sets the length to the first (reserved) word
9ace7282 1297
1298 // does nothing if the level is 0
1299 msg.Compress();
1300
1301 char *mbuf = msg.Buffer();
1302 if (msg.CompBuffer()) {
1303 msg.SetLength(); // set once more to have to byte order
1304 mbuf = msg.CompBuffer();
1305 iMsgLength = msg.CompLength();
1306 }
1307 assert(mbuf!=NULL);
1308 iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 1309 if (iResult>=0) {
9ace7282 1310 HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
a655eae3 1311 }
b3f4766b 1312 fLastObjectSize=iMsgLength;
a655eae3 1313 } else {
1314 HLTError("object serialization failed for object %p", pObject);
1315 iResult=-ENOMSG;
1316 }
1317 } else {
1318 iResult=-EINVAL;
1319 }
1320 return iResult;
1321}
1322
79c114b5 1323int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1324 void* pHeader, int headerSize)
a655eae3 1325{
1326 // see header file for function documentation
90ebac25 1327 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1328 AliHLTComponentDataType dt;
1329 SetDataType(dt, dtID, dtOrigin);
79c114b5 1330 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1331}
1332
438635e3 1333int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1334 const void* pHeader, int headerSize)
a655eae3 1335{
1336 // see header file for function documentation
90ebac25 1337 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d4d4b02 1338 if (fPushbackPeriod>0) {
1339 // suppress the output
1340 TDatime time;
1341 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime<fPushbackPeriod) return 0;
1342 }
1343
9d9ffd37 1344 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1345}
1346
438635e3 1347int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1348 const void* pHeader, int headerSize)
a655eae3 1349{
1350 // see header file for function documentation
90ebac25 1351 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1352 AliHLTComponentDataType dt;
1353 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1354 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1355}
1356
438635e3 1357int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1358 const void* pHeader, int iHeaderSize)
a655eae3 1359{
1360 // see header file for function documentation
1361 int iResult=0;
79c114b5 1362 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1363
1364 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1365 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1366 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1367
1368 // copy header if provided but skip if the header is the target location
1369 // in that case it has already been copied
79c114b5 1370 if (pHeader!=NULL && pHeader!=pTgt) {
1371 memcpy(pTgt, pHeader, iHeaderSize);
1372 }
1373
1374 pTgt += (AliHLTUInt8_t) iHeaderSize;
1375
438635e3 1376 // copy buffer if provided but skip if buffer is the target location
1377 // in that case it has already been copied
a655eae3 1378 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1379 memcpy(pTgt, pBuffer, iBufferSize);
1380
4b98eadb 1381 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1382 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1383 }
79c114b5 1384 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1385 } else {
1386 if (fpOutputBuffer) {
b3f4766b 1387 HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize);
a655eae3 1388 } else {
1389 HLTError("output buffer not available");
1390 }
1391 iResult=-ENOSPC;
1392 }
a655eae3 1393 }
438635e3 1394 if (iResult>=0) {
1395 AliHLTComponentBlockData bd;
1396 FillBlockData( bd );
1397 bd.fOffset = fOutputBufferFilled;
1398 bd.fSize = iBlkSize;
1399 bd.fDataType = dt;
1400 bd.fSpecification = spec;
1401 fOutputBlocks.push_back( bd );
1402 fOutputBufferFilled+=bd.fSize;
1403 }
1404
a655eae3 1405 return iResult;
1406}
1407
8451168b 1408int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1409{
66043029 1410 // see header file for function documentation
8451168b 1411 if (!pObject) return -EINVAL;
1412 AliHLTMessage msg(kMESS_OBJECT);
1413 msg.WriteObject(pObject);
1414 return msg.Length();
1415}
1416
79c114b5 1417AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1418 const char* dtOrigin,
1419 AliHLTUInt32_t spec)
1420{
1421 // see header file for function documentation
1422 ALIHLTCOMPONENT_BASE_STOPWATCH();
1423 AliHLTComponentDataType dt;
1424 SetDataType(dt, dtID, dtOrigin);
1425 return CreateMemoryFile(capacity, dt, spec);
1426}
1427
1428AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1429 const AliHLTComponentDataType& dt,
1430 AliHLTUInt32_t spec)
1431{
1432 // see header file for function documentation
1433 ALIHLTCOMPONENT_BASE_STOPWATCH();
1434 AliHLTMemoryFile* pFile=NULL;
83fec083 1435 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1436 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1437 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1438 if (pFile) {
83fec083 1439 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1440 if (nofBlocks+1>fMemFiles.size()) {
1441 fMemFiles.resize(nofBlocks+1, NULL);
1442 }
1443 if (nofBlocks<fMemFiles.size()) {
1444 fMemFiles[nofBlocks]=pFile;
1445 AliHLTComponentBlockData bd;
1446 FillBlockData( bd );
1447 bd.fOffset = fOutputBufferFilled;
79c114b5 1448 bd.fSize = capacity;
1449 bd.fDataType = dt;
1450 bd.fSpecification = spec;
1451 fOutputBufferFilled+=bd.fSize;
1452 fOutputBlocks.push_back( bd );
1453 } else {
1454 HLTError("can not allocate/grow object array");
29312178 1455 pFile->CloseMemoryFile(0);
79c114b5 1456 delete pFile;
1457 pFile=NULL;
1458 }
1459 }
1460 } else {
1461 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1462 }
1463 return pFile;
1464}
1465
1466AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1467 const char* dtOrigin,
1468 AliHLTUInt32_t spec,
1469 float capacity)
1470{
1471 // see header file for function documentation
1472 ALIHLTCOMPONENT_BASE_STOPWATCH();
1473 AliHLTComponentDataType dt;
1474 SetDataType(dt, dtID, dtOrigin);
1475 int size=fOutputBufferSize-fOutputBufferFilled;
1476 if (capacity<0 || capacity>1.0) {
1477 HLTError("invalid parameter: capacity %f", capacity);
1478 return NULL;
1479 }
1480 size=(int)(size*capacity);
1481 return CreateMemoryFile(size, dt, spec);
1482}
1483
1484AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1485 AliHLTUInt32_t spec,
1486 float capacity)
1487{
1488 // see header file for function documentation
1489 ALIHLTCOMPONENT_BASE_STOPWATCH();
1490 int size=fOutputBufferSize-fOutputBufferFilled;
1491 if (capacity<0 || capacity>1.0) {
1492 HLTError("invalid parameter: capacity %f", capacity);
1493 return NULL;
1494 }
1495 size=(int)(size*capacity);
1496 return CreateMemoryFile(size, dt, spec);
1497}
1498
1499int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1500 const char* key, int option)
1501{
3a7c0444 1502 // see header file for function documentation
79c114b5 1503 int iResult=0;
1504 if (pFile && pObject) {
1505 pFile->cd();
1506 iResult=pObject->Write(key, option);
1507 if (iResult>0) {
1508 // success
1509 } else {
1510 iResult=-pFile->GetErrno();
1511 if (iResult==-ENOSPC) {
1512 HLTError("error writing memory file, buffer too small");
1513 }
1514 }
1515 } else {
1516 iResult=-EINVAL;
1517 }
1518 return iResult;
1519}
1520
1521int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1522{
3a7c0444 1523 // see header file for function documentation
79c114b5 1524 int iResult=0;
1525 if (pFile) {
2be3f004 1526 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1527 int i=0;
1528 while (element!=fMemFiles.end() && iResult>=0) {
1529 if (*element && *element==pFile) {
29312178 1530 iResult=pFile->CloseMemoryFile();
79c114b5 1531
1532 // sync memory files and descriptors
1533 if (iResult>=0) {
1534 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1535 }
1536 delete *element;
1537 *element=NULL;
1538 return iResult;
1539 }
1540 element++; i++;
1541 }
1542 HLTError("can not find memory file %p", pFile);
1543 iResult=-ENOENT;
1544 } else {
1545 iResult=-EINVAL;
1546 }
1547 return iResult;
1548}
1549
eafbc306 1550int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
a655eae3 1551{
1552 // see header file for function documentation
eafbc306 1553 int iResult=0;
1554
1555 AliHLTComponentEventDoneData* newEDD = NULL;
1556
1557 unsigned long newSize=edd.fDataSize;
1558 if (fEventDoneData)
1559 newSize += fEventDoneData->fDataSize;
1560
1561 if (newSize>fEventDoneDataSize) {
1562 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1563 if (!newEDD)
1564 return -ENOMEM;
1565 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1566 newEDD->fDataSize = newSize;
1567 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1568 unsigned long long offset = 0;
1569 if (fEventDoneData) {
1570 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1571 offset += fEventDoneData->fDataSize;
1572 }
1573 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1574 if (fEventDoneData)
1575 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1576 fEventDoneData = newEDD;
1577 fEventDoneDataSize = newSize;
1578 }
1579 else {
1580 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1581 fEventDoneData->fDataSize += edd.fDataSize;
1582 }
a655eae3 1583 return iResult;
1584}
1585
3cde846d 1586int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1587 const AliHLTComponentBlockData* blocks,
1588 AliHLTComponentTriggerData& trigData,
1589 AliHLTUInt8_t* outputPtr,
1590 AliHLTUInt32_t& size,
1591 AliHLTUInt32_t& outputBlockCnt,
1592 AliHLTComponentBlockData*& outputBlocks,
1593 AliHLTComponentEventDoneData*& edd )
1594{
70ed7d01 1595 // see header file for function documentation
66108417 1596 HLTLogKeyword(fChainId.c_str());
90ebac25 1597 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1598 int iResult=0;
1599 fCurrentEvent=evtData.fEventID;
a655eae3 1600 fCurrentEventData=evtData;
1601 fpInputBlocks=blocks;
1602 fCurrentInputBlock=-1;
1603 fSearchDataType=kAliHLTAnyDataType;
1604 fpOutputBuffer=outputPtr;
1605 fOutputBufferSize=size;
1606 fOutputBufferFilled=0;
1607 fOutputBlocks.clear();
96f9673a 1608 outputBlockCnt=0;
1609 outputBlocks=NULL;
438635e3 1610
1611 AliHLTComponentBlockDataList forwardedBlocks;
1612
1613 // optional component statistics
a0aeb701 1614 AliHLTComponentStatisticsList compStats;
438635e3 1615 bool bAddComponentTableEntry=false;
abb52c8f 1616 vector<AliHLTUInt32_t> parentComponentTables;
78d29060 1617#if defined(HLT_COMPONENT_STATISTICS)
1618 if ((fFlags&kDisableComponentStat)==0) {
1619 AliHLTComponentStatistics outputStat;
1620 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1621 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1622 outputStat.fId=fChainIdCrc;
1623 if (fpBenchmark) {
1624 fpBenchmark->Stop();
1625 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1626 fpBenchmark->Reset();
1627 fpBenchmark->Start();
1628 }
1629 compStats.push_back(outputStat);
a0aeb701 1630 }
78d29060 1631#endif // HLT_COMPONENT_STATISTICS
559631d5 1632
48abe484 1633 // data processing is skipped
1634 // - if there are only steering events in the block list.
1635 // For the sake of data source components data processing
1636 // is not skipped if there is no block list at all or if it
1637 // just contains the eventType block
1638 // - always skipped if the event is of type
1639 // - gkAliEventTypeConfiguration
1640 // - gkAliEventTypeReadPreprocessor
45c0a780 1641 const unsigned int skipModeDefault=0x1;
1642 const unsigned int skipModeForce=0x2;
1643 unsigned int bSkipDataProcessing=skipModeDefault;
1644
559631d5 1645 // find special events
45c0a780 1646 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1647 // first look for all special events and execute in the appropriate
1648 // sequence afterwords
1649 int indexComConfEvent=-1;
b543e186 1650 int indexUpdtDCSEvent=-1;
579d9eb7 1651 int indexSOREvent=-1;
1652 int indexEOREvent=-1;
cf9cf07e 1653 int indexECSParamBlock=-1;
83fec083 1654 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1655 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1656 indexSOREvent=i;
45c0a780 1657 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1658 bSkipDataProcessing&=~skipModeDefault;
1659 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1660 // run type string
1661 // handling is not clear yet
1662 if (fpInputBlocks[i].fPtr) {
1663 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1664 }
579d9eb7 1665 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1666 indexEOREvent=i;
45c0a780 1667 // the calibration processor relies on the SOR and EOR events
1668 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1669 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1670 // DDL list
1671 // this event is most likely deprecated
1672 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1673 indexComConfEvent=i;
b543e186 1674 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1675 indexUpdtDCSEvent=i;
1676 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1677 fEventType=fpInputBlocks[i].fSpecification;
1678
1679 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1680 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1681
1682 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1683 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1684
1685 // never skip if the event type block is the only block
1686 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1687
a0aeb701 1688 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1689 if (compStats.size()>0) {
1690 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1691 for (AliHLTUInt32_t offset=0;
1692 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1693 offset+=sizeof(AliHLTComponentStatistics)) {
1694 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1695 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1696 compStats[0].fLevel=pStat->fLevel+1;
1697 }
1698 compStats.push_back(*pStat);
1699 }
1700 }
438635e3 1701 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1702 forwardedBlocks.push_back(fpInputBlocks[i]);
abb52c8f 1703 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
cf9cf07e 1704 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
1705 indexECSParamBlock=i;
45c0a780 1706 } else {
1707 // the processing function is called if there is at least one
1708 // non-steering data block. Steering blocks are not filtered out
1709 // for sake of performance
1710 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1711 if (compStats.size()>0) {
1712 compStats[0].fInputBlockCount++;
1713 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1714 }
579d9eb7 1715 }
1716 }
45c0a780 1717
579d9eb7 1718 if (indexSOREvent>=0) {
1719 // start of run
438635e3 1720 bAddComponentTableEntry=true;
579d9eb7 1721 if (fpRunDesc==NULL) {
1722 fpRunDesc=new AliHLTRunDesc;
48abe484 1723 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1724 }
1725 if (fpRunDesc) {
1726 AliHLTRunDesc rundesc;
1727 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1728 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1729 *fpRunDesc=rundesc;
579d9eb7 1730 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1731 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1732 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1733 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1734 }
559631d5 1735 }
579d9eb7 1736 } else {
45c0a780 1737 iResult=-ENOMEM;
579d9eb7 1738 }
cf9cf07e 1739
1740 if (indexECSParamBlock>=0) {
1741 if (fpInputBlocks[indexECSParamBlock].fSize>0) {
1742 const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
1743 TString paramString;
1744 if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
1745 HLTWarning("ECS parameter string not terminated");
1746 paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
1747 paramString+="";
1748 } else {
1749 paramString=param;
1750 }
1751 ScanECSParam(paramString.Data());
1752 } else {
1753 HLTWarning("empty ECS parameter received");
1754 }
1755 } else {
1756 // TODO: later on we might throw a warning here since the CTP trigger classes
1757 // should be mandatory
1758 }
579d9eb7 1759 }
1760 if (indexEOREvent>=0) {
9d4d4b02 1761 fLastPushBackTime=0; // always send at EOR
438635e3 1762 bAddComponentTableEntry=true;
579d9eb7 1763 if (fpRunDesc!=NULL) {
1764 if (fpRunDesc) {
1765 AliHLTRunDesc rundesc;
1766 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1767 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1768 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1769 } else {
1770 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1771 }
559631d5 1772 }
bee8f777 1773 // we do not unload the fpRunDesc struct here in order to have the run information
1774 // available during the event processing
1775 // https://savannah.cern.ch/bugs/?39711
1776 // the info will be cleared in DeInit
559631d5 1777 }
579d9eb7 1778 } else {
1779 HLTWarning("did not receive SOR, ignoring EOR");
1780 }
1781 }
48abe484 1782 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1783 TString cdbEntry;
b543e186 1784 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1785 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1786 }
1787 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1788 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1789 if (tmpResult<0) {
1790 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1791 }
1792 }
48abe484 1793 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1794 TString modules;
1795 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1796 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1797 }
d6b69874 1798 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1799 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1800 if (tmpResult<0) {
1801 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1802 }
1803 }
45c0a780 1804 } else {
1805 // processing function needs to be called if there are no input data
1806 // blocks in order to make data source components working.
1807 bSkipDataProcessing&=~skipModeDefault;
559631d5 1808 }
a0aeb701 1809
1810 // data processing is not skipped if the component explicitly asks
1811 // for the private blocks
78d29060 1812 if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
a0aeb701 1813
edd72347 1814 if (fpCTPData) {
1815 // set the active triggers for this event
1816 fpCTPData->SetTriggers(trigData);
1817 // increment CTP trigger counters if available
1818 if (IsDataEvent()) fpCTPData->Increment(trigData);
1819 }
adb91bc3 1820
2be3f004 1821 AliHLTComponentBlockDataList blockData;
45c0a780 1822 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1823 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1824 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1825 // in order to avoid 'shadowed variable' warning
1826 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1827 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1828 } // end of the scope of the stopwatch guard
b543e186 1829 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1830 if (fOutputBlocks.size()>0) {
df61f928 1831 // High Level interface
1832
1833 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1834 // sync memory files and descriptors
2be3f004 1835 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1836 int i=0;
1837 while (element!=fMemFiles.end() && iResult>=0) {
1838 if (*element) {
1839 if ((*element)->IsClosed()==0) {
1840 HLTWarning("memory file has not been closed, force flush");
1841 iResult=CloseMemoryFile(*element);
1842 }
1843 }
1844 element++; i++;
1845 }
1846
1847 if (iResult>=0) {
1848 // create the descriptor list
1849 if (blockData.size()>0) {
1850 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1851 iResult=-EFAULT;
1852 } else {
abb52c8f 1853 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 1854 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1855 if (offset>0) fOutputBufferFilled+=offset;
1856 }
438635e3 1857 if (bAddComponentTableEntry) {
abb52c8f 1858 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
438635e3 1859 if (offset>0) size+=offset;
1860 }
1861 if (forwardedBlocks.size()>0) {
1862 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1863 }
79c114b5 1864 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1865 size=fOutputBufferFilled;
1866 }
a655eae3 1867 }
1868 } else {
df61f928 1869 // Low Level interface
a0aeb701 1870 if (compStats.size()>0) {
1871 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1872 if (offset>0) size+=offset;
1873 }
438635e3 1874 if (bAddComponentTableEntry) {
abb52c8f 1875 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
438635e3 1876 if (offset>0) size+=offset;
1877 }
1878 if (forwardedBlocks.size()>0) {
1879 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1880 }
a655eae3 1881 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1882 }
1883 if (iResult<0) {
1884 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1885 }
1886 }
b543e186 1887 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1888 outputBlockCnt=0;
1889 outputBlocks=NULL;
1890 }
8451168b 1891 CleanupInputObjects();
48abe484 1892 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1893 IncrementEventCounter();
1894 }
96f9673a 1895 if (outputBlockCnt==0) {
1896 // no output blocks, set size to 0
1897 size=0;
1898 }
6f4231a1 1899
1900 // reset the internal EventData struct
4646c6e3 1901 FillEventData(fCurrentEventData);
edd72347 1902
1903 // reset the active triggers
1904 if (fpCTPData) fpCTPData->SetTriggers(0);
9d4d4b02 1905
1906 // set the time for the pushback period
1907 if (fPushbackPeriod>0) {
1908 // suppress the output
1909 TDatime time;
1910 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime>=fPushbackPeriod) {
1911 fLastPushBackTime=time.Get();
1912 }
1913 }
1914
3cde846d 1915 return iResult;
1916}
a655eae3 1917
a0aeb701 1918int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1919 AliHLTUInt8_t* buffer,
1920 AliHLTUInt32_t bufferSize,
1921 AliHLTUInt32_t offset,
1922 AliHLTComponentStatisticsList& stats) const
1923{
1924 // see header file for function documentation
1925 int iResult=0;
78d29060 1926 if ((fFlags&kDisableComponentStat)!=0) return 0;
1927#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 1928 if (stats.size()==0) return -ENOENT;
ae962989 1929 // check if there is space for at least one entry
1930 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
a0aeb701 1931 stats[0].fTotalOutputSize=offset;
1932 stats[0].fOutputBlockCount=blocks.size();
1933 if (fpBenchmark) {
2e3fd14f 1934 fpBenchmark->Stop();
1935 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1936 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1937 fpBenchmark->Continue();
a0aeb701 1938 }
ae962989 1939 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
1940 AliHLTUInt32_t removedLevel=0;
1941 do {
1942 // remove all entries of the level of the last entry
1943 removedLevel=stats.back().fLevel;
1944 AliHLTComponentStatisticsList::iterator element=stats.begin();
1945 element++;
1946 while (element!=stats.end()) {
1947 if (element->fLevel<=removedLevel) {
1948 element=stats.erase(element);
1949 } else {
1950 element++;
1951 }
1952 }
1953 } while (stats.size()>1 &&
1954 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
1955 }
1956 assert(stats.size()>0);
1957 if (stats.size()==0) return 0;
1958
a0aeb701 1959 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1960 AliHLTComponentBlockData bd;
1961 FillBlockData( bd );
1962 bd.fOffset = offset;
1963 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1964 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1965 bd.fSpecification = kAliHLTVoidDataSpec;
1966 unsigned int master=0;
1967 for (unsigned int i=1; i<blocks.size(); i++) {
1968 if (blocks[i].fSize>blocks[master].fSize &&
1969 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1970 master=i;
1971 }
1972 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1973 // take the data origin of the biggest block as specification
1974 // this is similar to the treatment in the HOMER interface. For traditional
1975 // reasons, the bytes are swapped there on a little endian architecture, so
1976 // we do it as well.
1977 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1978#ifdef R__BYTESWAP // set on little endian architectures
1979 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1980 ((bd.fSpecification & 0xFF00ULL) << 8) |
1981 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1982 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1983#endif
1984 }
1985 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1986 blocks.push_back(bd);
1987 iResult=bd.fSize;
1988 }
bd6cac58 1989#else
1990 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
1991 // get rid of warning
1992 }
78d29060 1993#endif // HLT_COMPONENT_STATISTICS
438635e3 1994 return iResult;
1995}
1996
1997int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1998 AliHLTUInt8_t* buffer,
1999 AliHLTUInt32_t bufferSize,
abb52c8f 2000 AliHLTUInt32_t offset,
2001 const vector<AliHLTUInt32_t>& parents) const
438635e3 2002{
2003 // see header file for function documentation
2004 int iResult=0;
78d29060 2005 if ((fFlags&kDisableComponentStat)!=0) return 0;
2006#if defined(HLT_COMPONENT_STATISTICS)
abb52c8f 2007 // the payload consists of the AliHLTComponentTableEntry struct,
2008 // followed by a an array of 32bit crc chain ids and the component
2009 // description string
2010 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2011 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2012
2013 // the component description has the following format:
2014 // chain-id{component-id:arguments}
2015 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2016 unsigned int descriptionSize=fChainId.size()+1;
2017 descriptionSize+=2; // the '{}' around the component id
2018 descriptionSize+=strlen(componentId);
2019 descriptionSize+=1; // the ':' between component id and arguments
2020 descriptionSize+=fComponentArgs.size();
2021
2022 payloadSize+=descriptionSize;
2023 if (buffer && (offset+payloadSize<=bufferSize)) {
2024 AliHLTUInt8_t* pTgt=buffer+offset;
2025 memset(pTgt, 0, payloadSize);
2026
2027 // write entry
2028 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2029 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
2030 pEntry->fNofParents=parents.size();
2031 pEntry->fSizeDescription=descriptionSize;
2032 pTgt=pEntry->fBuffer;
2033
2034 // write array of parents
2035 if (parents.size()>0) {
2036 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2037 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2038 pTgt+=copy;
2039 }
2040
2041 // write component description
2042 memcpy(pTgt, fChainId.c_str(), fChainId.size());
2043 pTgt+=fChainId.size();
2044 *pTgt++='{';
2045 memcpy(pTgt, componentId, strlen(componentId));
2046 pTgt+=strlen(componentId);
2047 *pTgt++=':';
2048 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2049 pTgt+=fComponentArgs.size();
2050 *pTgt++='}';
2051 *pTgt++=0;
2052
438635e3 2053 AliHLTComponentBlockData bd;
2054 FillBlockData( bd );
2055 bd.fOffset = offset;
abb52c8f 2056 bd.fSize = payloadSize;
438635e3 2057 bd.fDataType = kAliHLTDataTypeComponentTable;
2058 bd.fSpecification = fChainIdCrc;
438635e3 2059 blocks.push_back(bd);
2060 iResult=bd.fSize;
2061 }
bd6cac58 2062#else
2063 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
2064 // get rid of warning
2065 }
78d29060 2066#endif // HLT_COMPONENT_STATISTICS
a0aeb701 2067 return iResult;
2068}
2069
90ebac25 2070AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2071 :
2072 fpStopwatch(NULL),
2073 fpPrec(NULL)
2074{
2075 // standard constructor (not for use)
2076}
2077
2078AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2079 :
2080 fpStopwatch(pStopwatch),
2081 fpPrec(NULL)
2082{
2083 // constructor
2084
2085 // check for already existing guard
2086 if (fgpCurrent) fpPrec=fgpCurrent;
2087 fgpCurrent=this;
2088
2089 // stop the preceeding guard if it controls a different stopwatch
2090 int bStart=1;
2091 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2092
2093 // start the stopwatch if the current guard controls a different one
2094 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2095}
2096
e419b223 2097AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 2098 :
2099 fpStopwatch(NULL),
2100 fpPrec(NULL)
2101{
e419b223 2102 //
2103 // copy constructor not for use
2104 //
2105}
2106
2107AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
2108{
2109 //
2110 // assignment operator not for use
2111 //
2112 fpStopwatch=NULL;
2113 fpPrec=NULL;
2114 return *this;
90ebac25 2115}
2116
2117AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2118
2119AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2120{
2121 // destructor
2122
2123 // resume the preceeding guard if it controls a different stopwatch
2124 int bStop=1;
2125 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2126
2127 // stop the stopwatch if the current guard controls a different one
2128 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2129
2130 // resume to the preceeding guard
2131 fgpCurrent=fpPrec;
2132}
2133
0007ed52 2134int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
90ebac25 2135{
2136 // see header file for function documentation
2137 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2138 return fpStopwatch!=pSucc?1:0;
2139}
2140
0007ed52 2141int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
90ebac25 2142{
2143 // see header file for function documentation
2144 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2145 return fpStopwatch!=pSucc?1:0;
2146}
2147
2148int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2149{
2150 // see header file for function documentation
2151 int iResult=0;
2152 if (pSW!=NULL && type<kSWTypeCount) {
2153 if (fpStopwatches) {
2154 TObject* pObj=fpStopwatches->At((int)type);
2155 if (pSW==NULL // explicit reset
2156 || pObj==NULL) { // explicit set
2157 fpStopwatches->AddAt(pSW, (int)type);
2158 } else if (pObj!=pSW) {
2159 HLTWarning("stopwatch %d already set, reset first", (int)type);
2160 iResult=-EBUSY;
2161 }
2162 }
2163 } else {
2164 iResult=-EINVAL;
2165 }
2166 return iResult;
2167}
2168
2169int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2170{
2171 // see header file for function documentation
2172 if (pStopwatches==NULL) return -EINVAL;
2173
2174 int iResult=0;
77fd699f 2175 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
90ebac25 2176 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2177 return iResult;
2178}
559631d5 2179
2180AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2181{
29312178 2182 // see header file for function documentation
6e289790 2183
2184 // 2010-02-11 OCDB is now the reliable source for the run number, it is
2185 // initialized either by aliroot or the external interface depending
2186 // on the environment. It turned out that the rundescriptor is not set
2187 // in the aliroot mode, resulting in an invalid run number. However this
2188 // did not cause problems until now. OCDB initialization has been revised
2189 // already in 10/2009. This was a remnant.
2190 // Have to check whether we get rid of the rundescriptor at some point.
2191 if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2192 if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2193 HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2194 }
559631d5 2195 return fpRunDesc->fRunNo;
2196}
2197
2198AliHLTUInt32_t AliHLTComponent::GetRunType() const
2199{
29312178 2200 // see header file for function documentation
45c0a780 2201 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 2202 return fpRunDesc->fRunType;
2203}
2204
6700298e 2205AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2206{
2207 // see header file for function documentation
bee8f777 2208 if (fCurrentEventData.fEventCreation_s) {
2209 return fCurrentEventData.fEventCreation_s;
2210 }
2211 // using the actual UTC if the time stamp was not set by the framework
2212 return static_cast<AliHLTUInt32_t>(time(NULL));
6700298e 2213}
2214
2215AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2216{
2217 // see header file for function documentation
2218 return (GetEventId()>>36)&0xfffffff;
2219}
2220
2221AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2222{
2223 // see header file for function documentation
2224 return (GetEventId()>>12)&0xffffff;
2225}
2226
2227AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2228{
2229 // see header file for function documentation
2230 return GetEventId()&0xfff;
2231}
2232
0007ed52 2233bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
48abe484 2234{
2235 // see header file for function documentation
2236 if (pTgt) *pTgt=fEventType;
2237 return (fEventType==gkAliEventTypeData ||
2238 fEventType==gkAliEventTypeDataReplay ||
2239 fEventType==gkAliEventTypeCalibration);
2240}
2241
83fec083 2242int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 2243 const char* structname, const char* eventname)
2244{
29312178 2245 // see header file for function documentation
559631d5 2246 int iResult=0;
2247 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2248 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2249 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2250 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 2251 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 2252 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 2253 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 2254 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2255 }
2256 if (copy!=iStructSize) {
c5123824 2257 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 2258 if (copy>iStructSize) {
2259 copy=iStructSize;
2260 } else {
2261 memset(pTgt, 0, iStructSize);
2262 }
2263 }
3294f81a 2264 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 2265 *pTgt=iStructSize;
2266 iResult=copy;
2267 } else {
2268 HLTWarning("%s event: missing data block", eventname);
2269 }
2270 } else {
2271 iResult=-ENODATA;
2272 }
2273 } else {
2274 HLTError("invalid struct");
2275 iResult=-EINVAL;
2276 }
2277 return iResult;
2278}
ed504011 2279
2280void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
2281{
2282 // see header file for function documentation
2283
2284 // -- Detector offset
2285 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
2286
2287 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
2288 Int_t wordBase = 0;
2289
2290 if ( ddlIdBase <= 3 )
2291 wordBase = ddlIdBase;
2292 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
2293 wordBase = ddlIdBase + 7;
2294 else
2295 wordBase = ddlIdBase + 9;
2296
2297 // -- Bit index in Word
2298 Int_t bitIdx = ddlId % 32;
2299
2300 // -- Index of word
2301 Int_t wordIdx = wordBase;
2302
2303 // -- if TPC (3) or TOD (5) add word idx
2304 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
2305 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
2306 }
2307
2308 // -- Set -- 'OR' word with bit mask;
2309 if ( state )
2310 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
2311 // -- Unset -- 'AND' word with bit mask;
2312 else
2313 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
2314}
2315
2316Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
2317{
2318 // see header file for function documentation
2319
2320 Int_t iResult = -1;
2321
2322 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
2323
2324 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
2325 // check for special cases TPC and TOF
2326 if ( wordNdx > 3 && wordNdx <= 10 ) {
2327 wordNdx = 10;
2328 iResult = 3;
2329 }
2330 else if ( wordNdx > 12 && wordNdx <= 14 ) {
2331 wordNdx = 14;
2332 iResult = 12;
2333 }
2334 else
2335 iResult = wordNdx;
2336 }
2337 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
2338 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
2339 iResult = -1;
2340 break;
2341 }
2342 }
2343
2344 return iResult;
2345}
48abe484 2346
2347AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2348{
2349 // see header file for function documentation
2350 AliHLTUInt32_t remainder = 0;
2351 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2352 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2353 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2354
2355 // code from
2356 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2357
2358 /*
2359 * Perform modulo-2 division, a byte at a time.
2360 */
2361 for (int byte = 0; byte < size; ++byte)
2362 {
2363 /*
2364 * Bring the next byte into the remainder.
2365 */
2366 remainder ^= (buffer[byte] << (crcwidth - 8));
2367
2368 /*
2369 * Perform modulo-2 division, a bit at a time.
2370 */
2371 for (uint8_t bit = 8; bit > 0; --bit)
2372 {
2373 /*
2374 * Try to divide the current data bit.
2375 */
2376 if (remainder & topbit)
2377 {
2378 remainder = (remainder << 1) ^ polynomial;
2379 }
2380 else
2381 {
2382 remainder = (remainder << 1);
2383 }
2384 }
2385 }
2386
2387 /*
2388 * The final remainder is the CRC result.
2389 */
2390 return (remainder);
2391}
abb52c8f 2392
2393int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2394 string& retChainId, string& retCompId, string& retCompArgs,
2395 vector<AliHLTUInt32_t>& parents)
2396{
2397 // see header file for function documentation
2398 retChainId.clear();
2399 retCompId.clear();
2400 retCompArgs.clear();
2401 parents.clear();
2402 if (!pBuffer || size==0) return 0;
2403
2404 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2405 if (size<8/* the initial size of the structure*/ ||
2406 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2407 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2408 const AliHLTUInt8_t* pEnd=pBuffer+size;
2409
2410 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2411 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2412 parents.push_back(*pParents);
2413 }
2414
2415 const char* pDescription=reinterpret_cast<const char*>(pParents);
2416 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2417 *(pDescription+pEntry->fSizeDescription)!=0) {
2418 return -EBADF;
2419 }
2420
2421 TString descriptor=reinterpret_cast<const char*>(pDescription);
2422 TString chainId;
2423 TString compId;
2424 TString compArgs;
2425 TObjArray* pTokens=descriptor.Tokenize("{");
2426 if (pTokens) {
2427 int n=0;
77fd699f 2428 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2429 retChainId=((TObjString*)pTokens->At(n++))->GetString();
2430 }
77fd699f 2431 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2432 compId=((TObjString*)pTokens->At(n++))->GetString();
2433 }
2434 delete pTokens;
2435 }
2436 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2437 int n=0;
77fd699f 2438 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2439 compId=((TObjString*)pTokens->At(n++))->GetString();
2440 }
77fd699f 2441 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2442 compArgs=((TObjString*)pTokens->At(n++))->GetString();
2443 }
2444 delete pTokens;
2445 }
2446 compId.ReplaceAll("}", "");
2447 compArgs.ReplaceAll("}", "");
2448
2449 retCompId=compId;
2450 retCompArgs=compArgs;
2451
2452 if (retChainId.size()==0) return -ENODATA;
2453
2454 return 1;
2455}
97d2b87a 2456
2457int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2458 const char* originClass, const char* originFunc,
2459 const char* file, int line, ... ) const
2460{
2461 // see header file for function documentation
2462 int iResult=0;
2463
2464 va_list args;
2465 va_start(args, line);
2466
2467 // logging function needs to be const in order to be called from const member functions
2468 // without problems. But at this point we face the problem with virtual members which
2469 // are not necessarily const.
2470 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
7efb6418 2471 AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
97d2b87a 2472 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
7efb6418 2473 nonconst->GetComponentID());
97d2b87a 2474 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2475 va_end(args);
2476
2477 return iResult;
2478}
cf9cf07e 2479
2480int AliHLTComponent::ScanECSParam(const char* ecsParam)
2481{
2482 // see header file for function documentation
2483
2484 // format of the parameter string from ECS
2485 // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
2486 // search for a subset of the parameterkeys
c4ffab2c 2487 // RUN_TYPE=
2488 // RUN_NUMBER=
2489 // HLT_IN_DDL_LIST=
2490 // CTP_TRIGGER_CLASS=
2491 // DATA_FORMAT_VERSION=
2492 // BEAM_TYPE=
2493 // HLT_OUT_DDL_LIST=
2494 // HLT_TRIGGER_CODE=
2495 // DETECTOR_LIST=
2496 // HLT_MODE=
2497 // The command apears not to be sent by the online framework
cf9cf07e 2498 int iResult=0;
2499 TString string=ecsParam;
2500 TObjArray* parameter=string.Tokenize(";");
2501 if (parameter) {
77fd699f 2502 for (int i=0; i<parameter->GetEntriesFast(); i++) {
cf9cf07e 2503 TString entry=((TObjString*)parameter->At(i))->GetString();
2504 HLTDebug("scanning ECS entry: %s", entry.Data());
2505 TObjArray* entryParams=entry.Tokenize("=");
2506 if (entryParams) {
77fd699f 2507 if (entryParams->GetEntriesFast()>1) {
cf9cf07e 2508 if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
2509 int result=InitCTPTriggerClasses((((TObjString*)entryParams->At(1))->GetString()).Data());
2510 if (iResult>=0 && result<0) iResult=result;
2511 } else {
2512 // TODO: scan the other parameters
2513 // e.g. consistency check of run number
2514 }
2515 }
2516 delete entryParams;
2517 }
2518 }
2519 delete parameter;
2520 }
2521
2522 return iResult;
2523}
2524
adb91bc3 2525int AliHLTComponent::SetupCTPData()
cf9cf07e 2526{
2527 // see header file for function documentation
adb91bc3 2528 if (fpCTPData) delete fpCTPData;
2529 fpCTPData=new AliHLTCTPData;
2530 if (!fpCTPData) return -ENOMEM;
cf9cf07e 2531 return 0;
2532}
2533
adb91bc3 2534int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
cf9cf07e 2535{
2536 // see header file for function documentation
adb91bc3 2537 if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
2538 return fpCTPData->InitCTPTriggerClasses(ctpString);
2539}
cf9cf07e 2540
adb91bc3 2541bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
2542{
2543 // see header file for function documentation
2544 if (!fpCTPData) {
2545 static bool bWarningThrown=false;
2546 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2547 bWarningThrown=true;
cf9cf07e 2548 return false;
2549 }
2550
adb91bc3 2551 return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
cf9cf07e 2552}
a5e775ec 2553
3fcb48b8 2554int AliHLTComponent::CheckCTPTrigger(const char* name) const
2555{
2556 // see header file for function documentation
2557 if (!fpCTPData) {
2558 static bool bWarningThrown=false;
2559 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2560 bWarningThrown=true;
2561 return false;
2562 }
2563
2564 return fpCTPData->CheckTrigger(name);
2565}
2566
a5e775ec 2567Double_t AliHLTComponent::GetBz()
2568{
2569 // Returns Bz.
2570 return AliHLTMisc::Instance().GetBz();
2571}
2572
2573Double_t AliHLTComponent::GetBz(const Double_t *r)
2574{
2575 // Returns Bz (kG) at the point "r" .
2576 return AliHLTMisc::Instance().GetBz(r);
2577}
2578
2579void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
2580{
2581 // Returns Bx, By and Bz (kG) at the point "r" .
2582 AliHLTMisc::Instance().GetBxByBz(r, b);
2583}