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