bugfix: digit publisher was crashing due to malfunction in SOR/EOR handling
[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
438635e3 997 assert(msg.Buffer()!=NULL);
79c114b5 998 iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 999 if (iResult>=0) {
8451168b 1000 HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
a655eae3 1001 }
1002 } else {
1003 HLTError("object serialization failed for object %p", pObject);
1004 iResult=-ENOMSG;
1005 }
1006 } else {
1007 iResult=-EINVAL;
1008 }
1009 return iResult;
1010}
1011
79c114b5 1012int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1013 void* pHeader, int headerSize)
a655eae3 1014{
1015 // see header file for function documentation
90ebac25 1016 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1017 AliHLTComponentDataType dt;
1018 SetDataType(dt, dtID, dtOrigin);
79c114b5 1019 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1020}
1021
438635e3 1022int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1023 const void* pHeader, int headerSize)
a655eae3 1024{
1025 // see header file for function documentation
90ebac25 1026 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d9ffd37 1027 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1028}
1029
438635e3 1030int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1031 const void* pHeader, int headerSize)
a655eae3 1032{
1033 // see header file for function documentation
90ebac25 1034 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1035 AliHLTComponentDataType dt;
1036 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1037 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1038}
1039
438635e3 1040int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1041 const void* pHeader, int iHeaderSize)
a655eae3 1042{
1043 // see header file for function documentation
1044 int iResult=0;
79c114b5 1045 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1046
1047 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1048 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1049 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1050
1051 // copy header if provided but skip if the header is the target location
1052 // in that case it has already been copied
79c114b5 1053 if (pHeader!=NULL && pHeader!=pTgt) {
1054 memcpy(pTgt, pHeader, iHeaderSize);
1055 }
1056
1057 pTgt += (AliHLTUInt8_t) iHeaderSize;
1058
438635e3 1059 // copy buffer if provided but skip if buffer is the target location
1060 // in that case it has already been copied
a655eae3 1061 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1062 memcpy(pTgt, pBuffer, iBufferSize);
1063
4b98eadb 1064 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1065 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1066 }
79c114b5 1067 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1068 } else {
1069 if (fpOutputBuffer) {
79c114b5 1070 HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
a655eae3 1071 } else {
1072 HLTError("output buffer not available");
1073 }
1074 iResult=-ENOSPC;
1075 }
a655eae3 1076 }
438635e3 1077 if (iResult>=0) {
1078 AliHLTComponentBlockData bd;
1079 FillBlockData( bd );
1080 bd.fOffset = fOutputBufferFilled;
1081 bd.fSize = iBlkSize;
1082 bd.fDataType = dt;
1083 bd.fSpecification = spec;
1084 fOutputBlocks.push_back( bd );
1085 fOutputBufferFilled+=bd.fSize;
1086 }
1087
a655eae3 1088 return iResult;
1089}
1090
8451168b 1091int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1092{
66043029 1093 // see header file for function documentation
8451168b 1094 if (!pObject) return -EINVAL;
1095 AliHLTMessage msg(kMESS_OBJECT);
1096 msg.WriteObject(pObject);
1097 return msg.Length();
1098}
1099
79c114b5 1100AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1101 const char* dtOrigin,
1102 AliHLTUInt32_t spec)
1103{
1104 // see header file for function documentation
1105 ALIHLTCOMPONENT_BASE_STOPWATCH();
1106 AliHLTComponentDataType dt;
1107 SetDataType(dt, dtID, dtOrigin);
1108 return CreateMemoryFile(capacity, dt, spec);
1109}
1110
1111AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1112 const AliHLTComponentDataType& dt,
1113 AliHLTUInt32_t spec)
1114{
1115 // see header file for function documentation
1116 ALIHLTCOMPONENT_BASE_STOPWATCH();
1117 AliHLTMemoryFile* pFile=NULL;
83fec083 1118 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1119 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1120 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1121 if (pFile) {
83fec083 1122 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1123 if (nofBlocks+1>fMemFiles.size()) {
1124 fMemFiles.resize(nofBlocks+1, NULL);
1125 }
1126 if (nofBlocks<fMemFiles.size()) {
1127 fMemFiles[nofBlocks]=pFile;
1128 AliHLTComponentBlockData bd;
1129 FillBlockData( bd );
1130 bd.fOffset = fOutputBufferFilled;
79c114b5 1131 bd.fSize = capacity;
1132 bd.fDataType = dt;
1133 bd.fSpecification = spec;
1134 fOutputBufferFilled+=bd.fSize;
1135 fOutputBlocks.push_back( bd );
1136 } else {
1137 HLTError("can not allocate/grow object array");
29312178 1138 pFile->CloseMemoryFile(0);
79c114b5 1139 delete pFile;
1140 pFile=NULL;
1141 }
1142 }
1143 } else {
1144 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1145 }
1146 return pFile;
1147}
1148
1149AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1150 const char* dtOrigin,
1151 AliHLTUInt32_t spec,
1152 float capacity)
1153{
1154 // see header file for function documentation
1155 ALIHLTCOMPONENT_BASE_STOPWATCH();
1156 AliHLTComponentDataType dt;
1157 SetDataType(dt, dtID, dtOrigin);
1158 int size=fOutputBufferSize-fOutputBufferFilled;
1159 if (capacity<0 || capacity>1.0) {
1160 HLTError("invalid parameter: capacity %f", capacity);
1161 return NULL;
1162 }
1163 size=(int)(size*capacity);
1164 return CreateMemoryFile(size, dt, spec);
1165}
1166
1167AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1168 AliHLTUInt32_t spec,
1169 float capacity)
1170{
1171 // see header file for function documentation
1172 ALIHLTCOMPONENT_BASE_STOPWATCH();
1173 int size=fOutputBufferSize-fOutputBufferFilled;
1174 if (capacity<0 || capacity>1.0) {
1175 HLTError("invalid parameter: capacity %f", capacity);
1176 return NULL;
1177 }
1178 size=(int)(size*capacity);
1179 return CreateMemoryFile(size, dt, spec);
1180}
1181
1182int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1183 const char* key, int option)
1184{
3a7c0444 1185 // see header file for function documentation
79c114b5 1186 int iResult=0;
1187 if (pFile && pObject) {
1188 pFile->cd();
1189 iResult=pObject->Write(key, option);
1190 if (iResult>0) {
1191 // success
1192 } else {
1193 iResult=-pFile->GetErrno();
1194 if (iResult==-ENOSPC) {
1195 HLTError("error writing memory file, buffer too small");
1196 }
1197 }
1198 } else {
1199 iResult=-EINVAL;
1200 }
1201 return iResult;
1202}
1203
1204int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1205{
3a7c0444 1206 // see header file for function documentation
79c114b5 1207 int iResult=0;
1208 if (pFile) {
2be3f004 1209 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1210 int i=0;
1211 while (element!=fMemFiles.end() && iResult>=0) {
1212 if (*element && *element==pFile) {
29312178 1213 iResult=pFile->CloseMemoryFile();
79c114b5 1214
1215 // sync memory files and descriptors
1216 if (iResult>=0) {
1217 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1218 }
1219 delete *element;
1220 *element=NULL;
1221 return iResult;
1222 }
1223 element++; i++;
1224 }
1225 HLTError("can not find memory file %p", pFile);
1226 iResult=-ENOENT;
1227 } else {
1228 iResult=-EINVAL;
1229 }
1230 return iResult;
1231}
1232
29312178 1233int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData /*edd*/)
a655eae3 1234{
1235 // see header file for function documentation
1236 int iResult=-ENOSYS;
1237 //#warning function not yet implemented
1238 HLTWarning("function not yet implemented");
1239 return iResult;
1240}
1241
3cde846d 1242int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1243 const AliHLTComponentBlockData* blocks,
1244 AliHLTComponentTriggerData& trigData,
1245 AliHLTUInt8_t* outputPtr,
1246 AliHLTUInt32_t& size,
1247 AliHLTUInt32_t& outputBlockCnt,
1248 AliHLTComponentBlockData*& outputBlocks,
1249 AliHLTComponentEventDoneData*& edd )
1250{
70ed7d01 1251 // see header file for function documentation
b2065764 1252 HLTLogKeyword(GetComponentID());
90ebac25 1253 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1254 int iResult=0;
1255 fCurrentEvent=evtData.fEventID;
a655eae3 1256 fCurrentEventData=evtData;
1257 fpInputBlocks=blocks;
1258 fCurrentInputBlock=-1;
1259 fSearchDataType=kAliHLTAnyDataType;
1260 fpOutputBuffer=outputPtr;
1261 fOutputBufferSize=size;
1262 fOutputBufferFilled=0;
1263 fOutputBlocks.clear();
96f9673a 1264 outputBlockCnt=0;
1265 outputBlocks=NULL;
438635e3 1266
1267 AliHLTComponentBlockDataList forwardedBlocks;
1268
1269 // optional component statistics
a0aeb701 1270 AliHLTComponentStatisticsList compStats;
438635e3 1271 bool bAddComponentTableEntry=false;
a0aeb701 1272#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1273 AliHLTComponentStatistics outputStat;
1274 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
48abe484 1275 outputStat.fId=fChainIdCrc;
a0aeb701 1276 compStats.push_back(outputStat);
1277 if (fpBenchmark) {
1278 fpBenchmark->Reset();
1279 fpBenchmark->Start();
1280 }
1281#endif
559631d5 1282
48abe484 1283 // data processing is skipped
1284 // - if there are only steering events in the block list.
1285 // For the sake of data source components data processing
1286 // is not skipped if there is no block list at all or if it
1287 // just contains the eventType block
1288 // - always skipped if the event is of type
1289 // - gkAliEventTypeConfiguration
1290 // - gkAliEventTypeReadPreprocessor
45c0a780 1291 const unsigned int skipModeDefault=0x1;
1292 const unsigned int skipModeForce=0x2;
1293 unsigned int bSkipDataProcessing=skipModeDefault;
1294
559631d5 1295 // find special events
45c0a780 1296 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1297 // first look for all special events and execute in the appropriate
1298 // sequence afterwords
1299 int indexComConfEvent=-1;
b543e186 1300 int indexUpdtDCSEvent=-1;
579d9eb7 1301 int indexSOREvent=-1;
1302 int indexEOREvent=-1;
83fec083 1303 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1304 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1305 indexSOREvent=i;
45c0a780 1306 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1307 bSkipDataProcessing&=~skipModeDefault;
1308 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1309 // run type string
1310 // handling is not clear yet
1311 if (fpInputBlocks[i].fPtr) {
1312 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1313 }
579d9eb7 1314 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1315 indexEOREvent=i;
45c0a780 1316 // the calibration processor relies on the SOR and EOR events
1317 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1318 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1319 // DDL list
1320 // this event is most likely deprecated
1321 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1322 indexComConfEvent=i;
b543e186 1323 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1324 indexUpdtDCSEvent=i;
1325 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1326 fEventType=fpInputBlocks[i].fSpecification;
1327
1328 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1329 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1330
1331 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1332 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1333
1334 // never skip if the event type block is the only block
1335 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1336
a0aeb701 1337 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1338 if (compStats.size()>0) {
1339 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1340 for (AliHLTUInt32_t offset=0;
1341 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1342 offset+=sizeof(AliHLTComponentStatistics)) {
1343 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1344 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1345 compStats[0].fLevel=pStat->fLevel+1;
1346 }
1347 compStats.push_back(*pStat);
1348 }
1349 }
438635e3 1350 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1351 forwardedBlocks.push_back(fpInputBlocks[i]);
45c0a780 1352 } else {
1353 // the processing function is called if there is at least one
1354 // non-steering data block. Steering blocks are not filtered out
1355 // for sake of performance
1356 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1357 if (compStats.size()>0) {
1358 compStats[0].fInputBlockCount++;
1359 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1360 }
579d9eb7 1361 }
1362 }
45c0a780 1363
579d9eb7 1364 if (indexSOREvent>=0) {
1365 // start of run
438635e3 1366 bAddComponentTableEntry=true;
579d9eb7 1367 if (fpRunDesc==NULL) {
1368 fpRunDesc=new AliHLTRunDesc;
48abe484 1369 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1370 }
1371 if (fpRunDesc) {
1372 AliHLTRunDesc rundesc;
1373 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1374 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1375 *fpRunDesc=rundesc;
579d9eb7 1376 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1377 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1378 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1379 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1380 }
559631d5 1381 }
579d9eb7 1382 } else {
45c0a780 1383 iResult=-ENOMEM;
579d9eb7 1384 }
1385 }
1386 if (indexEOREvent>=0) {
438635e3 1387 bAddComponentTableEntry=true;
579d9eb7 1388 if (fpRunDesc!=NULL) {
1389 if (fpRunDesc) {
1390 AliHLTRunDesc rundesc;
1391 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1392 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1393 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1394 } else {
1395 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1396 }
559631d5 1397 }
579d9eb7 1398 AliHLTRunDesc* pRunDesc=fpRunDesc;
1399 fpRunDesc=NULL;
1400 delete pRunDesc;
559631d5 1401 }
579d9eb7 1402 } else {
1403 HLTWarning("did not receive SOR, ignoring EOR");
1404 }
1405 }
48abe484 1406 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1407 TString cdbEntry;
b543e186 1408 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1409 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1410 }
1411 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1412 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1413 if (tmpResult<0) {
1414 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1415 }
1416 }
48abe484 1417 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1418 TString modules;
1419 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1420 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1421 }
d6b69874 1422 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1423 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1424 if (tmpResult<0) {
1425 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1426 }
1427 }
45c0a780 1428 } else {
1429 // processing function needs to be called if there are no input data
1430 // blocks in order to make data source components working.
1431 bSkipDataProcessing&=~skipModeDefault;
559631d5 1432 }
a0aeb701 1433
1434 // data processing is not skipped if the component explicitly asks
1435 // for the private blocks
1436 if (fRequireSteeringBlocks) bSkipDataProcessing=0;
1437
2be3f004 1438 AliHLTComponentBlockDataList blockData;
45c0a780 1439 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1440 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1441 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1442 // in order to avoid 'shadowed variable' warning
1443 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1444 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1445 } // end of the scope of the stopwatch guard
b543e186 1446 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1447 if (fOutputBlocks.size()>0) {
df61f928 1448 // High Level interface
1449
1450 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1451 // sync memory files and descriptors
2be3f004 1452 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1453 int i=0;
1454 while (element!=fMemFiles.end() && iResult>=0) {
1455 if (*element) {
1456 if ((*element)->IsClosed()==0) {
1457 HLTWarning("memory file has not been closed, force flush");
1458 iResult=CloseMemoryFile(*element);
1459 }
1460 }
1461 element++; i++;
1462 }
1463
1464 if (iResult>=0) {
1465 // create the descriptor list
1466 if (blockData.size()>0) {
1467 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1468 iResult=-EFAULT;
1469 } else {
a0aeb701 1470 if (compStats.size()>0) {
1471 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1472 if (offset>0) fOutputBufferFilled+=offset;
1473 }
438635e3 1474 if (bAddComponentTableEntry) {
1475 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled);
1476 if (offset>0) size+=offset;
1477 }
1478 if (forwardedBlocks.size()>0) {
1479 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1480 }
79c114b5 1481 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1482 size=fOutputBufferFilled;
1483 }
a655eae3 1484 }
1485 } else {
df61f928 1486 // Low Level interface
a0aeb701 1487 if (compStats.size()>0) {
1488 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1489 if (offset>0) size+=offset;
1490 }
438635e3 1491 if (bAddComponentTableEntry) {
1492 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size);
1493 if (offset>0) size+=offset;
1494 }
1495 if (forwardedBlocks.size()>0) {
1496 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1497 }
a655eae3 1498 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1499 }
1500 if (iResult<0) {
1501 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1502 }
1503 }
b543e186 1504 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1505 outputBlockCnt=0;
1506 outputBlocks=NULL;
1507 }
8451168b 1508 CleanupInputObjects();
48abe484 1509 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1510 IncrementEventCounter();
1511 }
96f9673a 1512 if (outputBlockCnt==0) {
1513 // no output blocks, set size to 0
1514 size=0;
1515 }
3cde846d 1516 return iResult;
1517}
a655eae3 1518
a0aeb701 1519int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1520 AliHLTUInt8_t* buffer,
1521 AliHLTUInt32_t bufferSize,
1522 AliHLTUInt32_t offset,
1523 AliHLTComponentStatisticsList& stats) const
1524{
1525 // see header file for function documentation
1526 int iResult=0;
438635e3 1527#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
a0aeb701 1528 if (stats.size()==0) return -ENOENT;
1529 stats[0].fTotalOutputSize=offset;
1530 stats[0].fOutputBlockCount=blocks.size();
1531 if (fpBenchmark) {
1532 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*1000000);
1533 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*1000000);
1534 }
1535 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1536 AliHLTComponentBlockData bd;
1537 FillBlockData( bd );
1538 bd.fOffset = offset;
1539 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1540 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1541 bd.fSpecification = kAliHLTVoidDataSpec;
1542 unsigned int master=0;
1543 for (unsigned int i=1; i<blocks.size(); i++) {
1544 if (blocks[i].fSize>blocks[master].fSize &&
1545 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1546 master=i;
1547 }
1548 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1549 // take the data origin of the biggest block as specification
1550 // this is similar to the treatment in the HOMER interface. For traditional
1551 // reasons, the bytes are swapped there on a little endian architecture, so
1552 // we do it as well.
1553 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1554#ifdef R__BYTESWAP // set on little endian architectures
1555 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1556 ((bd.fSpecification & 0xFF00ULL) << 8) |
1557 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1558 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1559#endif
1560 }
1561 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1562 blocks.push_back(bd);
1563 iResult=bd.fSize;
1564 }
438635e3 1565#endif
1566 return iResult;
1567}
1568
1569int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1570 AliHLTUInt8_t* buffer,
1571 AliHLTUInt32_t bufferSize,
1572 AliHLTUInt32_t offset) const
1573{
1574 // see header file for function documentation
1575 int iResult=0;
1576#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1577 if (buffer && (offset+fChainId.size()+1<=bufferSize)) {
1578 AliHLTComponentBlockData bd;
1579 FillBlockData( bd );
1580 bd.fOffset = offset;
1581 bd.fSize = fChainId.size()+1;
1582 bd.fDataType = kAliHLTDataTypeComponentTable;
1583 bd.fSpecification = fChainIdCrc;
1584 memcpy(buffer+offset, fChainId.c_str(), fChainId.size()+1);
1585 blocks.push_back(bd);
1586 iResult=bd.fSize;
1587 }
1588 #endif
a0aeb701 1589 return iResult;
1590}
1591
90ebac25 1592AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1593 :
1594 fpStopwatch(NULL),
1595 fpPrec(NULL)
1596{
1597 // standard constructor (not for use)
1598}
1599
1600AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1601 :
1602 fpStopwatch(pStopwatch),
1603 fpPrec(NULL)
1604{
1605 // constructor
1606
1607 // check for already existing guard
1608 if (fgpCurrent) fpPrec=fgpCurrent;
1609 fgpCurrent=this;
1610
1611 // stop the preceeding guard if it controls a different stopwatch
1612 int bStart=1;
1613 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1614
1615 // start the stopwatch if the current guard controls a different one
1616 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1617}
1618
e419b223 1619AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 1620 :
1621 fpStopwatch(NULL),
1622 fpPrec(NULL)
1623{
e419b223 1624 //
1625 // copy constructor not for use
1626 //
1627}
1628
1629AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1630{
1631 //
1632 // assignment operator not for use
1633 //
1634 fpStopwatch=NULL;
1635 fpPrec=NULL;
1636 return *this;
90ebac25 1637}
1638
1639AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1640
1641AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1642{
1643 // destructor
1644
1645 // resume the preceeding guard if it controls a different stopwatch
1646 int bStop=1;
1647 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1648
1649 // stop the stopwatch if the current guard controls a different one
1650 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1651
1652 // resume to the preceeding guard
1653 fgpCurrent=fpPrec;
1654}
1655
1656int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1657{
1658 // see header file for function documentation
1659 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1660 return fpStopwatch!=pSucc?1:0;
1661}
1662
1663int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1664{
1665 // see header file for function documentation
1666 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1667 return fpStopwatch!=pSucc?1:0;
1668}
1669
1670int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
1671{
1672 // see header file for function documentation
1673 int iResult=0;
1674 if (pSW!=NULL && type<kSWTypeCount) {
1675 if (fpStopwatches) {
1676 TObject* pObj=fpStopwatches->At((int)type);
1677 if (pSW==NULL // explicit reset
1678 || pObj==NULL) { // explicit set
1679 fpStopwatches->AddAt(pSW, (int)type);
1680 } else if (pObj!=pSW) {
1681 HLTWarning("stopwatch %d already set, reset first", (int)type);
1682 iResult=-EBUSY;
1683 }
1684 }
1685 } else {
1686 iResult=-EINVAL;
1687 }
1688 return iResult;
1689}
1690
1691int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1692{
1693 // see header file for function documentation
1694 if (pStopwatches==NULL) return -EINVAL;
1695
1696 int iResult=0;
1697 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1698 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1699 return iResult;
1700}
559631d5 1701
1702AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1703{
29312178 1704 // see header file for function documentation
45c0a780 1705 if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
559631d5 1706 return fpRunDesc->fRunNo;
1707}
1708
1709AliHLTUInt32_t AliHLTComponent::GetRunType() const
1710{
29312178 1711 // see header file for function documentation
45c0a780 1712 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 1713 return fpRunDesc->fRunType;
1714}
1715
48abe484 1716bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
1717{
1718 // see header file for function documentation
1719 if (pTgt) *pTgt=fEventType;
1720 return (fEventType==gkAliEventTypeData ||
1721 fEventType==gkAliEventTypeDataReplay ||
1722 fEventType==gkAliEventTypeCalibration);
1723}
1724
83fec083 1725int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 1726 const char* structname, const char* eventname)
1727{
29312178 1728 // see header file for function documentation
559631d5 1729 int iResult=0;
1730 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1731 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1732 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1733 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 1734 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 1735 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 1736 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 1737 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1738 }
1739 if (copy!=iStructSize) {
c5123824 1740 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 1741 if (copy>iStructSize) {
1742 copy=iStructSize;
1743 } else {
1744 memset(pTgt, 0, iStructSize);
1745 }
1746 }
3294f81a 1747 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 1748 *pTgt=iStructSize;
1749 iResult=copy;
1750 } else {
1751 HLTWarning("%s event: missing data block", eventname);
1752 }
1753 } else {
1754 iResult=-ENODATA;
1755 }
1756 } else {
1757 HLTError("invalid struct");
1758 iResult=-EINVAL;
1759 }
1760 return iResult;
1761}
ed504011 1762
1763void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1764{
1765 // see header file for function documentation
1766
1767 // -- Detector offset
1768 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
1769
1770 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
1771 Int_t wordBase = 0;
1772
1773 if ( ddlIdBase <= 3 )
1774 wordBase = ddlIdBase;
1775 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1776 wordBase = ddlIdBase + 7;
1777 else
1778 wordBase = ddlIdBase + 9;
1779
1780 // -- Bit index in Word
1781 Int_t bitIdx = ddlId % 32;
1782
1783 // -- Index of word
1784 Int_t wordIdx = wordBase;
1785
1786 // -- if TPC (3) or TOD (5) add word idx
1787 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1788 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1789 }
1790
1791 // -- Set -- 'OR' word with bit mask;
1792 if ( state )
1793 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1794 // -- Unset -- 'AND' word with bit mask;
1795 else
1796 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1797}
1798
1799Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1800{
1801 // see header file for function documentation
1802
1803 Int_t iResult = -1;
1804
1805 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1806
1807 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1808 // check for special cases TPC and TOF
1809 if ( wordNdx > 3 && wordNdx <= 10 ) {
1810 wordNdx = 10;
1811 iResult = 3;
1812 }
1813 else if ( wordNdx > 12 && wordNdx <= 14 ) {
1814 wordNdx = 14;
1815 iResult = 12;
1816 }
1817 else
1818 iResult = wordNdx;
1819 }
1820 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
1821 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
1822 iResult = -1;
1823 break;
1824 }
1825 }
1826
1827 return iResult;
1828}
48abe484 1829
1830AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
1831{
1832 // see header file for function documentation
1833 AliHLTUInt32_t remainder = 0;
1834 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
1835 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
1836 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
1837
1838 // code from
1839 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
1840
1841 /*
1842 * Perform modulo-2 division, a byte at a time.
1843 */
1844 for (int byte = 0; byte < size; ++byte)
1845 {
1846 /*
1847 * Bring the next byte into the remainder.
1848 */
1849 remainder ^= (buffer[byte] << (crcwidth - 8));
1850
1851 /*
1852 * Perform modulo-2 division, a bit at a time.
1853 */
1854 for (uint8_t bit = 8; bit > 0; --bit)
1855 {
1856 /*
1857 * Try to divide the current data bit.
1858 */
1859 if (remainder & topbit)
1860 {
1861 remainder = (remainder << 1) ^ polynomial;
1862 }
1863 else
1864 {
1865 remainder = (remainder << 1);
1866 }
1867 }
1868 }
1869
1870 /*
1871 * The final remainder is the CRC result.
1872 */
1873 return (remainder);
1874}