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