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