Major update required to handle old and new AliHLTEventDDL structures within HLT...
[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"
89413559 37#include "AliRawDataHeader.h"
70ed7d01 38#include "TString.h"
ed504011 39#include "TMath.h"
a655eae3 40#include "TObjArray.h"
79c114b5 41#include "TObjectTable.h"
a655eae3 42#include "TClass.h"
90ebac25 43#include "TStopwatch.h"
cf9cf07e 44#include "TFormula.h"
79c114b5 45#include "AliHLTMemoryFile.h"
579d9eb7 46#include "AliHLTMisc.h"
ec25e4ca 47#include <cassert>
bee8f777 48#include <ctime>
0da432fa 49#include <stdint.h>
f23a6e1a 50
9ace7282 51/**
52 * default compression level for ROOT objects
53 */
54#define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
2e3fd14f 55#define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
9ace7282 56
b22e91eb 57/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 58ClassImp(AliHLTComponent);
59
60/** stopwatch macro using the stopwatch guard */
61#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
62//#define ALIHLTCOMPONENT_STOPWATCH(type)
63
64/** stopwatch macro for operations of the base class */
65#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
66/** stopwatch macro for operations of the detector algorithm (DA) */
67#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 68
f23a6e1a 69AliHLTComponent::AliHLTComponent()
85869391 70 :
53feaef5 71 fEnvironment(),
3cde846d 72 fCurrentEvent(0),
a655eae3 73 fEventCount(-1),
74 fFailedEvents(0),
75 fCurrentEventData(),
76 fpInputBlocks(NULL),
77 fCurrentInputBlock(-1),
78 fSearchDataType(kAliHLTVoidDataType),
79 fClassName(),
80 fpInputObjects(NULL),
81 fpOutputBuffer(NULL),
82 fOutputBufferSize(0),
83 fOutputBufferFilled(0),
90ebac25 84 fOutputBlocks(),
79c114b5 85 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 86 fMemFiles(),
87 fpRunDesc(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
cc63ef09 1411 if (!pObject) return 0;
1412
1413 AliHLTMessage msg(kMESS_OBJECT);
1414 msg.WriteObject(pObject);
1415 return msg.Length();
8451168b 1416}
1417
79c114b5 1418AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1419 const char* dtOrigin,
1420 AliHLTUInt32_t spec)
1421{
1422 // see header file for function documentation
1423 ALIHLTCOMPONENT_BASE_STOPWATCH();
1424 AliHLTComponentDataType dt;
1425 SetDataType(dt, dtID, dtOrigin);
1426 return CreateMemoryFile(capacity, dt, spec);
1427}
1428
1429AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1430 const AliHLTComponentDataType& dt,
1431 AliHLTUInt32_t spec)
1432{
1433 // see header file for function documentation
1434 ALIHLTCOMPONENT_BASE_STOPWATCH();
1435 AliHLTMemoryFile* pFile=NULL;
83fec083 1436 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1437 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1438 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1439 if (pFile) {
83fec083 1440 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1441 if (nofBlocks+1>fMemFiles.size()) {
1442 fMemFiles.resize(nofBlocks+1, NULL);
1443 }
1444 if (nofBlocks<fMemFiles.size()) {
1445 fMemFiles[nofBlocks]=pFile;
1446 AliHLTComponentBlockData bd;
1447 FillBlockData( bd );
1448 bd.fOffset = fOutputBufferFilled;
79c114b5 1449 bd.fSize = capacity;
1450 bd.fDataType = dt;
1451 bd.fSpecification = spec;
1452 fOutputBufferFilled+=bd.fSize;
1453 fOutputBlocks.push_back( bd );
1454 } else {
1455 HLTError("can not allocate/grow object array");
29312178 1456 pFile->CloseMemoryFile(0);
79c114b5 1457 delete pFile;
1458 pFile=NULL;
1459 }
1460 }
1461 } else {
1462 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1463 }
1464 return pFile;
1465}
1466
1467AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1468 const char* dtOrigin,
1469 AliHLTUInt32_t spec,
1470 float capacity)
1471{
1472 // see header file for function documentation
1473 ALIHLTCOMPONENT_BASE_STOPWATCH();
1474 AliHLTComponentDataType dt;
1475 SetDataType(dt, dtID, dtOrigin);
1476 int size=fOutputBufferSize-fOutputBufferFilled;
1477 if (capacity<0 || capacity>1.0) {
1478 HLTError("invalid parameter: capacity %f", capacity);
1479 return NULL;
1480 }
1481 size=(int)(size*capacity);
1482 return CreateMemoryFile(size, dt, spec);
1483}
1484
1485AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1486 AliHLTUInt32_t spec,
1487 float capacity)
1488{
1489 // see header file for function documentation
1490 ALIHLTCOMPONENT_BASE_STOPWATCH();
1491 int size=fOutputBufferSize-fOutputBufferFilled;
1492 if (capacity<0 || capacity>1.0) {
1493 HLTError("invalid parameter: capacity %f", capacity);
1494 return NULL;
1495 }
1496 size=(int)(size*capacity);
1497 return CreateMemoryFile(size, dt, spec);
1498}
1499
1500int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1501 const char* key, int option)
1502{
3a7c0444 1503 // see header file for function documentation
79c114b5 1504 int iResult=0;
1505 if (pFile && pObject) {
1506 pFile->cd();
1507 iResult=pObject->Write(key, option);
1508 if (iResult>0) {
1509 // success
1510 } else {
1511 iResult=-pFile->GetErrno();
1512 if (iResult==-ENOSPC) {
1513 HLTError("error writing memory file, buffer too small");
1514 }
1515 }
1516 } else {
1517 iResult=-EINVAL;
1518 }
1519 return iResult;
1520}
1521
1522int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1523{
3a7c0444 1524 // see header file for function documentation
79c114b5 1525 int iResult=0;
1526 if (pFile) {
2be3f004 1527 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1528 int i=0;
1529 while (element!=fMemFiles.end() && iResult>=0) {
1530 if (*element && *element==pFile) {
29312178 1531 iResult=pFile->CloseMemoryFile();
79c114b5 1532
1533 // sync memory files and descriptors
1534 if (iResult>=0) {
1535 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1536 }
1537 delete *element;
1538 *element=NULL;
1539 return iResult;
1540 }
1541 element++; i++;
1542 }
1543 HLTError("can not find memory file %p", pFile);
1544 iResult=-ENOENT;
1545 } else {
1546 iResult=-EINVAL;
1547 }
1548 return iResult;
1549}
1550
eafbc306 1551int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
a655eae3 1552{
1553 // see header file for function documentation
eafbc306 1554 int iResult=0;
1555
1556 AliHLTComponentEventDoneData* newEDD = NULL;
1557
1558 unsigned long newSize=edd.fDataSize;
1559 if (fEventDoneData)
1560 newSize += fEventDoneData->fDataSize;
1561
1562 if (newSize>fEventDoneDataSize) {
1563 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1564 if (!newEDD)
1565 return -ENOMEM;
1566 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1567 newEDD->fDataSize = newSize;
1568 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1569 unsigned long long offset = 0;
1570 if (fEventDoneData) {
1571 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1572 offset += fEventDoneData->fDataSize;
1573 }
1574 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1575 if (fEventDoneData)
1576 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1577 fEventDoneData = newEDD;
1578 fEventDoneDataSize = newSize;
1579 }
1580 else {
1581 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1582 fEventDoneData->fDataSize += edd.fDataSize;
1583 }
a655eae3 1584 return iResult;
1585}
1586
3cde846d 1587int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1588 const AliHLTComponentBlockData* blocks,
1589 AliHLTComponentTriggerData& trigData,
1590 AliHLTUInt8_t* outputPtr,
1591 AliHLTUInt32_t& size,
1592 AliHLTUInt32_t& outputBlockCnt,
1593 AliHLTComponentBlockData*& outputBlocks,
1594 AliHLTComponentEventDoneData*& edd )
1595{
70ed7d01 1596 // see header file for function documentation
66108417 1597 HLTLogKeyword(fChainId.c_str());
90ebac25 1598 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1599 int iResult=0;
1600 fCurrentEvent=evtData.fEventID;
a655eae3 1601 fCurrentEventData=evtData;
1602 fpInputBlocks=blocks;
1603 fCurrentInputBlock=-1;
1604 fSearchDataType=kAliHLTAnyDataType;
1605 fpOutputBuffer=outputPtr;
1606 fOutputBufferSize=size;
1607 fOutputBufferFilled=0;
1608 fOutputBlocks.clear();
96f9673a 1609 outputBlockCnt=0;
1610 outputBlocks=NULL;
438635e3 1611
1612 AliHLTComponentBlockDataList forwardedBlocks;
1613
1614 // optional component statistics
a0aeb701 1615 AliHLTComponentStatisticsList compStats;
438635e3 1616 bool bAddComponentTableEntry=false;
abb52c8f 1617 vector<AliHLTUInt32_t> parentComponentTables;
78d29060 1618#if defined(HLT_COMPONENT_STATISTICS)
1619 if ((fFlags&kDisableComponentStat)==0) {
1620 AliHLTComponentStatistics outputStat;
1621 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1622 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1623 outputStat.fId=fChainIdCrc;
1624 if (fpBenchmark) {
1625 fpBenchmark->Stop();
1626 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1627 fpBenchmark->Reset();
1628 fpBenchmark->Start();
1629 }
1630 compStats.push_back(outputStat);
a0aeb701 1631 }
78d29060 1632#endif // HLT_COMPONENT_STATISTICS
559631d5 1633
48abe484 1634 // data processing is skipped
1635 // - if there are only steering events in the block list.
1636 // For the sake of data source components data processing
1637 // is not skipped if there is no block list at all or if it
1638 // just contains the eventType block
1639 // - always skipped if the event is of type
1640 // - gkAliEventTypeConfiguration
1641 // - gkAliEventTypeReadPreprocessor
45c0a780 1642 const unsigned int skipModeDefault=0x1;
1643 const unsigned int skipModeForce=0x2;
1644 unsigned int bSkipDataProcessing=skipModeDefault;
1645
559631d5 1646 // find special events
45c0a780 1647 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1648 // first look for all special events and execute in the appropriate
1649 // sequence afterwords
1650 int indexComConfEvent=-1;
b543e186 1651 int indexUpdtDCSEvent=-1;
579d9eb7 1652 int indexSOREvent=-1;
1653 int indexEOREvent=-1;
cf9cf07e 1654 int indexECSParamBlock=-1;
83fec083 1655 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1656 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1657 indexSOREvent=i;
45c0a780 1658 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1659 bSkipDataProcessing&=~skipModeDefault;
1660 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1661 // run type string
1662 // handling is not clear yet
1663 if (fpInputBlocks[i].fPtr) {
1664 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1665 }
579d9eb7 1666 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1667 indexEOREvent=i;
45c0a780 1668 // the calibration processor relies on the SOR and EOR events
1669 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1670 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1671 // DDL list
1672 // this event is most likely deprecated
1673 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1674 indexComConfEvent=i;
b543e186 1675 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1676 indexUpdtDCSEvent=i;
1677 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1678 fEventType=fpInputBlocks[i].fSpecification;
1679
1680 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1681 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1682
1683 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1684 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1685
1686 // never skip if the event type block is the only block
1687 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1688
a0aeb701 1689 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1690 if (compStats.size()>0) {
1691 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1692 for (AliHLTUInt32_t offset=0;
1693 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1694 offset+=sizeof(AliHLTComponentStatistics)) {
1695 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1696 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1697 compStats[0].fLevel=pStat->fLevel+1;
1698 }
1699 compStats.push_back(*pStat);
1700 }
1701 }
438635e3 1702 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1703 forwardedBlocks.push_back(fpInputBlocks[i]);
abb52c8f 1704 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
cf9cf07e 1705 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
1706 indexECSParamBlock=i;
45c0a780 1707 } else {
1708 // the processing function is called if there is at least one
1709 // non-steering data block. Steering blocks are not filtered out
1710 // for sake of performance
1711 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1712 if (compStats.size()>0) {
1713 compStats[0].fInputBlockCount++;
1714 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1715 }
579d9eb7 1716 }
1717 }
45c0a780 1718
579d9eb7 1719 if (indexSOREvent>=0) {
1720 // start of run
438635e3 1721 bAddComponentTableEntry=true;
579d9eb7 1722 if (fpRunDesc==NULL) {
1723 fpRunDesc=new AliHLTRunDesc;
48abe484 1724 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1725 }
1726 if (fpRunDesc) {
1727 AliHLTRunDesc rundesc;
1728 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1729 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1730 *fpRunDesc=rundesc;
579d9eb7 1731 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1732 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1733 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1734 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1735 }
559631d5 1736 }
579d9eb7 1737 } else {
45c0a780 1738 iResult=-ENOMEM;
579d9eb7 1739 }
cf9cf07e 1740
1741 if (indexECSParamBlock>=0) {
1742 if (fpInputBlocks[indexECSParamBlock].fSize>0) {
1743 const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
1744 TString paramString;
1745 if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
1746 HLTWarning("ECS parameter string not terminated");
1747 paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
1748 paramString+="";
1749 } else {
1750 paramString=param;
1751 }
1752 ScanECSParam(paramString.Data());
1753 } else {
1754 HLTWarning("empty ECS parameter received");
1755 }
1756 } else {
1757 // TODO: later on we might throw a warning here since the CTP trigger classes
1758 // should be mandatory
1759 }
579d9eb7 1760 }
1761 if (indexEOREvent>=0) {
9d4d4b02 1762 fLastPushBackTime=0; // always send at EOR
438635e3 1763 bAddComponentTableEntry=true;
579d9eb7 1764 if (fpRunDesc!=NULL) {
1765 if (fpRunDesc) {
1766 AliHLTRunDesc rundesc;
1767 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1768 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1769 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1770 } else {
1771 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1772 }
559631d5 1773 }
bee8f777 1774 // we do not unload the fpRunDesc struct here in order to have the run information
1775 // available during the event processing
1776 // https://savannah.cern.ch/bugs/?39711
1777 // the info will be cleared in DeInit
559631d5 1778 }
579d9eb7 1779 } else {
1780 HLTWarning("did not receive SOR, ignoring EOR");
1781 }
1782 }
48abe484 1783 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1784 TString cdbEntry;
b543e186 1785 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1786 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1787 }
1788 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1789 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1790 if (tmpResult<0) {
1791 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1792 }
1793 }
48abe484 1794 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1795 TString modules;
1796 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1797 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1798 }
d6b69874 1799 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1800 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1801 if (tmpResult<0) {
1802 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1803 }
1804 }
45c0a780 1805 } else {
1806 // processing function needs to be called if there are no input data
1807 // blocks in order to make data source components working.
1808 bSkipDataProcessing&=~skipModeDefault;
559631d5 1809 }
a0aeb701 1810
1811 // data processing is not skipped if the component explicitly asks
1812 // for the private blocks
78d29060 1813 if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
a0aeb701 1814
edd72347 1815 if (fpCTPData) {
1816 // set the active triggers for this event
1817 fpCTPData->SetTriggers(trigData);
1818 // increment CTP trigger counters if available
1819 if (IsDataEvent()) fpCTPData->Increment(trigData);
1820 }
adb91bc3 1821
2be3f004 1822 AliHLTComponentBlockDataList blockData;
45c0a780 1823 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1824 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1825 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1826 // in order to avoid 'shadowed variable' warning
1827 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1828 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1829 } // end of the scope of the stopwatch guard
b543e186 1830 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1831 if (fOutputBlocks.size()>0) {
df61f928 1832 // High Level interface
1833
1834 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1835 // sync memory files and descriptors
2be3f004 1836 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1837 int i=0;
1838 while (element!=fMemFiles.end() && iResult>=0) {
1839 if (*element) {
1840 if ((*element)->IsClosed()==0) {
1841 HLTWarning("memory file has not been closed, force flush");
1842 iResult=CloseMemoryFile(*element);
1843 }
1844 }
1845 element++; i++;
1846 }
1847
1848 if (iResult>=0) {
1849 // create the descriptor list
1850 if (blockData.size()>0) {
1851 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1852 iResult=-EFAULT;
1853 } else {
abb52c8f 1854 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 1855 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1856 if (offset>0) fOutputBufferFilled+=offset;
1857 }
438635e3 1858 if (bAddComponentTableEntry) {
abb52c8f 1859 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
438635e3 1860 if (offset>0) size+=offset;
1861 }
1862 if (forwardedBlocks.size()>0) {
1863 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1864 }
79c114b5 1865 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1866 size=fOutputBufferFilled;
1867 }
a655eae3 1868 }
1869 } else {
df61f928 1870 // Low Level interface
a0aeb701 1871 if (compStats.size()>0) {
1872 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1873 if (offset>0) size+=offset;
1874 }
438635e3 1875 if (bAddComponentTableEntry) {
abb52c8f 1876 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
438635e3 1877 if (offset>0) size+=offset;
1878 }
1879 if (forwardedBlocks.size()>0) {
1880 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1881 }
a655eae3 1882 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1883 }
1884 if (iResult<0) {
1885 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1886 }
1887 }
b543e186 1888 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1889 outputBlockCnt=0;
1890 outputBlocks=NULL;
1891 }
8451168b 1892 CleanupInputObjects();
48abe484 1893 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1894 IncrementEventCounter();
1895 }
96f9673a 1896 if (outputBlockCnt==0) {
1897 // no output blocks, set size to 0
1898 size=0;
1899 }
6f4231a1 1900
1901 // reset the internal EventData struct
4646c6e3 1902 FillEventData(fCurrentEventData);
edd72347 1903
1904 // reset the active triggers
1905 if (fpCTPData) fpCTPData->SetTriggers(0);
9d4d4b02 1906
1907 // set the time for the pushback period
1908 if (fPushbackPeriod>0) {
1909 // suppress the output
1910 TDatime time;
1911 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime>=fPushbackPeriod) {
1912 fLastPushBackTime=time.Get();
1913 }
1914 }
1915
3cde846d 1916 return iResult;
1917}
a655eae3 1918
a0aeb701 1919int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1920 AliHLTUInt8_t* buffer,
1921 AliHLTUInt32_t bufferSize,
1922 AliHLTUInt32_t offset,
1923 AliHLTComponentStatisticsList& stats) const
1924{
1925 // see header file for function documentation
1926 int iResult=0;
78d29060 1927 if ((fFlags&kDisableComponentStat)!=0) return 0;
1928#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 1929 if (stats.size()==0) return -ENOENT;
ae962989 1930 // check if there is space for at least one entry
1931 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
a0aeb701 1932 stats[0].fTotalOutputSize=offset;
1933 stats[0].fOutputBlockCount=blocks.size();
1934 if (fpBenchmark) {
2e3fd14f 1935 fpBenchmark->Stop();
1936 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1937 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1938 fpBenchmark->Continue();
a0aeb701 1939 }
ae962989 1940 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
1941 AliHLTUInt32_t removedLevel=0;
1942 do {
1943 // remove all entries of the level of the last entry
1944 removedLevel=stats.back().fLevel;
1945 AliHLTComponentStatisticsList::iterator element=stats.begin();
1946 element++;
1947 while (element!=stats.end()) {
1948 if (element->fLevel<=removedLevel) {
1949 element=stats.erase(element);
1950 } else {
1951 element++;
1952 }
1953 }
1954 } while (stats.size()>1 &&
1955 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
1956 }
1957 assert(stats.size()>0);
1958 if (stats.size()==0) return 0;
1959
a0aeb701 1960 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1961 AliHLTComponentBlockData bd;
1962 FillBlockData( bd );
1963 bd.fOffset = offset;
1964 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1965 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1966 bd.fSpecification = kAliHLTVoidDataSpec;
1967 unsigned int master=0;
1968 for (unsigned int i=1; i<blocks.size(); i++) {
1969 if (blocks[i].fSize>blocks[master].fSize &&
1970 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1971 master=i;
1972 }
1973 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1974 // take the data origin of the biggest block as specification
1975 // this is similar to the treatment in the HOMER interface. For traditional
1976 // reasons, the bytes are swapped there on a little endian architecture, so
1977 // we do it as well.
1978 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1979#ifdef R__BYTESWAP // set on little endian architectures
1980 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1981 ((bd.fSpecification & 0xFF00ULL) << 8) |
1982 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1983 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1984#endif
1985 }
1986 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1987 blocks.push_back(bd);
1988 iResult=bd.fSize;
1989 }
bd6cac58 1990#else
1991 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
1992 // get rid of warning
1993 }
78d29060 1994#endif // HLT_COMPONENT_STATISTICS
438635e3 1995 return iResult;
1996}
1997
1998int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1999 AliHLTUInt8_t* buffer,
2000 AliHLTUInt32_t bufferSize,
abb52c8f 2001 AliHLTUInt32_t offset,
2002 const vector<AliHLTUInt32_t>& parents) const
438635e3 2003{
2004 // see header file for function documentation
2005 int iResult=0;
78d29060 2006 if ((fFlags&kDisableComponentStat)!=0) return 0;
2007#if defined(HLT_COMPONENT_STATISTICS)
abb52c8f 2008 // the payload consists of the AliHLTComponentTableEntry struct,
2009 // followed by a an array of 32bit crc chain ids and the component
2010 // description string
2011 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2012 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2013
2014 // the component description has the following format:
2015 // chain-id{component-id:arguments}
2016 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2017 unsigned int descriptionSize=fChainId.size()+1;
2018 descriptionSize+=2; // the '{}' around the component id
2019 descriptionSize+=strlen(componentId);
2020 descriptionSize+=1; // the ':' between component id and arguments
2021 descriptionSize+=fComponentArgs.size();
2022
2023 payloadSize+=descriptionSize;
2024 if (buffer && (offset+payloadSize<=bufferSize)) {
2025 AliHLTUInt8_t* pTgt=buffer+offset;
2026 memset(pTgt, 0, payloadSize);
2027
2028 // write entry
2029 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2030 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
2031 pEntry->fNofParents=parents.size();
2032 pEntry->fSizeDescription=descriptionSize;
2033 pTgt=pEntry->fBuffer;
2034
2035 // write array of parents
2036 if (parents.size()>0) {
2037 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2038 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2039 pTgt+=copy;
2040 }
2041
2042 // write component description
2043 memcpy(pTgt, fChainId.c_str(), fChainId.size());
2044 pTgt+=fChainId.size();
2045 *pTgt++='{';
2046 memcpy(pTgt, componentId, strlen(componentId));
2047 pTgt+=strlen(componentId);
2048 *pTgt++=':';
2049 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2050 pTgt+=fComponentArgs.size();
2051 *pTgt++='}';
2052 *pTgt++=0;
2053
438635e3 2054 AliHLTComponentBlockData bd;
2055 FillBlockData( bd );
2056 bd.fOffset = offset;
abb52c8f 2057 bd.fSize = payloadSize;
438635e3 2058 bd.fDataType = kAliHLTDataTypeComponentTable;
2059 bd.fSpecification = fChainIdCrc;
438635e3 2060 blocks.push_back(bd);
2061 iResult=bd.fSize;
2062 }
bd6cac58 2063#else
2064 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
2065 // get rid of warning
2066 }
78d29060 2067#endif // HLT_COMPONENT_STATISTICS
a0aeb701 2068 return iResult;
2069}
2070
90ebac25 2071AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2072 :
2073 fpStopwatch(NULL),
2074 fpPrec(NULL)
2075{
2076 // standard constructor (not for use)
2077}
2078
2079AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2080 :
2081 fpStopwatch(pStopwatch),
2082 fpPrec(NULL)
2083{
2084 // constructor
2085
2086 // check for already existing guard
2087 if (fgpCurrent) fpPrec=fgpCurrent;
2088 fgpCurrent=this;
2089
2090 // stop the preceeding guard if it controls a different stopwatch
2091 int bStart=1;
2092 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2093
2094 // start the stopwatch if the current guard controls a different one
2095 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2096}
2097
e419b223 2098AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 2099 :
2100 fpStopwatch(NULL),
2101 fpPrec(NULL)
2102{
e419b223 2103 //
2104 // copy constructor not for use
2105 //
2106}
2107
2108AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
2109{
2110 //
2111 // assignment operator not for use
2112 //
2113 fpStopwatch=NULL;
2114 fpPrec=NULL;
2115 return *this;
90ebac25 2116}
2117
2118AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2119
2120AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2121{
2122 // destructor
2123
2124 // resume the preceeding guard if it controls a different stopwatch
2125 int bStop=1;
2126 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2127
2128 // stop the stopwatch if the current guard controls a different one
2129 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2130
2131 // resume to the preceeding guard
2132 fgpCurrent=fpPrec;
2133}
2134
0007ed52 2135int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
90ebac25 2136{
2137 // see header file for function documentation
2138 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2139 return fpStopwatch!=pSucc?1:0;
2140}
2141
0007ed52 2142int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
90ebac25 2143{
2144 // see header file for function documentation
2145 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2146 return fpStopwatch!=pSucc?1:0;
2147}
2148
2149int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2150{
2151 // see header file for function documentation
2152 int iResult=0;
2153 if (pSW!=NULL && type<kSWTypeCount) {
2154 if (fpStopwatches) {
2155 TObject* pObj=fpStopwatches->At((int)type);
2156 if (pSW==NULL // explicit reset
2157 || pObj==NULL) { // explicit set
2158 fpStopwatches->AddAt(pSW, (int)type);
2159 } else if (pObj!=pSW) {
2160 HLTWarning("stopwatch %d already set, reset first", (int)type);
2161 iResult=-EBUSY;
2162 }
2163 }
2164 } else {
2165 iResult=-EINVAL;
2166 }
2167 return iResult;
2168}
2169
2170int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2171{
2172 // see header file for function documentation
2173 if (pStopwatches==NULL) return -EINVAL;
2174
2175 int iResult=0;
77fd699f 2176 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
90ebac25 2177 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2178 return iResult;
2179}
559631d5 2180
2181AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2182{
29312178 2183 // see header file for function documentation
6e289790 2184
2185 // 2010-02-11 OCDB is now the reliable source for the run number, it is
2186 // initialized either by aliroot or the external interface depending
2187 // on the environment. It turned out that the rundescriptor is not set
2188 // in the aliroot mode, resulting in an invalid run number. However this
2189 // did not cause problems until now. OCDB initialization has been revised
2190 // already in 10/2009. This was a remnant.
2191 // Have to check whether we get rid of the rundescriptor at some point.
2192 if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2193 if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2194 HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2195 }
559631d5 2196 return fpRunDesc->fRunNo;
2197}
2198
2199AliHLTUInt32_t AliHLTComponent::GetRunType() const
2200{
29312178 2201 // see header file for function documentation
45c0a780 2202 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 2203 return fpRunDesc->fRunType;
2204}
2205
6700298e 2206AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2207{
2208 // see header file for function documentation
bee8f777 2209 if (fCurrentEventData.fEventCreation_s) {
2210 return fCurrentEventData.fEventCreation_s;
2211 }
2212 // using the actual UTC if the time stamp was not set by the framework
2213 return static_cast<AliHLTUInt32_t>(time(NULL));
6700298e 2214}
2215
2216AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2217{
2218 // see header file for function documentation
2219 return (GetEventId()>>36)&0xfffffff;
2220}
2221
2222AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2223{
2224 // see header file for function documentation
2225 return (GetEventId()>>12)&0xffffff;
2226}
2227
2228AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2229{
2230 // see header file for function documentation
2231 return GetEventId()&0xfff;
2232}
2233
0007ed52 2234bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
48abe484 2235{
2236 // see header file for function documentation
2237 if (pTgt) *pTgt=fEventType;
2238 return (fEventType==gkAliEventTypeData ||
2239 fEventType==gkAliEventTypeDataReplay ||
2240 fEventType==gkAliEventTypeCalibration);
2241}
2242
83fec083 2243int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 2244 const char* structname, const char* eventname)
2245{
29312178 2246 // see header file for function documentation
559631d5 2247 int iResult=0;
2248 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2249 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2250 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2251 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 2252 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 2253 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 2254 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 2255 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2256 }
2257 if (copy!=iStructSize) {
c5123824 2258 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 2259 if (copy>iStructSize) {
2260 copy=iStructSize;
2261 } else {
2262 memset(pTgt, 0, iStructSize);
2263 }
2264 }
3294f81a 2265 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 2266 *pTgt=iStructSize;
2267 iResult=copy;
2268 } else {
2269 HLTWarning("%s event: missing data block", eventname);
2270 }
2271 } else {
2272 iResult=-ENODATA;
2273 }
2274 } else {
2275 HLTError("invalid struct");
2276 iResult=-EINVAL;
2277 }
2278 return iResult;
2279}
ed504011 2280
48abe484 2281AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2282{
2283 // see header file for function documentation
2284 AliHLTUInt32_t remainder = 0;
2285 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2286 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2287 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2288
2289 // code from
2290 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2291
2292 /*
2293 * Perform modulo-2 division, a byte at a time.
2294 */
2295 for (int byte = 0; byte < size; ++byte)
2296 {
2297 /*
2298 * Bring the next byte into the remainder.
2299 */
2300 remainder ^= (buffer[byte] << (crcwidth - 8));
2301
2302 /*
2303 * Perform modulo-2 division, a bit at a time.
2304 */
2305 for (uint8_t bit = 8; bit > 0; --bit)
2306 {
2307 /*
2308 * Try to divide the current data bit.
2309 */
2310 if (remainder & topbit)
2311 {
2312 remainder = (remainder << 1) ^ polynomial;
2313 }
2314 else
2315 {
2316 remainder = (remainder << 1);
2317 }
2318 }
2319 }
2320
2321 /*
2322 * The final remainder is the CRC result.
2323 */
2324 return (remainder);
2325}
abb52c8f 2326
2327int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2328 string& retChainId, string& retCompId, string& retCompArgs,
2329 vector<AliHLTUInt32_t>& parents)
2330{
2331 // see header file for function documentation
2332 retChainId.clear();
2333 retCompId.clear();
2334 retCompArgs.clear();
2335 parents.clear();
2336 if (!pBuffer || size==0) return 0;
2337
2338 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2339 if (size<8/* the initial size of the structure*/ ||
2340 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2341 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2342 const AliHLTUInt8_t* pEnd=pBuffer+size;
2343
2344 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2345 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2346 parents.push_back(*pParents);
2347 }
2348
2349 const char* pDescription=reinterpret_cast<const char*>(pParents);
2350 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2351 *(pDescription+pEntry->fSizeDescription)!=0) {
2352 return -EBADF;
2353 }
2354
2355 TString descriptor=reinterpret_cast<const char*>(pDescription);
2356 TString chainId;
2357 TString compId;
2358 TString compArgs;
2359 TObjArray* pTokens=descriptor.Tokenize("{");
2360 if (pTokens) {
2361 int n=0;
77fd699f 2362 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2363 retChainId=((TObjString*)pTokens->At(n++))->GetString();
2364 }
77fd699f 2365 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2366 compId=((TObjString*)pTokens->At(n++))->GetString();
2367 }
2368 delete pTokens;
2369 }
2370 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2371 int n=0;
77fd699f 2372 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2373 compId=((TObjString*)pTokens->At(n++))->GetString();
2374 }
77fd699f 2375 if (pTokens->GetEntriesFast()>n) {
abb52c8f 2376 compArgs=((TObjString*)pTokens->At(n++))->GetString();
2377 }
2378 delete pTokens;
2379 }
2380 compId.ReplaceAll("}", "");
2381 compArgs.ReplaceAll("}", "");
2382
2383 retCompId=compId;
2384 retCompArgs=compArgs;
2385
2386 if (retChainId.size()==0) return -ENODATA;
2387
2388 return 1;
2389}
97d2b87a 2390
89413559 2391int AliHLTComponent::ExtractTriggerData(
2392 const AliHLTComponentTriggerData& trigData,
2393 const AliHLTUInt8_t (**attributes)[gkAliHLTBlockDAttributeCount],
2394 AliHLTUInt64_t* status,
2395 const AliRawDataHeader** cdh,
2396 AliHLTReadoutList* readoutlist,
2397 bool printErrors
2398 )
2399{
2400 // see header file for function documentation
2401
2402 // Check that the trigger data structure is the correct size.
2403 if (trigData.fStructSize != sizeof(AliHLTComponentTriggerData))
2404 {
2405 if (printErrors)
2406 {
2407 AliHLTLogging log;
2408 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2409 "Invalid trigger structure size: %d but expected %d.", trigData.fStructSize, sizeof(AliHLTComponentTriggerData)
2410 );
2411 }
2412 return -ENOENT;
2413 }
2414
2415 // Check that the trigger data pointer points to data of a size we can handle.
2416 // Either it is the size of AliHLTEventTriggerData or 32 bits less for the old
2417 // version of AliHLTEventDDL, i.e. AliHLTEventDDLV0.
2418 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData) and
2419 trigData.fDataSize != sizeof(AliHLTEventTriggerData) - sizeof(AliHLTUInt32_t)
2420 )
2421 {
2422 if (printErrors)
2423 {
2424 AliHLTLogging log;
2425 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2426 "Invalid trigger data size: %d but expected %d.", trigData.fDataSize, sizeof(AliHLTEventTriggerData)
2427 );
2428 }
2429 return -EBADF;
2430 }
2431
2432 AliHLTEventTriggerData* evtData = reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
2433 assert(evtData != NULL);
2434
2435 // Check that the CDH has 8 words.
2436 if (cdh != NULL and evtData->fCommonHeaderWordCnt != 8)
2437 {
2438 if (printErrors)
2439 {
2440 AliHLTLogging log;
2441 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2442 "Common Data Header (CDH) has wrong number of data words: %d but expected %d",
2443 evtData->fCommonHeaderWordCnt, sizeof(AliRawDataHeader)/sizeof(AliHLTUInt32_t)
2444 );
2445 }
2446 return -EBADMSG;
2447 }
2448
2449 // Check that the readout list has the correct count of words. i.e. something we can handle,
2450 if (readoutlist != NULL and
2451 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV0 and
2452 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV1
2453 )
2454 {
2455 if (printErrors)
2456 {
2457 AliHLTLogging log;
2458 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2459 "Readout list structure has wrong number of data words: %d but expected %d",
2460 evtData->fReadoutList.fCount, gkAliHLTDDLListSize
2461 );
2462 }
2463 return -EPROTO;
2464 }
2465
2466 if (attributes != NULL)
2467 {
2468 *attributes = &evtData->fAttributes;
2469 }
2470 if (status != NULL)
2471 {
2472 *status = evtData->fHLTStatus;
2473 }
2474 if (cdh != NULL)
2475 {
2476 const AliRawDataHeader* cdhptr = reinterpret_cast<const AliRawDataHeader*>(&evtData->fCommonHeader);
2477 *cdh = cdhptr;
2478 }
2479 if (readoutlist != NULL)
2480 {
2481 *readoutlist = AliHLTReadoutList(evtData->fReadoutList);
2482 }
2483 return 0;
2484}
2485
97d2b87a 2486int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2487 const char* originClass, const char* originFunc,
2488 const char* file, int line, ... ) const
2489{
2490 // see header file for function documentation
2491 int iResult=0;
2492
2493 va_list args;
2494 va_start(args, line);
2495
2496 // logging function needs to be const in order to be called from const member functions
2497 // without problems. But at this point we face the problem with virtual members which
2498 // are not necessarily const.
2499 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
7efb6418 2500 AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
97d2b87a 2501 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
7efb6418 2502 nonconst->GetComponentID());
97d2b87a 2503 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2504 va_end(args);
2505
2506 return iResult;
2507}
cf9cf07e 2508
2509int AliHLTComponent::ScanECSParam(const char* ecsParam)
2510{
2511 // see header file for function documentation
2512
2513 // format of the parameter string from ECS
2514 // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
2515 // search for a subset of the parameterkeys
c4ffab2c 2516 // RUN_TYPE=
2517 // RUN_NUMBER=
2518 // HLT_IN_DDL_LIST=
2519 // CTP_TRIGGER_CLASS=
2520 // DATA_FORMAT_VERSION=
2521 // BEAM_TYPE=
2522 // HLT_OUT_DDL_LIST=
2523 // HLT_TRIGGER_CODE=
2524 // DETECTOR_LIST=
2525 // HLT_MODE=
2526 // The command apears not to be sent by the online framework
cf9cf07e 2527 int iResult=0;
2528 TString string=ecsParam;
2529 TObjArray* parameter=string.Tokenize(";");
2530 if (parameter) {
77fd699f 2531 for (int i=0; i<parameter->GetEntriesFast(); i++) {
cf9cf07e 2532 TString entry=((TObjString*)parameter->At(i))->GetString();
2533 HLTDebug("scanning ECS entry: %s", entry.Data());
2534 TObjArray* entryParams=entry.Tokenize("=");
2535 if (entryParams) {
77fd699f 2536 if (entryParams->GetEntriesFast()>1) {
cf9cf07e 2537 if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
2538 int result=InitCTPTriggerClasses((((TObjString*)entryParams->At(1))->GetString()).Data());
2539 if (iResult>=0 && result<0) iResult=result;
2540 } else {
2541 // TODO: scan the other parameters
2542 // e.g. consistency check of run number
2543 }
2544 }
2545 delete entryParams;
2546 }
2547 }
2548 delete parameter;
2549 }
2550
2551 return iResult;
2552}
2553
adb91bc3 2554int AliHLTComponent::SetupCTPData()
cf9cf07e 2555{
2556 // see header file for function documentation
adb91bc3 2557 if (fpCTPData) delete fpCTPData;
2558 fpCTPData=new AliHLTCTPData;
2559 if (!fpCTPData) return -ENOMEM;
cf9cf07e 2560 return 0;
2561}
2562
adb91bc3 2563int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
cf9cf07e 2564{
2565 // see header file for function documentation
adb91bc3 2566 if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
2567 return fpCTPData->InitCTPTriggerClasses(ctpString);
2568}
cf9cf07e 2569
adb91bc3 2570bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
2571{
2572 // see header file for function documentation
2573 if (!fpCTPData) {
2574 static bool bWarningThrown=false;
2575 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2576 bWarningThrown=true;
cf9cf07e 2577 return false;
2578 }
2579
adb91bc3 2580 return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
cf9cf07e 2581}
a5e775ec 2582
3fcb48b8 2583int AliHLTComponent::CheckCTPTrigger(const char* name) const
2584{
2585 // see header file for function documentation
2586 if (!fpCTPData) {
2587 static bool bWarningThrown=false;
2588 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2589 bWarningThrown=true;
2590 return false;
2591 }
2592
2593 return fpCTPData->CheckTrigger(name);
2594}
2595
a5e775ec 2596Double_t AliHLTComponent::GetBz()
2597{
2598 // Returns Bz.
2599 return AliHLTMisc::Instance().GetBz();
2600}
2601
2602Double_t AliHLTComponent::GetBz(const Double_t *r)
2603{
2604 // Returns Bz (kG) at the point "r" .
2605 return AliHLTMisc::Instance().GetBz(r);
2606}
2607
2608void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
2609{
2610 // Returns Bx, By and Bz (kG) at the point "r" .
2611 AliHLTMisc::Instance().GetBxByBz(r, b);
2612}