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