handling of multiple forwarded data blocks; some code documentation
[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"
79c114b5 39#include "AliHLTMemoryFile.h"
579d9eb7 40#include "AliHLTMisc.h"
ec25e4ca 41#include <cassert>
f23a6e1a 42
b22e91eb 43/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 44ClassImp(AliHLTComponent);
45
46/** stopwatch macro using the stopwatch guard */
47#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
48//#define ALIHLTCOMPONENT_STOPWATCH(type)
49
50/** stopwatch macro for operations of the base class */
51#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
52/** stopwatch macro for operations of the detector algorithm (DA) */
53#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 54
f23a6e1a 55AliHLTComponent::AliHLTComponent()
85869391 56 :
53feaef5 57 fEnvironment(),
3cde846d 58 fCurrentEvent(0),
a655eae3 59 fEventCount(-1),
60 fFailedEvents(0),
61 fCurrentEventData(),
62 fpInputBlocks(NULL),
63 fCurrentInputBlock(-1),
64 fSearchDataType(kAliHLTVoidDataType),
65 fClassName(),
66 fpInputObjects(NULL),
67 fpOutputBuffer(NULL),
68 fOutputBufferSize(0),
69 fOutputBufferFilled(0),
90ebac25 70 fOutputBlocks(),
79c114b5 71 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 72 fMemFiles(),
73 fpRunDesc(NULL),
579d9eb7 74 fpDDLList(NULL),
82c58a87 75 fCDBSetRunNoFunc(false),
a0aeb701 76 fChainId(),
48abe484 77 fChainIdCrc(0),
a0aeb701 78 fpBenchmark(NULL),
48abe484 79 fRequireSteeringBlocks(false),
80 fEventType(gkAliEventTypeUnknown)
70ed7d01 81{
82 // see header file for class documentation
83 // or
84 // refer to README to build package
85 // or
86 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
a3c9b745 87 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
70ed7d01 88 if (fgpComponentHandler)
89 fgpComponentHandler->ScheduleRegister(this);
7c781d33 90 //SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 91}
92
f23a6e1a 93AliHLTComponent::~AliHLTComponent()
94{
70ed7d01 95 // see header file for function documentation
a0aeb701 96 if (fpBenchmark) delete fpBenchmark;
97 fpBenchmark=NULL;
98
8451168b 99 CleanupInputObjects();
4498d7d1 100 if (fpStopwatches!=NULL) delete fpStopwatches;
101 fpStopwatches=NULL;
2be3f004 102 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 103 while (element!=fMemFiles.end()) {
104 if (*element) {
105 if ((*element)->IsClosed()==0) {
106 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
107 // close but do not flush as we dont know whether the buffer is still valid
29312178 108 (*element)->CloseMemoryFile(0);
79c114b5 109 }
110 delete *element;
111 *element=NULL;
112 }
113 element++;
114 }
45c0a780 115 if (fpRunDesc) {
116 delete fpRunDesc;
117 fpRunDesc=NULL;
118 }
f23a6e1a 119}
120
70ed7d01 121AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 122
85869391 123int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
124{
70ed7d01 125 // see header file for function documentation
85869391 126 int iResult=0;
70ed7d01 127 if (fgpComponentHandler==NULL || bOverwrite!=0)
128 fgpComponentHandler=pCH;
85869391 129 else
130 iResult=-EPERM;
131 return iResult;
132}
133
70ed7d01 134int AliHLTComponent::UnsetGlobalComponentHandler()
135{
136 // see header file for function documentation
85869391 137 return SetGlobalComponentHandler(NULL,1);
138}
139
a3c9b745 140int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
f23a6e1a 141{
70ed7d01 142 // see header file for function documentation
b2065764 143 HLTLogKeyword(GetComponentID());
f23a6e1a 144 int iResult=0;
f7561f8d 145 if (comenv) {
a3c9b745 146 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
147 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
148 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
70ed7d01 149 fEnvironment.fParam=environParam;
f23a6e1a 150 }
8451168b 151 const char** pArguments=NULL;
152 int iNofChildArgs=0;
153 TString argument="";
154 int bMissingParam=0;
155 if (argc>0) {
156 pArguments=new const char*[argc];
157 if (pArguments) {
158 for (int i=0; i<argc && iResult>=0; i++) {
159 argument=argv[i];
160 if (argument.IsNull()) continue;
161
162 // benchmark
163 if (argument.CompareTo("benchmark")==0) {
164
165 // loglevel
166 } else if (argument.CompareTo("loglevel")==0) {
167 if ((bMissingParam=(++i>=argc))) break;
168 TString parameter(argv[i]);
169 parameter.Remove(TString::kLeading, ' '); // remove all blanks
170 if (parameter.BeginsWith("0x") &&
171 parameter.Replace(0,2,"",0).IsHex()) {
172 AliHLTComponentLogSeverity loglevel=kHLTLogNone;
7a5ccd96 173 sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel);
8451168b 174 SetLocalLoggingLevel(loglevel);
175 } else {
176 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
177 iResult=-EINVAL;
178 }
179 } else {
180 pArguments[iNofChildArgs++]=argv[i];
181 }
182 }
183 } else {
184 iResult=-ENOMEM;
185 }
186 }
187 if (bMissingParam) {
188 HLTError("missing parameter for argument %s", argument.Data());
189 iResult=-EINVAL;
190 }
191 if (iResult>=0) {
192 iResult=DoInit(iNofChildArgs, pArguments);
193 }
a0aeb701 194 if (iResult>=0) {
195 fEventCount=0;
196
197 // find out if the component wants to get the steering events
198 // explicitly
199 AliHLTComponentDataTypeList inputDt;
200 GetInputDataTypes(inputDt);
201 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
202 dt!=inputDt.end() && !fRequireSteeringBlocks;
203 dt++) {
204 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
205 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
206 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
207 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
208 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
209 }
210 }
8451168b 211 if (pArguments) delete [] pArguments;
a0aeb701 212
213#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
214 // benchmarking stopwatch for the component statistics
215 fpBenchmark=new TStopwatch;
216 if (fpBenchmark) {
217 fpBenchmark->Start();
218 }
219#endif
220
f23a6e1a 221 return iResult;
222}
223
224int AliHLTComponent::Deinit()
225{
70ed7d01 226 // see header file for function documentation
b2065764 227 HLTLogKeyword(GetComponentID());
f23a6e1a 228 int iResult=0;
229 iResult=DoDeinit();
559631d5 230 if (fpRunDesc) {
231 HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
232 AliHLTRunDesc* pRunDesc=fpRunDesc;
233 fpRunDesc=NULL;
234 delete pRunDesc;
235 }
579d9eb7 236 fEventCount=0;
f23a6e1a 237 return iResult;
238}
fa2e9b7c 239
82c58a87 240int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
53feaef5 241{
82c58a87 242 // see header file for function documentation
579d9eb7 243 int iResult=0;
703bcca6 244 if (pHandler) {
82c58a87 245 // I have to think about separating the library handling from the
246 // component handler. Requiring the component hanlder here is not
247 // the cleanest solution.
248 // We presume the library already to be loaded
579d9eb7 249 // find the symbol
82c58a87 250 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
579d9eb7 251 if (pFunc) {
703bcca6 252 TString path;
253 if (cdbPath && cdbPath[0]!=0) {
254 path=cdbPath;
255 // very temporary fix, have to check for other formats
256 if (!path.BeginsWith("local://")) {
257 path="local://";
258 path+=cdbPath;
259 }
8f30c1ea 260 }
261 if ((iResult=(*pFunc)(path.Data()))>=0) {
82c58a87 262 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
263 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
264 "can not find function to set CDB run no");
265 }
266 }
579d9eb7 267 } else {
268 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
269 "can not find initialization function");
270 iResult=-ENOSYS;
53feaef5 271 }
82c58a87 272 } else {
273 iResult=-EINVAL;
274 }
579d9eb7 275 return iResult;
276}
277
278int AliHLTComponent::SetCDBRunNo(int runNo)
279{
82c58a87 280 // see header file for function documentation
281 if (!fCDBSetRunNoFunc) return 0;
282 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
579d9eb7 283}
284
45c0a780 285int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
286{
287 // see header file for function documentation
288 if (!desc) return -EINVAL;
289 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
290 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
291 return -EINVAL;
292 }
293
294 if (!fpRunDesc) {
295 fpRunDesc=new AliHLTRunDesc;
296 if (!fpRunDesc) return -ENOMEM;
297 *fpRunDesc=kAliHLTVoidRunDesc;
298 }
299
300 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
301 HLTWarning("Run description has already been set");
302 }
303 *fpRunDesc=*desc;
304 SetCDBRunNo(fpRunDesc->fRunNo);
305 // TODO: we have to decide about the runType
306 return 0;
307}
308
9a0ef890 309int AliHLTComponent::SetComponentDescription(const char* desc)
310{
48abe484 311 // see header file for function documentation
9a0ef890 312 int iResult=0;
313 if (!desc) return 0;
314
315 TString descriptor=desc;
316 TObjArray* pTokens=descriptor.Tokenize(" ");
317 if (pTokens) {
318 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
319 TString argument=((TObjString*)pTokens->At(i++))->GetString();
320 if (!argument || argument.IsNull()) continue;
321
a3c9b745 322 // chainid
323 if (argument.BeginsWith("chainid")) {
324 argument.ReplaceAll("chainid", "");
9a0ef890 325 if (argument.BeginsWith("=")) {
326 fChainId=argument.Replace(0,1,"");
48abe484 327 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
328 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
9a0ef890 329 } else {
330 fChainId="";
331 }
332 } else {
48abe484 333 HLTWarning("unknown component description %s", argument.Data());
9a0ef890 334 }
335 }
336 }
337
338 return iResult;
339}
340
579d9eb7 341int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
342{
343 // default implementation, childs can overload
b543e186 344 HLTLogKeyword("dummy");
53feaef5 345 return 0;
346}
347
348int AliHLTComponent::DoDeinit()
349{
579d9eb7 350 // default implementation, childs can overload
b543e186 351 HLTLogKeyword("dummy");
579d9eb7 352 return 0;
353}
354
355int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
356{
357 // default implementation, childs can overload
b543e186 358 HLTLogKeyword("dummy");
359 return 0;
360}
361
362int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
363{
364 // default implementation, childs can overload
365 HLTLogKeyword("dummy");
53feaef5 366 return 0;
367}
368
45c0a780 369int AliHLTComponent::StartOfRun()
370{
371 // default implementation, childs can overload
372 HLTLogKeyword("dummy");
373 return 0;
374}
375
376int AliHLTComponent::EndOfRun()
377{
378 // default implementation, childs can overload
379 HLTLogKeyword("dummy");
380 return 0;
381}
382
383
2be3f004 384int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
de6593d0 385{
82c58a87 386 // default implementation, childs can overload
3a7c0444 387 HLTLogKeyword("dummy");
de6593d0 388 return 0;
389}
390
70ed7d01 391void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
392{
393 // see header file for function documentation
9ce4bf4a 394 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
395 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
396 strcat( output, ":" );
397 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 398}
399
fbdb63fd 400string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
9ce4bf4a 401{
70ed7d01 402 // see header file for function documentation
9ce4bf4a 403 string out("");
fbdb63fd 404
405 if (mode==2) {
406 int i=0;
407 char tmp[8];
408 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
409 sprintf(tmp, "'%d", type.fOrigin[i]);
410 out+=tmp;
411 }
412 out+="':'";
413 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
414 sprintf(tmp, "%d'", type.fID[i]);
415 out+=tmp;
416 }
417 return out;
418 }
419
420 if (mode==1) {
421 int i=0;
422 char tmp[8];
423 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
424 unsigned char* puc=(unsigned char*)type.fOrigin;
425 if ((puc[i])<32)
426 sprintf(tmp, "'\\%x", type.fOrigin[i]);
427 else
428 sprintf(tmp, "'%c", type.fOrigin[i]);
429 out+=tmp;
430 }
431 out+="':'";
432 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
433 unsigned char* puc=(unsigned char*)type.fID;
434 if (puc[i]<32)
435 sprintf(tmp, "\\%x'", type.fID[i]);
436 else
437 sprintf(tmp, "%c'", type.fID[i]);
438 out+=tmp;
439 }
440 return out;
441 }
442
9ce4bf4a 443 if (type==kAliHLTVoidDataType) {
444 out="VOID:VOID";
445 } else {
3cde846d 446 // some gymnastics in order to avoid a '0' which is part of either or both
447 // ID and origin terminating the whole string. Unfortunately, string doesn't
448 // stop appending at the '0' if the number of elements to append was
449 // explicitely specified
450 string tmp("");
451 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
452 out.append(tmp.c_str());
9ce4bf4a 453 out.append(":");
3cde846d 454 tmp="";
455 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
456 out.append(tmp.c_str());
9ce4bf4a 457 }
458 return out;
459}
460
461
70ed7d01 462void* AliHLTComponent::AllocMemory( unsigned long size )
463{
464 // see header file for function documentation
85869391 465 if (fEnvironment.fAllocMemoryFunc)
466 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 467 HLTFatal("no memory allocation handler registered");
85869391 468 return NULL;
469}
470
2be3f004 471int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 472 AliHLTComponentBlockData** outputBlocks )
473{
474 // see header file for function documentation
9ce4bf4a 475 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 476 return -EFAULT;
fa2e9b7c 477 AliHLTUInt32_t count = blocks.size();
478 if ( !count )
479 {
480 *blockCount = 0;
481 *outputBlocks = NULL;
482 return 0;
483 }
8ede8717 484 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 485 if ( !*outputBlocks )
2d7ff710 486 return -ENOMEM;
ca8524df 487 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 488 (*outputBlocks)[i] = blocks[i];
732e8f50 489 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
5f5b708b 490 (*outputBlocks)[i].fDataType=GetOutputDataType();
491 /* data type was set to the output data type by the PubSub AliRoot
492 Wrapper component, if data type of the block was ********:****.
493 Now handled by the component base class in order to have same
494 behavior when running embedded in AliRoot
ca8524df 495 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
496 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 497 */
ca8524df 498 }
499 }
fa2e9b7c 500 *blockCount = count;
501 return 0;
502
503}
0c0c9d99 504
70ed7d01 505int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd )
506{
507 // see header file for function documentation
85869391 508 if (fEnvironment.fGetEventDoneDataFunc)
509 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
510 return -ENOSYS;
511}
512
2be3f004 513int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
0c0c9d99 514{
70ed7d01 515 // see header file for function documentation
0c0c9d99 516 int iResult=0;
517 if (pConsumer) {
8a106878 518 AliHLTComponentDataTypeList itypes;
519 AliHLTComponentDataTypeList otypes;
520 otypes.push_back(GetOutputDataType());
521 if (otypes[0]==kAliHLTMultipleDataType) {
522 otypes.clear();
523 int count=0;
524 if ((count=GetOutputDataTypes(otypes))>0) {
525 } else if (GetComponentType()!=kSink) {
526 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
527 }
528 }
529 ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
48abe484 530 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
531 for (;otype!=otypes.end();otype++) {
532 //PrintDataTypeContent((*otype), "publisher \'%s\'");
533 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
534 if (tgtList) tgtList->push_back(*otype);
535 iResult++;
536 continue;
537 }
538
539 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
540 for (;itype!=itypes.end() && (*itype)!=(*otype); itype++);
541 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
542 if (itype!=itypes.end()) {
543 if (tgtList) tgtList->push_back(*otype);
0c0c9d99 544 iResult++;
0c0c9d99 545 }
0c0c9d99 546 }
547 } else {
548 iResult=-EINVAL;
549 }
550 return iResult;
551}
2d7ff710 552
8b97f4f1 553void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
5f5b708b 554{
66043029 555 // see header file for function documentation
8b97f4f1 556 const char* fmt="\'%s\'";
5f5b708b 557 if (format) fmt=format;
8b97f4f1 558 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
559 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
560 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
561 dt.fID[0],
562 dt.fID[1],
563 dt.fID[2],
564 dt.fID[3],
565 dt.fID[4],
566 dt.fID[5],
567 dt.fID[6],
568 dt.fID[7],
569 dt.fOrigin[0],
570 dt.fOrigin[1],
571 dt.fOrigin[2],
572 dt.fOrigin[3]));
5f5b708b 573}
574
fbdb63fd 575void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
70ed7d01 576{
577 // see header file for function documentation
2d7ff710 578 blockData.fStructSize = sizeof(blockData);
579 FillShmData( blockData.fShmKey );
580 blockData.fOffset = ~(AliHLTUInt32_t)0;
581 blockData.fPtr = NULL;
582 blockData.fSize = 0;
583 FillDataType( blockData.fDataType );
a655eae3 584 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 585}
586
fbdb63fd 587void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
70ed7d01 588{
589 // see header file for function documentation
2d7ff710 590 shmData.fStructSize = sizeof(shmData);
591 shmData.fShmType = gkAliHLTComponentInvalidShmType;
592 shmData.fShmID = gkAliHLTComponentInvalidShmID;
593}
594
fbdb63fd 595void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
70ed7d01 596{
597 // see header file for function documentation
ca8524df 598 dataType=kAliHLTAnyDataType;
2d7ff710 599}
600
70ed7d01 601void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
602{
603 // see header file for function documentation
2d7ff710 604 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
605 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
606}
607
70ed7d01 608void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
609{
610 // see header file for function documentation
7e3efc8f 611 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
612 if (id) {
613 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
d76bc02a 614 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
7e3efc8f 615 }
616 if (origin) {
617 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
d76bc02a 618 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
7e3efc8f 619 }
2d7ff710 620}
9ce4bf4a 621
18b56222 622void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
623{
624 // see header file for function documentation
625 dt.fStructSize=sizeof(AliHLTComponentDataType);
626 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
627 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
628 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
629 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
630}
631
9ce4bf4a 632void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
633{
70ed7d01 634 // see header file for function documentation
9ce4bf4a 635 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
636 evtData.fStructSize=sizeof(AliHLTComponentEventData);
48abe484 637 evtData.fEventID=kAliHLTVoidEventID;
9ce4bf4a 638}
639
70ed7d01 640void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
641{
642 // see header file for function documentation
9ce4bf4a 643 TString msg;
644 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
645 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
646 if (dt.fID[i]!=0) msg+=dt.fID[i];
647 else msg+="\\0";
648 }
649 msg+="\" Origin=\"";
650 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
651 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
652 else msg+="\\0";
653 }
654 msg+="\"";
3cde846d 655 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 656}
657
70ed7d01 658int AliHLTComponent::GetEventCount() const
3cde846d 659{
70ed7d01 660 // see header file for function documentation
3cde846d 661 return fEventCount;
662}
663
664int AliHLTComponent::IncrementEventCounter()
665{
70ed7d01 666 // see header file for function documentation
3cde846d 667 if (fEventCount>=0) fEventCount++;
668 return fEventCount;
669}
670
66043029 671int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 672{
673 // see header file for function documentation
674 if (fpInputBlocks!=NULL) {
675 return fCurrentEventData.fBlockCnt;
676 }
677 return 0;
678}
679
680const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
681 const char* classname,
682 int bForce)
683{
684 // see header file for function documentation
90ebac25 685 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 686 fSearchDataType=dt;
687 if (classname) fClassName=classname;
688 else fClassName.clear();
1edbbe49 689 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 690 TObject* pObj=NULL;
691 if (idx>=0) {
79c114b5 692 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 693 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
694 fCurrentInputBlock=idx;
695 } else {
696 }
697 }
698 return pObj;
699}
700
701const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
702 const char* dtOrigin,
703 const char* classname,
704 int bForce)
705{
706 // see header file for function documentation
90ebac25 707 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 708 AliHLTComponentDataType dt;
709 SetDataType(dt, dtID, dtOrigin);
710 return GetFirstInputObject(dt, classname, bForce);
711}
712
713const TObject* AliHLTComponent::GetNextInputObject(int bForce)
714{
715 // see header file for function documentation
90ebac25 716 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 717 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 718 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
719 TObject* pObj=NULL;
720 if (idx>=0) {
721 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
722 fCurrentInputBlock=idx;
723 }
724 }
725 return pObj;
726}
727
1edbbe49 728int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 729{
730 // see header file for function documentation
731 int iResult=-ENOENT;
732 if (fpInputBlocks!=NULL) {
733 int idx=startIdx<0?0:startIdx;
4b98eadb 734 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 735 if (dt!=fpInputBlocks[idx].fDataType) continue;
736
1edbbe49 737 if (bObject!=0) {
738 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 739 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
740 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 741 }
3dd8541e 742 iResult=idx;
a655eae3 743 }
744 }
745 return iResult;
746}
747
748TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
749{
750 // see header file for function documentation
751 TObject* pObj=NULL;
752 if (fpInputBlocks!=NULL) {
4b98eadb 753 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 754 if (fpInputBlocks[idx].fPtr) {
3294f81a 755 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 756 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 757 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 758 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 759 TClass* objclass=msg.GetClass();
760 pObj=msg.ReadObject(objclass);
761 if (pObj && objclass) {
762 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 763 } else {
764 }
1edbbe49 765 //} else {
766 } else if (bForce!=0) {
c5123824 767 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 768 }
769 } else {
770 HLTFatal("block descriptor empty");
771 }
772 } else {
773 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
774 }
775 } else {
776 HLTError("no input blocks available");
777 }
778
779 return pObj;
780}
781
298ef463 782TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 783{
784 // see header file for function documentation
785 if (fpInputObjects==NULL) {
786 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
787 }
788 TObject* pObj=NULL;
789 if (fpInputObjects) {
790 pObj=fpInputObjects->At(idx);
791 if (pObj==NULL) {
792 pObj=CreateInputObject(idx, bForce);
793 if (pObj) {
794 fpInputObjects->AddAt(pObj, idx);
795 }
796 }
797 } else {
798 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
799 }
800 return pObj;
801}
802
8451168b 803int AliHLTComponent::CleanupInputObjects()
804{
66043029 805 // see header file for function documentation
8451168b 806 if (!fpInputObjects) return 0;
807 TObjArray* array=fpInputObjects;
808 fpInputObjects=NULL;
809 for (int i=0; i<array->GetEntries(); i++) {
810 TObject* pObj=array->At(i);
79c114b5 811 // grrr, garbage collection strikes back: When read via AliHLTMessage
812 // (CreateInputObject), and written to a TFile afterwards, the
813 // TFile::Close calls ROOOT's garbage collection. No clue why the
814 // object ended up in the key list and needs to be deleted
815 if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
8451168b 816 }
817 delete array;
90ebac25 818 return 0;
8451168b 819}
820
a655eae3 821AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
822{
823 // see header file for function documentation
90ebac25 824 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 825 AliHLTComponentDataType dt=kAliHLTVoidDataType;
826 int idx=fCurrentInputBlock;
827 if (pObject) {
828 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
829 } else {
830 HLTError("unknown object %p", pObject);
831 }
832 }
833 if (idx>=0) {
4b98eadb 834 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 835 dt=fpInputBlocks[idx].fDataType;
836 } else {
837 HLTFatal("severe internal error, index out of range");
838 }
839 }
840 return dt;
841}
842
843AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
844{
845 // see header file for function documentation
90ebac25 846 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 847 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
848 int idx=fCurrentInputBlock;
849 if (pObject) {
850 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
851 } else {
852 HLTError("unknown object %p", pObject);
853 }
854 }
855 if (idx>=0) {
4b98eadb 856 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 857 iSpec=fpInputBlocks[idx].fSpecification;
858 } else {
859 HLTFatal("severe internal error, index out of range");
860 }
861 }
862 return iSpec;
863}
864
c7e9e2f2 865int AliHLTComponent::Forward(const TObject* pObject)
866{
867 // see header file for function documentation
868 int iResult=0;
869 int idx=fCurrentInputBlock;
870 if (pObject) {
871 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
872 } else {
873 HLTError("unknown object %p", pObject);
874 iResult=-ENOENT;
875 }
876 }
877 if (idx>=0) {
878 fOutputBlocks.push_back(fpInputBlocks[idx]);
879 }
880 return iResult;
881}
882
883int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
884{
885 // see header file for function documentation
886 int iResult=0;
887 int idx=fCurrentInputBlock;
888 if (pBlock) {
889 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
890 } else {
891 HLTError("unknown Block %p", pBlock);
892 iResult=-ENOENT;
893 }
894 }
895 if (idx>=0) {
896 // check for fpInputBlocks pointer done in FindInputBlock
897 fOutputBlocks.push_back(fpInputBlocks[idx]);
898 }
899 return iResult;
900}
901
a655eae3 902const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
903{
904 // see header file for function documentation
90ebac25 905 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 906 fSearchDataType=dt;
907 fClassName.clear();
908 int idx=FindInputBlock(fSearchDataType, 0);
909 const AliHLTComponentBlockData* pBlock=NULL;
910 if (idx>=0) {
911 // check for fpInputBlocks pointer done in FindInputBlock
912 pBlock=&fpInputBlocks[idx];
1edbbe49 913 fCurrentInputBlock=idx;
a655eae3 914 }
915 return pBlock;
916}
917
918const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
919 const char* dtOrigin)
920{
921 // see header file for function documentation
90ebac25 922 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 923 AliHLTComponentDataType dt;
924 SetDataType(dt, dtID, dtOrigin);
925 return GetFirstInputBlock(dt);
926}
927
10b9cbf9 928const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 929{
930 // see header file for function documentation
931 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 932 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 933 return &fpInputBlocks[index];
934}
935
a655eae3 936const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
937{
938 // see header file for function documentation
90ebac25 939 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 940 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
941 const AliHLTComponentBlockData* pBlock=NULL;
942 if (idx>=0) {
943 // check for fpInputBlocks pointer done in FindInputBlock
944 pBlock=&fpInputBlocks[idx];
1edbbe49 945 fCurrentInputBlock=idx;
a655eae3 946 }
947 return pBlock;
948}
949
66043029 950int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 951{
952 // see header file for function documentation
953 int iResult=-ENOENT;
954 if (fpInputBlocks!=NULL) {
955 if (pBlock) {
956 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 957 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 958 }
959 } else {
960 iResult=-EINVAL;
961 }
962 }
963 return iResult;
964}
965
966AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
967{
968 // see header file for function documentation
90ebac25 969 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 970 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
971 int idx=fCurrentInputBlock;
972 if (pBlock) {
973 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
974 } else {
975 HLTError("unknown Block %p", pBlock);
976 }
977 }
978 if (idx>=0) {
979 // check for fpInputBlocks pointer done in FindInputBlock
980 iSpec=fpInputBlocks[idx].fSpecification;
981 }
982 return iSpec;
983}
984
79c114b5 985int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
986 void* pHeader, int headerSize)
a655eae3 987{
988 // see header file for function documentation
90ebac25 989 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 990 int iResult=0;
991 if (pObject) {
992 AliHLTMessage msg(kMESS_OBJECT);
993 msg.WriteObject(pObject);
994 Int_t iMsgLength=msg.Length();
995 if (iMsgLength>0) {
996 msg.SetLength(); // sets the length to the first (reserved) word
79c114b5 997 iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 998 if (iResult>=0) {
8451168b 999 HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
a655eae3 1000 }
1001 } else {
1002 HLTError("object serialization failed for object %p", pObject);
1003 iResult=-ENOMSG;
1004 }
1005 } else {
1006 iResult=-EINVAL;
1007 }
1008 return iResult;
1009}
1010
79c114b5 1011int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1012 void* pHeader, int headerSize)
a655eae3 1013{
1014 // see header file for function documentation
90ebac25 1015 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1016 AliHLTComponentDataType dt;
1017 SetDataType(dt, dtID, dtOrigin);
79c114b5 1018 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1019}
1020
9d9ffd37 1021int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1022 void* pHeader, int headerSize)
a655eae3 1023{
1024 // see header file for function documentation
90ebac25 1025 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d9ffd37 1026 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1027}
1028
9d9ffd37 1029int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1030 void* pHeader, int headerSize)
a655eae3 1031{
1032 // see header file for function documentation
90ebac25 1033 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1034 AliHLTComponentDataType dt;
1035 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1036 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1037}
1038
79c114b5 1039int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1040 void* pHeader, int iHeaderSize)
a655eae3 1041{
1042 // see header file for function documentation
1043 int iResult=0;
79c114b5 1044 int iBlkSize = iBufferSize + iHeaderSize;
a655eae3 1045 if (pBuffer) {
79c114b5 1046 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1047 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1048 AliHLTComponentBlockData bd;
1049 FillBlockData( bd );
1050 bd.fOffset = fOutputBufferFilled;
79c114b5 1051 bd.fSize = iBlkSize;
a655eae3 1052 bd.fDataType = dt;
1053 bd.fSpecification = spec;
79c114b5 1054 if (pHeader!=NULL && pHeader!=pTgt) {
1055 memcpy(pTgt, pHeader, iHeaderSize);
1056 }
1057
1058 pTgt += (AliHLTUInt8_t) iHeaderSize;
1059
a655eae3 1060 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1061 memcpy(pTgt, pBuffer, iBufferSize);
1062
4b98eadb 1063 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1064 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1065 }
1066 fOutputBufferFilled+=bd.fSize;
1067 fOutputBlocks.push_back( bd );
79c114b5 1068 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1069 } else {
1070 if (fpOutputBuffer) {
79c114b5 1071 HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
a655eae3 1072 } else {
1073 HLTError("output buffer not available");
1074 }
1075 iResult=-ENOSPC;
1076 }
1077 } else {
1078 iResult=-EINVAL;
1079 }
1080 return iResult;
1081}
1082
8451168b 1083int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1084{
66043029 1085 // see header file for function documentation
8451168b 1086 if (!pObject) return -EINVAL;
1087 AliHLTMessage msg(kMESS_OBJECT);
1088 msg.WriteObject(pObject);
1089 return msg.Length();
1090}
1091
79c114b5 1092AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1093 const char* dtOrigin,
1094 AliHLTUInt32_t spec)
1095{
1096 // see header file for function documentation
1097 ALIHLTCOMPONENT_BASE_STOPWATCH();
1098 AliHLTComponentDataType dt;
1099 SetDataType(dt, dtID, dtOrigin);
1100 return CreateMemoryFile(capacity, dt, spec);
1101}
1102
1103AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1104 const AliHLTComponentDataType& dt,
1105 AliHLTUInt32_t spec)
1106{
1107 // see header file for function documentation
1108 ALIHLTCOMPONENT_BASE_STOPWATCH();
1109 AliHLTMemoryFile* pFile=NULL;
83fec083 1110 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1111 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1112 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1113 if (pFile) {
83fec083 1114 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1115 if (nofBlocks+1>fMemFiles.size()) {
1116 fMemFiles.resize(nofBlocks+1, NULL);
1117 }
1118 if (nofBlocks<fMemFiles.size()) {
1119 fMemFiles[nofBlocks]=pFile;
1120 AliHLTComponentBlockData bd;
1121 FillBlockData( bd );
1122 bd.fOffset = fOutputBufferFilled;
79c114b5 1123 bd.fSize = capacity;
1124 bd.fDataType = dt;
1125 bd.fSpecification = spec;
1126 fOutputBufferFilled+=bd.fSize;
1127 fOutputBlocks.push_back( bd );
1128 } else {
1129 HLTError("can not allocate/grow object array");
29312178 1130 pFile->CloseMemoryFile(0);
79c114b5 1131 delete pFile;
1132 pFile=NULL;
1133 }
1134 }
1135 } else {
1136 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1137 }
1138 return pFile;
1139}
1140
1141AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1142 const char* dtOrigin,
1143 AliHLTUInt32_t spec,
1144 float capacity)
1145{
1146 // see header file for function documentation
1147 ALIHLTCOMPONENT_BASE_STOPWATCH();
1148 AliHLTComponentDataType dt;
1149 SetDataType(dt, dtID, dtOrigin);
1150 int size=fOutputBufferSize-fOutputBufferFilled;
1151 if (capacity<0 || capacity>1.0) {
1152 HLTError("invalid parameter: capacity %f", capacity);
1153 return NULL;
1154 }
1155 size=(int)(size*capacity);
1156 return CreateMemoryFile(size, dt, spec);
1157}
1158
1159AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1160 AliHLTUInt32_t spec,
1161 float capacity)
1162{
1163 // see header file for function documentation
1164 ALIHLTCOMPONENT_BASE_STOPWATCH();
1165 int size=fOutputBufferSize-fOutputBufferFilled;
1166 if (capacity<0 || capacity>1.0) {
1167 HLTError("invalid parameter: capacity %f", capacity);
1168 return NULL;
1169 }
1170 size=(int)(size*capacity);
1171 return CreateMemoryFile(size, dt, spec);
1172}
1173
1174int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1175 const char* key, int option)
1176{
3a7c0444 1177 // see header file for function documentation
79c114b5 1178 int iResult=0;
1179 if (pFile && pObject) {
1180 pFile->cd();
1181 iResult=pObject->Write(key, option);
1182 if (iResult>0) {
1183 // success
1184 } else {
1185 iResult=-pFile->GetErrno();
1186 if (iResult==-ENOSPC) {
1187 HLTError("error writing memory file, buffer too small");
1188 }
1189 }
1190 } else {
1191 iResult=-EINVAL;
1192 }
1193 return iResult;
1194}
1195
1196int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1197{
3a7c0444 1198 // see header file for function documentation
79c114b5 1199 int iResult=0;
1200 if (pFile) {
2be3f004 1201 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1202 int i=0;
1203 while (element!=fMemFiles.end() && iResult>=0) {
1204 if (*element && *element==pFile) {
29312178 1205 iResult=pFile->CloseMemoryFile();
79c114b5 1206
1207 // sync memory files and descriptors
1208 if (iResult>=0) {
1209 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1210 }
1211 delete *element;
1212 *element=NULL;
1213 return iResult;
1214 }
1215 element++; i++;
1216 }
1217 HLTError("can not find memory file %p", pFile);
1218 iResult=-ENOENT;
1219 } else {
1220 iResult=-EINVAL;
1221 }
1222 return iResult;
1223}
1224
29312178 1225int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData /*edd*/)
a655eae3 1226{
1227 // see header file for function documentation
1228 int iResult=-ENOSYS;
1229 //#warning function not yet implemented
1230 HLTWarning("function not yet implemented");
1231 return iResult;
1232}
1233
3cde846d 1234int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1235 const AliHLTComponentBlockData* blocks,
1236 AliHLTComponentTriggerData& trigData,
1237 AliHLTUInt8_t* outputPtr,
1238 AliHLTUInt32_t& size,
1239 AliHLTUInt32_t& outputBlockCnt,
1240 AliHLTComponentBlockData*& outputBlocks,
1241 AliHLTComponentEventDoneData*& edd )
1242{
70ed7d01 1243 // see header file for function documentation
b2065764 1244 HLTLogKeyword(GetComponentID());
90ebac25 1245 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1246 int iResult=0;
1247 fCurrentEvent=evtData.fEventID;
a655eae3 1248 fCurrentEventData=evtData;
1249 fpInputBlocks=blocks;
1250 fCurrentInputBlock=-1;
1251 fSearchDataType=kAliHLTAnyDataType;
1252 fpOutputBuffer=outputPtr;
1253 fOutputBufferSize=size;
1254 fOutputBufferFilled=0;
1255 fOutputBlocks.clear();
96f9673a 1256 outputBlockCnt=0;
1257 outputBlocks=NULL;
a0aeb701 1258 AliHLTComponentStatisticsList compStats;
1259#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1260 AliHLTComponentStatistics outputStat;
1261 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
48abe484 1262 outputStat.fId=fChainIdCrc;
a0aeb701 1263 compStats.push_back(outputStat);
1264 if (fpBenchmark) {
1265 fpBenchmark->Reset();
1266 fpBenchmark->Start();
1267 }
1268#endif
559631d5 1269
48abe484 1270 // data processing is skipped
1271 // - if there are only steering events in the block list.
1272 // For the sake of data source components data processing
1273 // is not skipped if there is no block list at all or if it
1274 // just contains the eventType block
1275 // - always skipped if the event is of type
1276 // - gkAliEventTypeConfiguration
1277 // - gkAliEventTypeReadPreprocessor
45c0a780 1278 const unsigned int skipModeDefault=0x1;
1279 const unsigned int skipModeForce=0x2;
1280 unsigned int bSkipDataProcessing=skipModeDefault;
1281
559631d5 1282 // find special events
45c0a780 1283 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1284 // first look for all special events and execute in the appropriate
1285 // sequence afterwords
1286 int indexComConfEvent=-1;
b543e186 1287 int indexUpdtDCSEvent=-1;
579d9eb7 1288 int indexSOREvent=-1;
1289 int indexEOREvent=-1;
83fec083 1290 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1291 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1292 indexSOREvent=i;
45c0a780 1293 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1294 bSkipDataProcessing&=~skipModeDefault;
1295 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1296 // run type string
1297 // handling is not clear yet
1298 if (fpInputBlocks[i].fPtr) {
1299 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1300 }
579d9eb7 1301 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1302 indexEOREvent=i;
45c0a780 1303 // the calibration processor relies on the SOR and EOR events
1304 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1305 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1306 // DDL list
1307 // this event is most likely deprecated
1308 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1309 indexComConfEvent=i;
b543e186 1310 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1311 indexUpdtDCSEvent=i;
1312 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1313 fEventType=fpInputBlocks[i].fSpecification;
1314
1315 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1316 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1317
1318 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1319 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1320
1321 // never skip if the event type block is the only block
1322 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1323
a0aeb701 1324 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1325 if (compStats.size()>0) {
1326 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1327 for (AliHLTUInt32_t offset=0;
1328 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1329 offset+=sizeof(AliHLTComponentStatistics)) {
1330 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1331 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1332 compStats[0].fLevel=pStat->fLevel+1;
1333 }
1334 compStats.push_back(*pStat);
1335 }
1336 }
45c0a780 1337 } else {
1338 // the processing function is called if there is at least one
1339 // non-steering data block. Steering blocks are not filtered out
1340 // for sake of performance
1341 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1342 if (compStats.size()>0) {
1343 compStats[0].fInputBlockCount++;
1344 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1345 }
579d9eb7 1346 }
1347 }
45c0a780 1348
579d9eb7 1349 if (indexSOREvent>=0) {
1350 // start of run
1351 if (fpRunDesc==NULL) {
1352 fpRunDesc=new AliHLTRunDesc;
48abe484 1353 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1354 }
1355 if (fpRunDesc) {
1356 AliHLTRunDesc rundesc;
1357 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1358 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1359 *fpRunDesc=rundesc;
579d9eb7 1360 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1361 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1362 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1363 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1364 }
559631d5 1365 }
579d9eb7 1366 } else {
45c0a780 1367 iResult=-ENOMEM;
579d9eb7 1368 }
1369 }
1370 if (indexEOREvent>=0) {
1371 if (fpRunDesc!=NULL) {
1372 if (fpRunDesc) {
1373 AliHLTRunDesc rundesc;
1374 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1375 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1376 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1377 } else {
1378 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1379 }
559631d5 1380 }
579d9eb7 1381 AliHLTRunDesc* pRunDesc=fpRunDesc;
1382 fpRunDesc=NULL;
1383 delete pRunDesc;
559631d5 1384 }
579d9eb7 1385 } else {
1386 HLTWarning("did not receive SOR, ignoring EOR");
1387 }
1388 }
48abe484 1389 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1390 TString cdbEntry;
b543e186 1391 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1392 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1393 }
1394 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1395 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1396 if (tmpResult<0) {
1397 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1398 }
1399 }
48abe484 1400 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1401 TString modules;
1402 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1403 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1404 }
d6b69874 1405 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1406 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1407 if (tmpResult<0) {
1408 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1409 }
1410 }
45c0a780 1411 } else {
1412 // processing function needs to be called if there are no input data
1413 // blocks in order to make data source components working.
1414 bSkipDataProcessing&=~skipModeDefault;
559631d5 1415 }
a0aeb701 1416
1417 // data processing is not skipped if the component explicitly asks
1418 // for the private blocks
1419 if (fRequireSteeringBlocks) bSkipDataProcessing=0;
1420
2be3f004 1421 AliHLTComponentBlockDataList blockData;
45c0a780 1422 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1423 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1424 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1425 // in order to avoid 'shadowed variable' warning
1426 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1427 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1428 } // end of the scope of the stopwatch guard
b543e186 1429 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1430 if (fOutputBlocks.size()>0) {
df61f928 1431 // High Level interface
1432
1433 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1434 // sync memory files and descriptors
2be3f004 1435 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1436 int i=0;
1437 while (element!=fMemFiles.end() && iResult>=0) {
1438 if (*element) {
1439 if ((*element)->IsClosed()==0) {
1440 HLTWarning("memory file has not been closed, force flush");
1441 iResult=CloseMemoryFile(*element);
1442 }
1443 }
1444 element++; i++;
1445 }
1446
1447 if (iResult>=0) {
1448 // create the descriptor list
1449 if (blockData.size()>0) {
1450 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1451 iResult=-EFAULT;
1452 } else {
a0aeb701 1453 if (compStats.size()>0) {
1454 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1455 if (offset>0) fOutputBufferFilled+=offset;
1456 }
79c114b5 1457 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1458 size=fOutputBufferFilled;
1459 }
a655eae3 1460 }
1461 } else {
df61f928 1462 // Low Level interface
a0aeb701 1463 if (compStats.size()>0) {
1464 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1465 if (offset>0) size+=offset;
1466 }
a655eae3 1467 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1468 }
1469 if (iResult<0) {
1470 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1471 }
1472 }
b543e186 1473 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1474 outputBlockCnt=0;
1475 outputBlocks=NULL;
1476 }
8451168b 1477 CleanupInputObjects();
48abe484 1478 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1479 IncrementEventCounter();
1480 }
96f9673a 1481 if (outputBlockCnt==0) {
1482 // no output blocks, set size to 0
1483 size=0;
1484 }
3cde846d 1485 return iResult;
1486}
a655eae3 1487
a0aeb701 1488int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1489 AliHLTUInt8_t* buffer,
1490 AliHLTUInt32_t bufferSize,
1491 AliHLTUInt32_t offset,
1492 AliHLTComponentStatisticsList& stats) const
1493{
1494 // see header file for function documentation
1495 int iResult=0;
1496 if (stats.size()==0) return -ENOENT;
1497 stats[0].fTotalOutputSize=offset;
1498 stats[0].fOutputBlockCount=blocks.size();
1499 if (fpBenchmark) {
1500 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*1000000);
1501 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*1000000);
1502 }
1503 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1504 AliHLTComponentBlockData bd;
1505 FillBlockData( bd );
1506 bd.fOffset = offset;
1507 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1508 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1509 bd.fSpecification = kAliHLTVoidDataSpec;
1510 unsigned int master=0;
1511 for (unsigned int i=1; i<blocks.size(); i++) {
1512 if (blocks[i].fSize>blocks[master].fSize &&
1513 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1514 master=i;
1515 }
1516 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1517 // take the data origin of the biggest block as specification
1518 // this is similar to the treatment in the HOMER interface. For traditional
1519 // reasons, the bytes are swapped there on a little endian architecture, so
1520 // we do it as well.
1521 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1522#ifdef R__BYTESWAP // set on little endian architectures
1523 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1524 ((bd.fSpecification & 0xFF00ULL) << 8) |
1525 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1526 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1527#endif
1528 }
1529 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1530 blocks.push_back(bd);
1531 iResult=bd.fSize;
1532 }
1533 return iResult;
1534}
1535
90ebac25 1536AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1537 :
1538 fpStopwatch(NULL),
1539 fpPrec(NULL)
1540{
1541 // standard constructor (not for use)
1542}
1543
1544AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1545 :
1546 fpStopwatch(pStopwatch),
1547 fpPrec(NULL)
1548{
1549 // constructor
1550
1551 // check for already existing guard
1552 if (fgpCurrent) fpPrec=fgpCurrent;
1553 fgpCurrent=this;
1554
1555 // stop the preceeding guard if it controls a different stopwatch
1556 int bStart=1;
1557 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1558
1559 // start the stopwatch if the current guard controls a different one
1560 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1561}
1562
e419b223 1563AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 1564 :
1565 fpStopwatch(NULL),
1566 fpPrec(NULL)
1567{
e419b223 1568 //
1569 // copy constructor not for use
1570 //
1571}
1572
1573AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1574{
1575 //
1576 // assignment operator not for use
1577 //
1578 fpStopwatch=NULL;
1579 fpPrec=NULL;
1580 return *this;
90ebac25 1581}
1582
1583AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1584
1585AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1586{
1587 // destructor
1588
1589 // resume the preceeding guard if it controls a different stopwatch
1590 int bStop=1;
1591 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1592
1593 // stop the stopwatch if the current guard controls a different one
1594 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1595
1596 // resume to the preceeding guard
1597 fgpCurrent=fpPrec;
1598}
1599
1600int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1601{
1602 // see header file for function documentation
1603 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1604 return fpStopwatch!=pSucc?1:0;
1605}
1606
1607int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1608{
1609 // see header file for function documentation
1610 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1611 return fpStopwatch!=pSucc?1:0;
1612}
1613
1614int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
1615{
1616 // see header file for function documentation
1617 int iResult=0;
1618 if (pSW!=NULL && type<kSWTypeCount) {
1619 if (fpStopwatches) {
1620 TObject* pObj=fpStopwatches->At((int)type);
1621 if (pSW==NULL // explicit reset
1622 || pObj==NULL) { // explicit set
1623 fpStopwatches->AddAt(pSW, (int)type);
1624 } else if (pObj!=pSW) {
1625 HLTWarning("stopwatch %d already set, reset first", (int)type);
1626 iResult=-EBUSY;
1627 }
1628 }
1629 } else {
1630 iResult=-EINVAL;
1631 }
1632 return iResult;
1633}
1634
1635int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1636{
1637 // see header file for function documentation
1638 if (pStopwatches==NULL) return -EINVAL;
1639
1640 int iResult=0;
1641 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1642 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1643 return iResult;
1644}
559631d5 1645
1646AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1647{
29312178 1648 // see header file for function documentation
45c0a780 1649 if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
559631d5 1650 return fpRunDesc->fRunNo;
1651}
1652
1653AliHLTUInt32_t AliHLTComponent::GetRunType() const
1654{
29312178 1655 // see header file for function documentation
45c0a780 1656 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 1657 return fpRunDesc->fRunType;
1658}
1659
48abe484 1660bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
1661{
1662 // see header file for function documentation
1663 if (pTgt) *pTgt=fEventType;
1664 return (fEventType==gkAliEventTypeData ||
1665 fEventType==gkAliEventTypeDataReplay ||
1666 fEventType==gkAliEventTypeCalibration);
1667}
1668
83fec083 1669int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 1670 const char* structname, const char* eventname)
1671{
29312178 1672 // see header file for function documentation
559631d5 1673 int iResult=0;
1674 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1675 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1676 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1677 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 1678 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 1679 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 1680 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 1681 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1682 }
1683 if (copy!=iStructSize) {
c5123824 1684 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 1685 if (copy>iStructSize) {
1686 copy=iStructSize;
1687 } else {
1688 memset(pTgt, 0, iStructSize);
1689 }
1690 }
3294f81a 1691 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 1692 *pTgt=iStructSize;
1693 iResult=copy;
1694 } else {
1695 HLTWarning("%s event: missing data block", eventname);
1696 }
1697 } else {
1698 iResult=-ENODATA;
1699 }
1700 } else {
1701 HLTError("invalid struct");
1702 iResult=-EINVAL;
1703 }
1704 return iResult;
1705}
ed504011 1706
1707void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1708{
1709 // see header file for function documentation
1710
1711 // -- Detector offset
1712 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
1713
1714 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
1715 Int_t wordBase = 0;
1716
1717 if ( ddlIdBase <= 3 )
1718 wordBase = ddlIdBase;
1719 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1720 wordBase = ddlIdBase + 7;
1721 else
1722 wordBase = ddlIdBase + 9;
1723
1724 // -- Bit index in Word
1725 Int_t bitIdx = ddlId % 32;
1726
1727 // -- Index of word
1728 Int_t wordIdx = wordBase;
1729
1730 // -- if TPC (3) or TOD (5) add word idx
1731 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1732 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1733 }
1734
1735 // -- Set -- 'OR' word with bit mask;
1736 if ( state )
1737 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1738 // -- Unset -- 'AND' word with bit mask;
1739 else
1740 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1741}
1742
1743Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1744{
1745 // see header file for function documentation
1746
1747 Int_t iResult = -1;
1748
1749 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1750
1751 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1752 // check for special cases TPC and TOF
1753 if ( wordNdx > 3 && wordNdx <= 10 ) {
1754 wordNdx = 10;
1755 iResult = 3;
1756 }
1757 else if ( wordNdx > 12 && wordNdx <= 14 ) {
1758 wordNdx = 14;
1759 iResult = 12;
1760 }
1761 else
1762 iResult = wordNdx;
1763 }
1764 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
1765 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
1766 iResult = -1;
1767 break;
1768 }
1769 }
1770
1771 return iResult;
1772}
48abe484 1773
1774AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
1775{
1776 // see header file for function documentation
1777 AliHLTUInt32_t remainder = 0;
1778 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
1779 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
1780 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
1781
1782 // code from
1783 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
1784
1785 /*
1786 * Perform modulo-2 division, a byte at a time.
1787 */
1788 for (int byte = 0; byte < size; ++byte)
1789 {
1790 /*
1791 * Bring the next byte into the remainder.
1792 */
1793 remainder ^= (buffer[byte] << (crcwidth - 8));
1794
1795 /*
1796 * Perform modulo-2 division, a bit at a time.
1797 */
1798 for (uint8_t bit = 8; bit > 0; --bit)
1799 {
1800 /*
1801 * Try to divide the current data bit.
1802 */
1803 if (remainder & topbit)
1804 {
1805 remainder = (remainder << 1) ^ polynomial;
1806 }
1807 else
1808 {
1809 remainder = (remainder << 1);
1810 }
1811 }
1812 }
1813
1814 /*
1815 * The final remainder is the CRC result.
1816 */
1817 return (remainder);
1818}