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