]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponent.cxx
Bug fix for modulo functionality
[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) {}
0622a0f3 1750 bool operator==(const AliHLTComponentStatistics& a) const {return a.fId==fId;}
1751 private:
1752 AliHLTComponentStatisticsId();
0622a0f3 1753 AliHLTUInt32_t fId;
1754 };
1755
1756 // operator for std::find of AliHLTComponentStatistics by id
1757 bool operator==(const AliHLTComponentStatistics& a, const AliHLTComponentStatisticsId& b)
1758 {
1759 return b==a;
1760 }
1761
1762 bool AliHLTComponentStatisticsCompareIds(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1763 {
1764 return a.fId==b.fId;
1765 }
1766
1767 // helper class to define operator== between AliHLTComponentBlockData and AliHLTComponentBlockData.fSpecification
1768 class AliHLTComponentBlockDataSpecification {
1769 public:
1770 AliHLTComponentBlockDataSpecification(AliHLTUInt32_t specification) : fSpecification(specification) {}
f308715b 1771 AliHLTComponentBlockDataSpecification(const AliHLTComponentBlockDataSpecification& src) : fSpecification(src.fSpecification) {}
0622a0f3 1772 bool operator==(const AliHLTComponentBlockData& bd) const {return bd.fSpecification==fSpecification;}
1773 private:
1774 AliHLTComponentBlockDataSpecification();
0622a0f3 1775 AliHLTUInt32_t fSpecification;
1776 };
1777
1778 // operator for std::find of AliHLTComponentBlockData by specification
1779 bool operator==(const AliHLTComponentBlockData& bd, const AliHLTComponentBlockDataSpecification& spec)
1780 {
1781 return spec==bd;
1782 }
1783
1784 // operator for std::find
1785 bool operator==(const AliHLTComponentBlockData& a, const AliHLTComponentBlockData& b)
1786 {
1787 if (!MatchExactly(a.fDataType,b.fDataType)) return false;
1788 return a.fSpecification==b.fSpecification;
1789 }
1790
1791} // end of namespace
1792
3cde846d 1793int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1794 const AliHLTComponentBlockData* blocks,
1795 AliHLTComponentTriggerData& trigData,
1796 AliHLTUInt8_t* outputPtr,
1797 AliHLTUInt32_t& size,
1798 AliHLTUInt32_t& outputBlockCnt,
1799 AliHLTComponentBlockData*& outputBlocks,
1800 AliHLTComponentEventDoneData*& edd )
1801{
70ed7d01 1802 // see header file for function documentation
66108417 1803 HLTLogKeyword(fChainId.c_str());
90ebac25 1804 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1805 int iResult=0;
1806 fCurrentEvent=evtData.fEventID;
a655eae3 1807 fCurrentEventData=evtData;
1808 fpInputBlocks=blocks;
1809 fCurrentInputBlock=-1;
1810 fSearchDataType=kAliHLTAnyDataType;
1811 fpOutputBuffer=outputPtr;
1812 fOutputBufferSize=size;
1813 fOutputBufferFilled=0;
1814 fOutputBlocks.clear();
96f9673a 1815 outputBlockCnt=0;
1816 outputBlocks=NULL;
438635e3 1817
1818 AliHLTComponentBlockDataList forwardedBlocks;
1819
1820 // optional component statistics
a0aeb701 1821 AliHLTComponentStatisticsList compStats;
438635e3 1822 bool bAddComponentTableEntry=false;
abb52c8f 1823 vector<AliHLTUInt32_t> parentComponentTables;
0622a0f3 1824 int processingLevel=-1;
78d29060 1825#if defined(HLT_COMPONENT_STATISTICS)
1826 if ((fFlags&kDisableComponentStat)==0) {
1827 AliHLTComponentStatistics outputStat;
1828 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1829 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1830 outputStat.fId=fChainIdCrc;
1831 if (fpBenchmark) {
1832 fpBenchmark->Stop();
1833 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1834 fpBenchmark->Reset();
1835 fpBenchmark->Start();
1836 }
1837 compStats.push_back(outputStat);
a0aeb701 1838 }
78d29060 1839#endif // HLT_COMPONENT_STATISTICS
559631d5 1840
48abe484 1841 // data processing is skipped
1842 // - if there are only steering events in the block list.
1843 // For the sake of data source components data processing
1844 // is not skipped if there is no block list at all or if it
1845 // just contains the eventType block
1846 // - always skipped if the event is of type
1847 // - gkAliEventTypeConfiguration
1848 // - gkAliEventTypeReadPreprocessor
45c0a780 1849 const unsigned int skipModeDefault=0x1;
1850 const unsigned int skipModeForce=0x2;
1851 unsigned int bSkipDataProcessing=skipModeDefault;
1852
559631d5 1853 // find special events
45c0a780 1854 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1855 // first look for all special events and execute in the appropriate
1856 // sequence afterwords
1857 int indexComConfEvent=-1;
b543e186 1858 int indexUpdtDCSEvent=-1;
579d9eb7 1859 int indexSOREvent=-1;
1860 int indexEOREvent=-1;
cf9cf07e 1861 int indexECSParamBlock=-1;
83fec083 1862 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1863 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1864 indexSOREvent=i;
45c0a780 1865 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1866 bSkipDataProcessing&=~skipModeDefault;
1867 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1868 // run type string
1869 // handling is not clear yet
1870 if (fpInputBlocks[i].fPtr) {
1871 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1872 }
579d9eb7 1873 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1874 indexEOREvent=i;
45c0a780 1875 // the calibration processor relies on the SOR and EOR events
1876 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1877 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1878 // DDL list
1879 // this event is most likely deprecated
1880 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1881 indexComConfEvent=i;
b543e186 1882 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1883 indexUpdtDCSEvent=i;
1884 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1885 fEventType=fpInputBlocks[i].fSpecification;
9e14734f 1886 if (fEventType != gkAliEventTypeConfiguration and
1887 fEventType != gkAliEventTypeReadPreprocessor
1888 )
1889 {
1890 // We can actually get the event type from the CDH if it is valid.
1891 // Otherwise just use the specification of the input block.
1892 const AliRawDataHeader* cdh;
1893 if (ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) == 0)
1894 {
1895 fEventType = ExtractEventTypeFromCDH(cdh);
1896 }
1897 }
48abe484 1898
1899 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1900 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1901
1902 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1903 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1904
1905 // never skip if the event type block is the only block
1906 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1907
a0aeb701 1908 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1909 if (compStats.size()>0) {
1910 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1911 for (AliHLTUInt32_t offset=0;
1912 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1913 offset+=sizeof(AliHLTComponentStatistics)) {
1914 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1915 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1916 compStats[0].fLevel=pStat->fLevel+1;
1917 }
0622a0f3 1918 if (find(compStats.begin(), compStats.end(), AliHLTComponentStatisticsId(pStat->fId))==compStats.end()) {
1919 compStats.push_back(*pStat);
1920 }
a0aeb701 1921 }
1922 }
438635e3 1923 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
0622a0f3 1924 AliHLTComponentBlockDataList::iterator element=forwardedBlocks.begin();
1925 while ((element=find(element, forwardedBlocks.end(), AliHLTComponentBlockDataSpecification(fpInputBlocks[i].fSpecification)))!=forwardedBlocks.end()) {
1926 if (element->fDataType==fpInputBlocks[i].fDataType) break;
1927 // TODO: think about some more checks inclusing also the actual data buffers
1928 // this has to handle multiplicity>1 in the online system, where all components
1929 // send the information on SOR, because this event is broadcasted
1930 }
1931 if (element==forwardedBlocks.end()) {
1932 forwardedBlocks.push_back(fpInputBlocks[i]);
1933 }
abb52c8f 1934 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
0622a0f3 1935 if (fpInputBlocks[i].fSize>=sizeof(AliHLTComponentTableEntry)) {
1936 const AliHLTComponentTableEntry* entry=reinterpret_cast<AliHLTComponentTableEntry*>(fpInputBlocks[i].fPtr);
1937 if (entry->fStructSize==sizeof(AliHLTComponentTableEntry)) {
1938 if (processingLevel<0 || processingLevel<=(int)entry->fLevel)
1939 processingLevel=entry->fLevel+1;
1940 }
1941 }
cf9cf07e 1942 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
1943 indexECSParamBlock=i;
45c0a780 1944 } else {
1945 // the processing function is called if there is at least one
1946 // non-steering data block. Steering blocks are not filtered out
1947 // for sake of performance
1948 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1949 if (compStats.size()>0) {
1950 compStats[0].fInputBlockCount++;
1951 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1952 }
579d9eb7 1953 }
1954 }
45c0a780 1955
579d9eb7 1956 if (indexSOREvent>=0) {
1957 // start of run
438635e3 1958 bAddComponentTableEntry=true;
0622a0f3 1959 compStats.clear(); // no component statistics for SOR
579d9eb7 1960 if (fpRunDesc==NULL) {
1961 fpRunDesc=new AliHLTRunDesc;
48abe484 1962 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1963 }
1964 if (fpRunDesc) {
1965 AliHLTRunDesc rundesc;
1966 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1967 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1968 *fpRunDesc=rundesc;
579d9eb7 1969 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1970 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1971 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1972 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1973 }
559631d5 1974 }
579d9eb7 1975 } else {
45c0a780 1976 iResult=-ENOMEM;
579d9eb7 1977 }
cf9cf07e 1978
1979 if (indexECSParamBlock>=0) {
1980 if (fpInputBlocks[indexECSParamBlock].fSize>0) {
1981 const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
1982 TString paramString;
1983 if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
1984 HLTWarning("ECS parameter string not terminated");
1985 paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
1986 paramString+="";
1987 } else {
1988 paramString=param;
1989 }
1990 ScanECSParam(paramString.Data());
1991 } else {
1992 HLTWarning("empty ECS parameter received");
1993 }
1994 } else {
1995 // TODO: later on we might throw a warning here since the CTP trigger classes
1996 // should be mandatory
1997 }
579d9eb7 1998 }
1999 if (indexEOREvent>=0) {
9d4d4b02 2000 fLastPushBackTime=0; // always send at EOR
438635e3 2001 bAddComponentTableEntry=true;
0622a0f3 2002 compStats.clear(); // no component statistics for EOR
579d9eb7 2003 if (fpRunDesc!=NULL) {
2004 if (fpRunDesc) {
2005 AliHLTRunDesc rundesc;
2006 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
2007 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 2008 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 2009 } else {
2010 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 2011 }
559631d5 2012 }
bee8f777 2013 // we do not unload the fpRunDesc struct here in order to have the run information
2014 // available during the event processing
2015 // https://savannah.cern.ch/bugs/?39711
2016 // the info will be cleared in DeInit
559631d5 2017 }
579d9eb7 2018 } else {
2019 HLTWarning("did not receive SOR, ignoring EOR");
2020 }
2021 }
76390ea0 2022 if (fEventType==gkAliEventTypeConfiguration) {
2023 if (indexComConfEvent>=0) {
579d9eb7 2024 TString cdbEntry;
b543e186 2025 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 2026 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
2027 }
2028 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
2029 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
2030 if (tmpResult<0) {
2031 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 2032 }
76390ea0 2033 } else {
2034 ALIHLTERRORGUARD(1, "incomplete Configure event, missing parameter data block");
2035 }
559631d5 2036 }
76390ea0 2037 if (fEventType==gkAliEventTypeReadPreprocessor) {
2038 if (indexUpdtDCSEvent>=0) {
b543e186 2039 TString modules;
4b30799e 2040 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
b543e186 2041 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
2042 }
d6b69874 2043 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
2044 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 2045 if (tmpResult<0) {
2046 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
2047 }
76390ea0 2048 } else {
2049 ALIHLTERRORGUARD(1, "incomplete ReadPreprocessor event, missing parameter data block");
2050 }
b543e186 2051 }
45c0a780 2052 } else {
2053 // processing function needs to be called if there are no input data
2054 // blocks in order to make data source components working.
2055 bSkipDataProcessing&=~skipModeDefault;
559631d5 2056 }
a0aeb701 2057
2058 // data processing is not skipped if the component explicitly asks
2059 // for the private blocks
78d29060 2060 if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
a0aeb701 2061
0622a0f3 2062 // data processing is not skipped for data sources
2063 if (GetComponentType()==AliHLTComponent::kSource) bSkipDataProcessing=0;
2064
edd72347 2065 if (fpCTPData) {
2066 // set the active triggers for this event
2067 fpCTPData->SetTriggers(trigData);
2068 // increment CTP trigger counters if available
2069 if (IsDataEvent()) fpCTPData->Increment(trigData);
2070 }
7e0dd7eb 2071
2072 // Check if the event processing should be skipped because of the
2073 // down scaling from the event modulo argument. Using a prime number
2074 // as pre divisor to pseudo-randomise the event number to get a more
2075 // uniform distribution.
2076 if (fEventModulo > 1)
2077 {
231bce06 2078 bSkipDataProcessing |= ( ((AliHLTUInt64_t(fCurrentEvent) / AliHLTUInt64_t(4789)) % AliHLTUInt64_t(fEventModulo)) != 0 );
7e0dd7eb 2079 }
adb91bc3 2080
2be3f004 2081 AliHLTComponentBlockDataList blockData;
45c0a780 2082 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 2083 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 2084 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
2085 // in order to avoid 'shadowed variable' warning
2086 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
d906c8d9 2087 AliHLTMisc::AliOnlineGuard onlineGuard;
90ebac25 2088 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
2089 } // end of the scope of the stopwatch guard
b543e186 2090 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 2091 if (fOutputBlocks.size()>0) {
df61f928 2092 // High Level interface
2093
2094 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 2095 // sync memory files and descriptors
2be3f004 2096 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 2097 int i=0;
2098 while (element!=fMemFiles.end() && iResult>=0) {
2099 if (*element) {
2100 if ((*element)->IsClosed()==0) {
2101 HLTWarning("memory file has not been closed, force flush");
2102 iResult=CloseMemoryFile(*element);
2103 }
2104 }
2105 element++; i++;
2106 }
2107
2108 if (iResult>=0) {
2109 // create the descriptor list
2110 if (blockData.size()>0) {
2111 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
2112 iResult=-EFAULT;
2113 } else {
abb52c8f 2114 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 2115 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
2116 if (offset>0) fOutputBufferFilled+=offset;
2117 }
438635e3 2118 if (bAddComponentTableEntry) {
0622a0f3 2119 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables, processingLevel);
438635e3 2120 if (offset>0) size+=offset;
2121 }
2122 if (forwardedBlocks.size()>0) {
2123 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2124 }
79c114b5 2125 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
2126 size=fOutputBufferFilled;
2127 }
a655eae3 2128 }
2129 } else {
df61f928 2130 // Low Level interface
0622a0f3 2131 if (blockData.empty() && size!=0) {
2132 // set the size to zero because there is no announced data
2133 //HLTWarning("no output blocks added by component but output buffer filled %d of %d", size, fOutputBufferSize);
2134 size=0;
2135 }
2136
a0aeb701 2137 if (compStats.size()>0) {
2138 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
2139 if (offset>0) size+=offset;
2140 }
438635e3 2141 if (bAddComponentTableEntry) {
0622a0f3 2142 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables, processingLevel);
438635e3 2143 if (offset>0) size+=offset;
2144 }
2145 if (forwardedBlocks.size()>0) {
2146 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2147 }
a655eae3 2148 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
2149 }
2150 if (iResult<0) {
2151 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
2152 }
2153 }
b543e186 2154 if (iResult<0 || bSkipDataProcessing) {
a655eae3 2155 outputBlockCnt=0;
2156 outputBlocks=NULL;
2157 }
8451168b 2158 CleanupInputObjects();
48abe484 2159 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 2160 IncrementEventCounter();
2161 }
96f9673a 2162 if (outputBlockCnt==0) {
2163 // no output blocks, set size to 0
2164 size=0;
2165 }
6f4231a1 2166
2167 // reset the internal EventData struct
4646c6e3 2168 FillEventData(fCurrentEventData);
edd72347 2169
2170 // reset the active triggers
2171 if (fpCTPData) fpCTPData->SetTriggers(0);
9d4d4b02 2172
2173 // set the time for the pushback period
2174 if (fPushbackPeriod>0) {
2175 // suppress the output
2176 TDatime time;
ebdd604d 2177 if (fLastPushBackTime<0) {
2178 // choose a random offset at beginning to equalize traffic for multiple instances
2179 // of the component
2180 gRandom->SetSeed(fChainIdCrc);
2181 fLastPushBackTime=time.Get();
2182 fLastPushBackTime-=gRandom->Integer(fPushbackPeriod);
2183 } else if ((int)time.Get()-fLastPushBackTime>=fPushbackPeriod) {
9d4d4b02 2184 fLastPushBackTime=time.Get();
2185 }
2186 }
2187
3cde846d 2188 return iResult;
2189}
a655eae3 2190
a0aeb701 2191int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
2192 AliHLTUInt8_t* buffer,
2193 AliHLTUInt32_t bufferSize,
2194 AliHLTUInt32_t offset,
2195 AliHLTComponentStatisticsList& stats) const
2196{
2197 // see header file for function documentation
2198 int iResult=0;
78d29060 2199 if ((fFlags&kDisableComponentStat)!=0) return 0;
2200#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 2201 if (stats.size()==0) return -ENOENT;
ae962989 2202 // check if there is space for at least one entry
2203 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
a0aeb701 2204 stats[0].fTotalOutputSize=offset;
2205 stats[0].fOutputBlockCount=blocks.size();
2206 if (fpBenchmark) {
2e3fd14f 2207 fpBenchmark->Stop();
2208 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2209 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2210 fpBenchmark->Continue();
a0aeb701 2211 }
0622a0f3 2212
2213 sort(stats.begin(), stats.end(), SortComponentStatisticsDescendingByLevel);
2214
2215 // shrink the number of entries if the buffer is too small
ae962989 2216 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
0622a0f3 2217 unsigned originalSize=stats.size();
ae962989 2218 AliHLTUInt32_t removedLevel=0;
2219 do {
2220 // remove all entries of the level of the last entry
2221 removedLevel=stats.back().fLevel;
2222 AliHLTComponentStatisticsList::iterator element=stats.begin();
2223 element++;
2224 while (element!=stats.end()) {
2225 if (element->fLevel<=removedLevel) {
2226 element=stats.erase(element);
2227 } else {
2228 element++;
2229 }
2230 }
2231 } while (stats.size()>1 &&
2232 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
0622a0f3 2233 HLTWarning("too little space in output buffer to add block of %d statistics entries (size %d), available %d, removed %d entries",
2234 originalSize, sizeof(AliHLTComponentStatistics), bufferSize-offset, originalSize-stats.size());
2235 } else {
2236 HLTDebug("adding block of %d statistics entries", stats.size());
ae962989 2237 }
2238 assert(stats.size()>0);
2239 if (stats.size()==0) return 0;
2240
a0aeb701 2241 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
2242 AliHLTComponentBlockData bd;
2243 FillBlockData( bd );
2244 bd.fOffset = offset;
2245 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
2246 bd.fDataType = kAliHLTDataTypeComponentStatistics;
0622a0f3 2247 bd.fSpecification = fChainIdCrc;
a0aeb701 2248 memcpy(buffer+offset, &(stats[0]), bd.fSize);
2249 blocks.push_back(bd);
2250 iResult=bd.fSize;
2251 }
bd6cac58 2252#else
2253 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
2254 // get rid of warning
2255 }
78d29060 2256#endif // HLT_COMPONENT_STATISTICS
438635e3 2257 return iResult;
2258}
2259
2260int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
2261 AliHLTUInt8_t* buffer,
2262 AliHLTUInt32_t bufferSize,
abb52c8f 2263 AliHLTUInt32_t offset,
0622a0f3 2264 const vector<AliHLTUInt32_t>& parents,
2265 int processingLevel) const
438635e3 2266{
2267 // see header file for function documentation
2268 int iResult=0;
78d29060 2269 if ((fFlags&kDisableComponentStat)!=0) return 0;
2270#if defined(HLT_COMPONENT_STATISTICS)
abb52c8f 2271 // the payload consists of the AliHLTComponentTableEntry struct,
2272 // followed by a an array of 32bit crc chain ids and the component
2273 // description string
2274 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2275 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2276
2277 // the component description has the following format:
2278 // chain-id{component-id:arguments}
2279 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2280 unsigned int descriptionSize=fChainId.size()+1;
2281 descriptionSize+=2; // the '{}' around the component id
2282 descriptionSize+=strlen(componentId);
2283 descriptionSize+=1; // the ':' between component id and arguments
2284 descriptionSize+=fComponentArgs.size();
2285
2286 payloadSize+=descriptionSize;
2287 if (buffer && (offset+payloadSize<=bufferSize)) {
2288 AliHLTUInt8_t* pTgt=buffer+offset;
2289 memset(pTgt, 0, payloadSize);
2290
2291 // write entry
2292 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2293 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
0622a0f3 2294 pEntry->fLevel=processingLevel>=0?processingLevel:0;
abb52c8f 2295 pEntry->fNofParents=parents.size();
2296 pEntry->fSizeDescription=descriptionSize;
2297 pTgt=pEntry->fBuffer;
2298
2299 // write array of parents
2300 if (parents.size()>0) {
2301 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2302 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2303 pTgt+=copy;
2304 }
2305
2306 // write component description
2307 memcpy(pTgt, fChainId.c_str(), fChainId.size());
2308 pTgt+=fChainId.size();
2309 *pTgt++='{';
2310 memcpy(pTgt, componentId, strlen(componentId));
2311 pTgt+=strlen(componentId);
2312 *pTgt++=':';
2313 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2314 pTgt+=fComponentArgs.size();
2315 *pTgt++='}';
2316 *pTgt++=0;
2317
438635e3 2318 AliHLTComponentBlockData bd;
2319 FillBlockData( bd );
2320 bd.fOffset = offset;
abb52c8f 2321 bd.fSize = payloadSize;
438635e3 2322 bd.fDataType = kAliHLTDataTypeComponentTable;
2323 bd.fSpecification = fChainIdCrc;
438635e3 2324 blocks.push_back(bd);
2325 iResult=bd.fSize;
2326 }
bd6cac58 2327#else
0622a0f3 2328 if (blocks.size() && buffer && bufferSize && offset && parents.size() && processingLevel) {
bd6cac58 2329 // get rid of warning
2330 }
78d29060 2331#endif // HLT_COMPONENT_STATISTICS
a0aeb701 2332 return iResult;
2333}
2334
90ebac25 2335AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2336 :
2337 fpStopwatch(NULL),
2338 fpPrec(NULL)
2339{
2340 // standard constructor (not for use)
2341}
2342
2343AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2344 :
2345 fpStopwatch(pStopwatch),
2346 fpPrec(NULL)
2347{
2348 // constructor
2349
2350 // check for already existing guard
2351 if (fgpCurrent) fpPrec=fgpCurrent;
2352 fgpCurrent=this;
2353
2354 // stop the preceeding guard if it controls a different stopwatch
2355 int bStart=1;
2356 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2357
2358 // start the stopwatch if the current guard controls a different one
2359 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2360}
2361
e419b223 2362AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 2363 :
2364 fpStopwatch(NULL),
2365 fpPrec(NULL)
2366{
e419b223 2367 //
2368 // copy constructor not for use
2369 //
2370}
2371
2372AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
2373{
2374 //
2375 // assignment operator not for use
2376 //
2377 fpStopwatch=NULL;
2378 fpPrec=NULL;
2379 return *this;
90ebac25 2380}
2381
2382AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2383
2384AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2385{
2386 // destructor
2387
2388 // resume the preceeding guard if it controls a different stopwatch
2389 int bStop=1;
2390 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2391
2392 // stop the stopwatch if the current guard controls a different one
2393 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2394
2395 // resume to the preceeding guard
2396 fgpCurrent=fpPrec;
2397}
2398
0007ed52 2399int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
90ebac25 2400{
2401 // see header file for function documentation
2402 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2403 return fpStopwatch!=pSucc?1:0;
2404}
2405
0007ed52 2406int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
90ebac25 2407{
2408 // see header file for function documentation
2409 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2410 return fpStopwatch!=pSucc?1:0;
2411}
2412
2413int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2414{
2415 // see header file for function documentation
2416 int iResult=0;
2417 if (pSW!=NULL && type<kSWTypeCount) {
2418 if (fpStopwatches) {
2419 TObject* pObj=fpStopwatches->At((int)type);
2420 if (pSW==NULL // explicit reset
2421 || pObj==NULL) { // explicit set
2422 fpStopwatches->AddAt(pSW, (int)type);
2423 } else if (pObj!=pSW) {
2424 HLTWarning("stopwatch %d already set, reset first", (int)type);
2425 iResult=-EBUSY;
2426 }
2427 }
2428 } else {
2429 iResult=-EINVAL;
2430 }
2431 return iResult;
2432}
2433
2434int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2435{
2436 // see header file for function documentation
2437 if (pStopwatches==NULL) return -EINVAL;
2438
2439 int iResult=0;
77fd699f 2440 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
90ebac25 2441 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2442 return iResult;
2443}
559631d5 2444
2445AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2446{
29312178 2447 // see header file for function documentation
6e289790 2448
2449 // 2010-02-11 OCDB is now the reliable source for the run number, it is
2450 // initialized either by aliroot or the external interface depending
2451 // on the environment. It turned out that the rundescriptor is not set
2452 // in the aliroot mode, resulting in an invalid run number. However this
2453 // did not cause problems until now. OCDB initialization has been revised
2454 // already in 10/2009. This was a remnant.
2455 // Have to check whether we get rid of the rundescriptor at some point.
2456 if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2457 if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2458 HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2459 }
559631d5 2460 return fpRunDesc->fRunNo;
2461}
2462
2463AliHLTUInt32_t AliHLTComponent::GetRunType() const
2464{
29312178 2465 // see header file for function documentation
45c0a780 2466 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 2467 return fpRunDesc->fRunType;
2468}
2469
6700298e 2470AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2471{
2472 // see header file for function documentation
bee8f777 2473 if (fCurrentEventData.fEventCreation_s) {
2474 return fCurrentEventData.fEventCreation_s;
2475 }
2476 // using the actual UTC if the time stamp was not set by the framework
2477 return static_cast<AliHLTUInt32_t>(time(NULL));
6700298e 2478}
2479
2480AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2481{
2482 // see header file for function documentation
2483 return (GetEventId()>>36)&0xfffffff;
2484}
2485
2486AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2487{
2488 // see header file for function documentation
2489 return (GetEventId()>>12)&0xffffff;
2490}
2491
2492AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2493{
2494 // see header file for function documentation
2495 return GetEventId()&0xfff;
2496}
2497
0007ed52 2498bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
48abe484 2499{
2500 // see header file for function documentation
2501 if (pTgt) *pTgt=fEventType;
2502 return (fEventType==gkAliEventTypeData ||
9e14734f 2503 fEventType==gkAliEventTypeDataReplay);
48abe484 2504}
2505
83fec083 2506int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 2507 const char* structname, const char* eventname)
2508{
29312178 2509 // see header file for function documentation
559631d5 2510 int iResult=0;
2511 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2512 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2513 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2514 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 2515 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 2516 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 2517 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 2518 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2519 }
2520 if (copy!=iStructSize) {
c5123824 2521 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 2522 if (copy>iStructSize) {
2523 copy=iStructSize;
2524 } else {
2525 memset(pTgt, 0, iStructSize);
2526 }
2527 }
3294f81a 2528 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 2529 *pTgt=iStructSize;
2530 iResult=copy;
2531 } else {
2532 HLTWarning("%s event: missing data block", eventname);
2533 }
2534 } else {
2535 iResult=-ENODATA;
2536 }
2537 } else {
2538 HLTError("invalid struct");
2539 iResult=-EINVAL;
2540 }
2541 return iResult;
2542}
ed504011 2543
48abe484 2544AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2545{
2546 // see header file for function documentation
2547 AliHLTUInt32_t remainder = 0;
2548 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2549 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2550 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2551
2552 // code from
2553 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2554
2555 /*
2556 * Perform modulo-2 division, a byte at a time.
2557 */
2558 for (int byte = 0; byte < size; ++byte)
2559 {
2560 /*
2561 * Bring the next byte into the remainder.
2562 */
2563 remainder ^= (buffer[byte] << (crcwidth - 8));
2564
2565 /*
2566 * Perform modulo-2 division, a bit at a time.
2567 */
2568 for (uint8_t bit = 8; bit > 0; --bit)
2569 {
2570 /*
2571 * Try to divide the current data bit.
2572 */
2573 if (remainder & topbit)
2574 {
2575 remainder = (remainder << 1) ^ polynomial;
2576 }
2577 else
2578 {
2579 remainder = (remainder << 1);
2580 }
2581 }
2582 }
2583
2584 /*
2585 * The final remainder is the CRC result.
2586 */
2587 return (remainder);
2588}
abb52c8f 2589
2590int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2591 string& retChainId, string& retCompId, string& retCompArgs,
0622a0f3 2592 vector<AliHLTUInt32_t>& parents, int& level)
abb52c8f 2593{
2594 // see header file for function documentation
2595 retChainId.clear();
2596 retCompId.clear();
2597 retCompArgs.clear();
2598 parents.clear();
0622a0f3 2599 level=-1;
abb52c8f 2600 if (!pBuffer || size==0) return 0;
2601
2602 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2603 if (size<8/* the initial size of the structure*/ ||
2604 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
0622a0f3 2605
2606 if (pEntry->fStructSize!=sizeof(AliHLTComponentTableEntry)) return -EBADF;
2607 level=pEntry->fLevel;
abb52c8f 2608 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2609 const AliHLTUInt8_t* pEnd=pBuffer+size;
2610
2611 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2612 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2613 parents.push_back(*pParents);
2614 }
2615
2616 const char* pDescription=reinterpret_cast<const char*>(pParents);
2617 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2618 *(pDescription+pEntry->fSizeDescription)!=0) {
2619 return -EBADF;
2620 }
2621
2622 TString descriptor=reinterpret_cast<const char*>(pDescription);
2623 TString chainId;
2624 TString compId;
2625 TString compArgs;
2626 TObjArray* pTokens=descriptor.Tokenize("{");
2627 if (pTokens) {
2628 int n=0;
77fd699f 2629 if (pTokens->GetEntriesFast()>n) {
704972af 2630 retChainId=pTokens->At(n++)->GetName();
abb52c8f 2631 }
77fd699f 2632 if (pTokens->GetEntriesFast()>n) {
704972af 2633 compId=pTokens->At(n++)->GetName();
abb52c8f 2634 }
2635 delete pTokens;
2636 }
2637 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2638 int n=0;
77fd699f 2639 if (pTokens->GetEntriesFast()>n) {
704972af 2640 compId=pTokens->At(n++)->GetName();
abb52c8f 2641 }
77fd699f 2642 if (pTokens->GetEntriesFast()>n) {
704972af 2643 compArgs=pTokens->At(n++)->GetName();
abb52c8f 2644 }
2645 delete pTokens;
2646 }
2647 compId.ReplaceAll("}", "");
2648 compArgs.ReplaceAll("}", "");
2649
2650 retCompId=compId;
2651 retCompArgs=compArgs;
2652
2653 if (retChainId.size()==0) return -ENODATA;
2654
2655 return 1;
2656}
97d2b87a 2657
89413559 2658int AliHLTComponent::ExtractTriggerData(
2659 const AliHLTComponentTriggerData& trigData,
2660 const AliHLTUInt8_t (**attributes)[gkAliHLTBlockDAttributeCount],
2661 AliHLTUInt64_t* status,
2662 const AliRawDataHeader** cdh,
2663 AliHLTReadoutList* readoutlist,
2664 bool printErrors
2665 )
2666{
2667 // see header file for function documentation
2668
2669 // Check that the trigger data structure is the correct size.
2670 if (trigData.fStructSize != sizeof(AliHLTComponentTriggerData))
2671 {
2672 if (printErrors)
2673 {
2674 AliHLTLogging log;
2675 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2676 "Invalid trigger structure size: %d but expected %d.", trigData.fStructSize, sizeof(AliHLTComponentTriggerData)
2677 );
2678 }
2679 return -ENOENT;
2680 }
2681
e4d966f5 2682 // Get the size of the AliHLTEventTriggerData structure without the readout list part.
2683 // The way we do this here should also handle memory alignment correctly.
2684 AliHLTEventTriggerData* dummy = NULL;
2685 size_t sizeWithoutReadout = (char*)(&dummy->fReadoutList) - (char*)(dummy);
2686
89413559 2687 // Check that the trigger data pointer points to data of a size we can handle.
e4d966f5 2688 // Either it is the size of AliHLTEventTriggerData or the size of the old
2689 // version of AliHLTEventTriggerData using AliHLTEventDDLV0.
89413559 2690 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData) and
e4d966f5 2691 trigData.fDataSize != sizeWithoutReadout + sizeof(AliHLTEventDDLV0)
89413559 2692 )
2693 {
2694 if (printErrors)
2695 {
2696 AliHLTLogging log;
2697 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2698 "Invalid trigger data size: %d but expected %d.", trigData.fDataSize, sizeof(AliHLTEventTriggerData)
2699 );
2700 }
2701 return -EBADF;
2702 }
2703
2704 AliHLTEventTriggerData* evtData = reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
2705 assert(evtData != NULL);
2706
2707 // Check that the CDH has 8 words.
2708 if (cdh != NULL and evtData->fCommonHeaderWordCnt != 8)
2709 {
2710 if (printErrors)
2711 {
2712 AliHLTLogging log;
2713 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2714 "Common Data Header (CDH) has wrong number of data words: %d but expected %d",
2715 evtData->fCommonHeaderWordCnt, sizeof(AliRawDataHeader)/sizeof(AliHLTUInt32_t)
2716 );
2717 }
2718 return -EBADMSG;
2719 }
2720
2721 // Check that the readout list has the correct count of words. i.e. something we can handle,
2722 if (readoutlist != NULL and
2723 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV0 and
2724 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV1
2725 )
2726 {
2727 if (printErrors)
2728 {
2729 AliHLTLogging log;
2730 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2731 "Readout list structure has wrong number of data words: %d but expected %d",
2732 evtData->fReadoutList.fCount, gkAliHLTDDLListSize
2733 );
2734 }
2735 return -EPROTO;
2736 }
2737
2738 if (attributes != NULL)
2739 {
2740 *attributes = &evtData->fAttributes;
2741 }
2742 if (status != NULL)
2743 {
2744 *status = evtData->fHLTStatus;
2745 }
2746 if (cdh != NULL)
2747 {
24451d1f 2748 const AliRawDataHeader* cdhptr = reinterpret_cast<const AliRawDataHeader*>(&evtData->fCommonHeader[0]);
89413559 2749 *cdh = cdhptr;
2750 }
2751 if (readoutlist != NULL)
2752 {
2753 *readoutlist = AliHLTReadoutList(evtData->fReadoutList);
2754 }
2755 return 0;
2756}
2757
9e14734f 2758AliHLTUInt32_t AliHLTComponent::ExtractEventTypeFromCDH(const AliRawDataHeader* cdh)
2759{
2760 // see header file for function documentation
2761
2762 UChar_t l1msg = cdh->GetL1TriggerMessage();
2763 if ((l1msg & 0x1) == 0x0) return gkAliEventTypeData;
2764 // The L2SwC bit must be one if we got here, i.e. l1msg & 0x1 == 0x1.
2765 if (((l1msg >> 2) & 0xF) == 0xE) return gkAliEventTypeStartOfRun;
2766 if (((l1msg >> 2) & 0xF) == 0xF) return gkAliEventTypeEndOfRun;
2767 // Check the C1T bit to see if this is a calibration event,
2768 // if not then it must be some other software trigger event.
2769 if (((l1msg >> 6) & 0x1) == 0x1) return gkAliEventTypeCalibration;
2770 return gkAliEventTypeSoftware;
2771}
2772
97d2b87a 2773int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2774 const char* originClass, const char* originFunc,
2775 const char* file, int line, ... ) const
2776{
2777 // see header file for function documentation
2778 int iResult=0;
2779
2780 va_list args;
2781 va_start(args, line);
2782
2783 // logging function needs to be const in order to be called from const member functions
2784 // without problems. But at this point we face the problem with virtual members which
2785 // are not necessarily const.
2786 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
7efb6418 2787 AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
97d2b87a 2788 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
7efb6418 2789 nonconst->GetComponentID());
97d2b87a 2790 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2791 va_end(args);
2792
2793 return iResult;
2794}
cf9cf07e 2795
cc095616 2796TUUID AliHLTComponent::GenerateGUID()
2797{
2798 // Generates a globally unique identifier.
2799
2800 // Start by creating a new UUID. We cannot use the one automatically generated
2801 // by ROOT because the algorithm used will not guarantee unique IDs when generating
2802 // these UUIDs at a high rate in parallel.
2803 TUUID uuid;
2804 // We then use the generated UUID to form part of the random number seeds which
2805 // will be used to generate a proper random UUID. For good measure we use a MD5
2806 // hash also. Note that we want to use the TUUID class because it will combine the
2807 // host address information into the UUID. Using gSystem->GetHostByName() apparently
2808 // can cause problems on Windows machines with a firewall, because it always tries
2809 // to contact a DNS. The TUUID class handles this case appropriately.
2810 union
2811 {
2812 UChar_t buf[16];
2813 UShort_t word[8];
2814 UInt_t dword[4];
2815 };
2816 uuid.GetUUID(buf);
2817 TMD5 md5;
2818 md5.Update(buf, sizeof(buf));
2819 TMD5 md52 = md5;
2820 md5.Final(buf);
2821 dword[0] += gSystem->GetUid();
2822 dword[1] += gSystem->GetGid();
2823 dword[2] += gSystem->GetPid();
2824 for (int i = 0; i < 4; ++i)
2825 {
2826 gRandom->SetSeed(dword[i]);
2827 dword[i] = gRandom->Integer(0xFFFFFFFF);
2828 }
2829 md52.Update(buf, sizeof(buf));
2830 md52.Final(buf);
2831 // To keep to the standard we need to set the version and reserved bits.
2832 word[3] = (word[3] & 0x0FFF) | 0x4000;
2833 buf[8] = (buf[8] & 0x3F) | 0x80;
2834
2835 // Create the name of the new class and file.
2836 char uuidstr[64];
2837 sprintf(uuidstr, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2838 dword[0], word[2], word[3], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]
2839 );
2840
2841 uuid.SetUUID(uuidstr);
2842 return uuid;
2843}
2844
cf9cf07e 2845int AliHLTComponent::ScanECSParam(const char* ecsParam)
2846{
2847 // see header file for function documentation
2848
2849 // format of the parameter string from ECS
2850 // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
2851 // search for a subset of the parameterkeys
c4ffab2c 2852 // RUN_TYPE=
2853 // RUN_NUMBER=
2854 // HLT_IN_DDL_LIST=
2855 // CTP_TRIGGER_CLASS=
2856 // DATA_FORMAT_VERSION=
2857 // BEAM_TYPE=
2858 // HLT_OUT_DDL_LIST=
2859 // HLT_TRIGGER_CODE=
2860 // DETECTOR_LIST=
2861 // HLT_MODE=
2862 // The command apears not to be sent by the online framework
cf9cf07e 2863 int iResult=0;
2864 TString string=ecsParam;
2865 TObjArray* parameter=string.Tokenize(";");
2866 if (parameter) {
77fd699f 2867 for (int i=0; i<parameter->GetEntriesFast(); i++) {
704972af 2868 TString entry=parameter->At(i)->GetName();
cf9cf07e 2869 HLTDebug("scanning ECS entry: %s", entry.Data());
2870 TObjArray* entryParams=entry.Tokenize("=");
2871 if (entryParams) {
77fd699f 2872 if (entryParams->GetEntriesFast()>1) {
cf9cf07e 2873 if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
704972af 2874 int result=InitCTPTriggerClasses(entryParams->At(1)->GetName());
cf9cf07e 2875 if (iResult>=0 && result<0) iResult=result;
2876 } else {
2877 // TODO: scan the other parameters
2878 // e.g. consistency check of run number
2879 }
2880 }
2881 delete entryParams;
2882 }
2883 }
2884 delete parameter;
2885 }
2886
2887 return iResult;
2888}
2889
adb91bc3 2890int AliHLTComponent::SetupCTPData()
cf9cf07e 2891{
2892 // see header file for function documentation
adb91bc3 2893 if (fpCTPData) delete fpCTPData;
2894 fpCTPData=new AliHLTCTPData;
2895 if (!fpCTPData) return -ENOMEM;
cf9cf07e 2896 return 0;
2897}
2898
adb91bc3 2899int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
cf9cf07e 2900{
2901 // see header file for function documentation
adb91bc3 2902 if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
2903 return fpCTPData->InitCTPTriggerClasses(ctpString);
2904}
cf9cf07e 2905
adb91bc3 2906bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
2907{
2908 // see header file for function documentation
2909 if (!fpCTPData) {
2910 static bool bWarningThrown=false;
2911 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2912 bWarningThrown=true;
cf9cf07e 2913 return false;
2914 }
2915
adb91bc3 2916 return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
cf9cf07e 2917}
a5e775ec 2918
3fcb48b8 2919int AliHLTComponent::CheckCTPTrigger(const char* name) const
2920{
2921 // see header file for function documentation
2922 if (!fpCTPData) {
2923 static bool bWarningThrown=false;
2924 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2925 bWarningThrown=true;
2926 return false;
2927 }
2928
2929 return fpCTPData->CheckTrigger(name);
2930}
2931
a5e775ec 2932Double_t AliHLTComponent::GetBz()
2933{
2934 // Returns Bz.
2935 return AliHLTMisc::Instance().GetBz();
2936}
2937
2938Double_t AliHLTComponent::GetBz(const Double_t *r)
2939{
2940 // Returns Bz (kG) at the point "r" .
2941 return AliHLTMisc::Instance().GetBz(r);
2942}
2943
2944void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
2945{
2946 // Returns Bx, By and Bz (kG) at the point "r" .
2947 AliHLTMisc::Instance().GetBxByBz(r, b);
2948}