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