]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponent.cxx
removing obsolete copy of AltroChannelSelectorComponent
[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();
95e36f3d 612 for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++);
48abe484 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
4646c6e3 752AliHLTEventID_t AliHLTComponent::GetEventId() const
753{
754 // see header file for function documentation
755 if (fpInputBlocks!=NULL) {
756 return fCurrentEventData.fEventID;
757 }
758 return 0;
759}
760
a655eae3 761const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
762 const char* classname,
763 int bForce)
764{
765 // see header file for function documentation
90ebac25 766 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 767 fSearchDataType=dt;
768 if (classname) fClassName=classname;
769 else fClassName.clear();
1edbbe49 770 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 771 TObject* pObj=NULL;
772 if (idx>=0) {
79c114b5 773 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 774 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
775 fCurrentInputBlock=idx;
776 } else {
777 }
778 }
779 return pObj;
780}
781
782const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
783 const char* dtOrigin,
784 const char* classname,
785 int bForce)
786{
787 // see header file for function documentation
90ebac25 788 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 789 AliHLTComponentDataType dt;
790 SetDataType(dt, dtID, dtOrigin);
791 return GetFirstInputObject(dt, classname, bForce);
792}
793
794const TObject* AliHLTComponent::GetNextInputObject(int bForce)
795{
796 // see header file for function documentation
90ebac25 797 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 798 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 799 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
800 TObject* pObj=NULL;
801 if (idx>=0) {
802 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
803 fCurrentInputBlock=idx;
804 }
805 }
806 return pObj;
807}
808
1edbbe49 809int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 810{
811 // see header file for function documentation
812 int iResult=-ENOENT;
813 if (fpInputBlocks!=NULL) {
814 int idx=startIdx<0?0:startIdx;
4b98eadb 815 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 816 if (dt!=fpInputBlocks[idx].fDataType) continue;
817
1edbbe49 818 if (bObject!=0) {
819 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 820 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
821 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 822 }
3dd8541e 823 iResult=idx;
a655eae3 824 }
825 }
826 return iResult;
827}
828
829TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
830{
831 // see header file for function documentation
832 TObject* pObj=NULL;
833 if (fpInputBlocks!=NULL) {
4b98eadb 834 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 835 if (fpInputBlocks[idx].fPtr) {
3294f81a 836 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 837 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 838 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 839 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 840 TClass* objclass=msg.GetClass();
841 pObj=msg.ReadObject(objclass);
842 if (pObj && objclass) {
843 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 844 } else {
845 }
1edbbe49 846 //} else {
847 } else if (bForce!=0) {
c5123824 848 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 849 }
850 } else {
851 HLTFatal("block descriptor empty");
852 }
853 } else {
854 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
855 }
856 } else {
857 HLTError("no input blocks available");
858 }
859
860 return pObj;
861}
862
298ef463 863TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 864{
865 // see header file for function documentation
866 if (fpInputObjects==NULL) {
867 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
868 }
869 TObject* pObj=NULL;
870 if (fpInputObjects) {
871 pObj=fpInputObjects->At(idx);
872 if (pObj==NULL) {
873 pObj=CreateInputObject(idx, bForce);
874 if (pObj) {
875 fpInputObjects->AddAt(pObj, idx);
876 }
877 }
878 } else {
879 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
880 }
881 return pObj;
882}
883
8451168b 884int AliHLTComponent::CleanupInputObjects()
885{
66043029 886 // see header file for function documentation
8451168b 887 if (!fpInputObjects) return 0;
888 TObjArray* array=fpInputObjects;
889 fpInputObjects=NULL;
890 for (int i=0; i<array->GetEntries(); i++) {
891 TObject* pObj=array->At(i);
79c114b5 892 // grrr, garbage collection strikes back: When read via AliHLTMessage
893 // (CreateInputObject), and written to a TFile afterwards, the
894 // TFile::Close calls ROOOT's garbage collection. No clue why the
895 // object ended up in the key list and needs to be deleted
896 if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
8451168b 897 }
898 delete array;
90ebac25 899 return 0;
8451168b 900}
901
a655eae3 902AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
903{
904 // see header file for function documentation
90ebac25 905 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 906 AliHLTComponentDataType dt=kAliHLTVoidDataType;
907 int idx=fCurrentInputBlock;
908 if (pObject) {
909 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
910 } else {
911 HLTError("unknown object %p", pObject);
912 }
913 }
914 if (idx>=0) {
4b98eadb 915 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 916 dt=fpInputBlocks[idx].fDataType;
917 } else {
918 HLTFatal("severe internal error, index out of range");
919 }
920 }
921 return dt;
922}
923
924AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
925{
926 // see header file for function documentation
90ebac25 927 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 928 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
929 int idx=fCurrentInputBlock;
930 if (pObject) {
931 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
932 } else {
933 HLTError("unknown object %p", pObject);
934 }
935 }
936 if (idx>=0) {
4b98eadb 937 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 938 iSpec=fpInputBlocks[idx].fSpecification;
939 } else {
940 HLTFatal("severe internal error, index out of range");
941 }
942 }
943 return iSpec;
944}
945
c7e9e2f2 946int AliHLTComponent::Forward(const TObject* pObject)
947{
948 // see header file for function documentation
949 int iResult=0;
950 int idx=fCurrentInputBlock;
951 if (pObject) {
952 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
953 } else {
954 HLTError("unknown object %p", pObject);
955 iResult=-ENOENT;
956 }
957 }
958 if (idx>=0) {
959 fOutputBlocks.push_back(fpInputBlocks[idx]);
960 }
961 return iResult;
962}
963
964int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
965{
966 // see header file for function documentation
967 int iResult=0;
968 int idx=fCurrentInputBlock;
969 if (pBlock) {
970 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
971 } else {
972 HLTError("unknown Block %p", pBlock);
973 iResult=-ENOENT;
974 }
975 }
976 if (idx>=0) {
977 // check for fpInputBlocks pointer done in FindInputBlock
978 fOutputBlocks.push_back(fpInputBlocks[idx]);
979 }
980 return iResult;
981}
982
a655eae3 983const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
984{
985 // see header file for function documentation
90ebac25 986 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 987 fSearchDataType=dt;
988 fClassName.clear();
989 int idx=FindInputBlock(fSearchDataType, 0);
990 const AliHLTComponentBlockData* pBlock=NULL;
991 if (idx>=0) {
992 // check for fpInputBlocks pointer done in FindInputBlock
993 pBlock=&fpInputBlocks[idx];
1edbbe49 994 fCurrentInputBlock=idx;
a655eae3 995 }
996 return pBlock;
997}
998
999const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1000 const char* dtOrigin)
1001{
1002 // see header file for function documentation
90ebac25 1003 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1004 AliHLTComponentDataType dt;
1005 SetDataType(dt, dtID, dtOrigin);
1006 return GetFirstInputBlock(dt);
1007}
1008
10b9cbf9 1009const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 1010{
1011 // see header file for function documentation
1012 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 1013 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 1014 return &fpInputBlocks[index];
1015}
1016
a655eae3 1017const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1018{
1019 // see header file for function documentation
90ebac25 1020 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1021 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1022 const AliHLTComponentBlockData* pBlock=NULL;
1023 if (idx>=0) {
1024 // check for fpInputBlocks pointer done in FindInputBlock
1025 pBlock=&fpInputBlocks[idx];
1edbbe49 1026 fCurrentInputBlock=idx;
a655eae3 1027 }
1028 return pBlock;
1029}
1030
66043029 1031int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 1032{
1033 // see header file for function documentation
1034 int iResult=-ENOENT;
1035 if (fpInputBlocks!=NULL) {
1036 if (pBlock) {
1037 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 1038 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 1039 }
1040 } else {
1041 iResult=-EINVAL;
1042 }
1043 }
1044 return iResult;
1045}
1046
1047AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1048{
1049 // see header file for function documentation
90ebac25 1050 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1051 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1052 int idx=fCurrentInputBlock;
1053 if (pBlock) {
1054 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1055 } else {
1056 HLTError("unknown Block %p", pBlock);
1057 }
1058 }
1059 if (idx>=0) {
1060 // check for fpInputBlocks pointer done in FindInputBlock
1061 iSpec=fpInputBlocks[idx].fSpecification;
1062 }
1063 return iSpec;
1064}
1065
79c114b5 1066int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1067 void* pHeader, int headerSize)
a655eae3 1068{
1069 // see header file for function documentation
90ebac25 1070 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1071 int iResult=0;
1072 if (pObject) {
1073 AliHLTMessage msg(kMESS_OBJECT);
9ace7282 1074 msg.SetCompressionLevel(fCompressionLevel);
a655eae3 1075 msg.WriteObject(pObject);
1076 Int_t iMsgLength=msg.Length();
1077 if (iMsgLength>0) {
9ace7282 1078 // Matthias Sep 2008
1079 // NOTE: AliHLTMessage does implement it's own SetLength method
1080 // which is not architecture independent. The original SetLength
1081 // stores the size always in network byte order.
1082 // I'm trying to remember the rational for that, might be that
1083 // it was just some lack of knowledge. Want to change this, but
1084 // has to be done carefullt to be backward compatible.
a655eae3 1085 msg.SetLength(); // sets the length to the first (reserved) word
9ace7282 1086
1087 // does nothing if the level is 0
1088 msg.Compress();
1089
1090 char *mbuf = msg.Buffer();
1091 if (msg.CompBuffer()) {
1092 msg.SetLength(); // set once more to have to byte order
1093 mbuf = msg.CompBuffer();
1094 iMsgLength = msg.CompLength();
1095 }
1096 assert(mbuf!=NULL);
1097 iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 1098 if (iResult>=0) {
9ace7282 1099 HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
a655eae3 1100 }
1101 } else {
1102 HLTError("object serialization failed for object %p", pObject);
1103 iResult=-ENOMSG;
1104 }
1105 } else {
1106 iResult=-EINVAL;
1107 }
1108 return iResult;
1109}
1110
79c114b5 1111int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1112 void* pHeader, int headerSize)
a655eae3 1113{
1114 // see header file for function documentation
90ebac25 1115 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1116 AliHLTComponentDataType dt;
1117 SetDataType(dt, dtID, dtOrigin);
79c114b5 1118 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1119}
1120
438635e3 1121int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1122 const void* pHeader, int headerSize)
a655eae3 1123{
1124 // see header file for function documentation
90ebac25 1125 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d9ffd37 1126 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1127}
1128
438635e3 1129int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1130 const void* pHeader, int headerSize)
a655eae3 1131{
1132 // see header file for function documentation
90ebac25 1133 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1134 AliHLTComponentDataType dt;
1135 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1136 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1137}
1138
438635e3 1139int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1140 const void* pHeader, int iHeaderSize)
a655eae3 1141{
1142 // see header file for function documentation
1143 int iResult=0;
79c114b5 1144 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1145
1146 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1147 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1148 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1149
1150 // copy header if provided but skip if the header is the target location
1151 // in that case it has already been copied
79c114b5 1152 if (pHeader!=NULL && pHeader!=pTgt) {
1153 memcpy(pTgt, pHeader, iHeaderSize);
1154 }
1155
1156 pTgt += (AliHLTUInt8_t) iHeaderSize;
1157
438635e3 1158 // copy buffer if provided but skip if buffer is the target location
1159 // in that case it has already been copied
a655eae3 1160 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1161 memcpy(pTgt, pBuffer, iBufferSize);
1162
4b98eadb 1163 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1164 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1165 }
79c114b5 1166 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1167 } else {
1168 if (fpOutputBuffer) {
79c114b5 1169 HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
a655eae3 1170 } else {
1171 HLTError("output buffer not available");
1172 }
1173 iResult=-ENOSPC;
1174 }
a655eae3 1175 }
438635e3 1176 if (iResult>=0) {
1177 AliHLTComponentBlockData bd;
1178 FillBlockData( bd );
1179 bd.fOffset = fOutputBufferFilled;
1180 bd.fSize = iBlkSize;
1181 bd.fDataType = dt;
1182 bd.fSpecification = spec;
1183 fOutputBlocks.push_back( bd );
1184 fOutputBufferFilled+=bd.fSize;
1185 }
1186
a655eae3 1187 return iResult;
1188}
1189
8451168b 1190int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1191{
66043029 1192 // see header file for function documentation
8451168b 1193 if (!pObject) return -EINVAL;
1194 AliHLTMessage msg(kMESS_OBJECT);
1195 msg.WriteObject(pObject);
1196 return msg.Length();
1197}
1198
79c114b5 1199AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1200 const char* dtOrigin,
1201 AliHLTUInt32_t spec)
1202{
1203 // see header file for function documentation
1204 ALIHLTCOMPONENT_BASE_STOPWATCH();
1205 AliHLTComponentDataType dt;
1206 SetDataType(dt, dtID, dtOrigin);
1207 return CreateMemoryFile(capacity, dt, spec);
1208}
1209
1210AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1211 const AliHLTComponentDataType& dt,
1212 AliHLTUInt32_t spec)
1213{
1214 // see header file for function documentation
1215 ALIHLTCOMPONENT_BASE_STOPWATCH();
1216 AliHLTMemoryFile* pFile=NULL;
83fec083 1217 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1218 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1219 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1220 if (pFile) {
83fec083 1221 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1222 if (nofBlocks+1>fMemFiles.size()) {
1223 fMemFiles.resize(nofBlocks+1, NULL);
1224 }
1225 if (nofBlocks<fMemFiles.size()) {
1226 fMemFiles[nofBlocks]=pFile;
1227 AliHLTComponentBlockData bd;
1228 FillBlockData( bd );
1229 bd.fOffset = fOutputBufferFilled;
79c114b5 1230 bd.fSize = capacity;
1231 bd.fDataType = dt;
1232 bd.fSpecification = spec;
1233 fOutputBufferFilled+=bd.fSize;
1234 fOutputBlocks.push_back( bd );
1235 } else {
1236 HLTError("can not allocate/grow object array");
29312178 1237 pFile->CloseMemoryFile(0);
79c114b5 1238 delete pFile;
1239 pFile=NULL;
1240 }
1241 }
1242 } else {
1243 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1244 }
1245 return pFile;
1246}
1247
1248AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1249 const char* dtOrigin,
1250 AliHLTUInt32_t spec,
1251 float capacity)
1252{
1253 // see header file for function documentation
1254 ALIHLTCOMPONENT_BASE_STOPWATCH();
1255 AliHLTComponentDataType dt;
1256 SetDataType(dt, dtID, dtOrigin);
1257 int size=fOutputBufferSize-fOutputBufferFilled;
1258 if (capacity<0 || capacity>1.0) {
1259 HLTError("invalid parameter: capacity %f", capacity);
1260 return NULL;
1261 }
1262 size=(int)(size*capacity);
1263 return CreateMemoryFile(size, dt, spec);
1264}
1265
1266AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1267 AliHLTUInt32_t spec,
1268 float capacity)
1269{
1270 // see header file for function documentation
1271 ALIHLTCOMPONENT_BASE_STOPWATCH();
1272 int size=fOutputBufferSize-fOutputBufferFilled;
1273 if (capacity<0 || capacity>1.0) {
1274 HLTError("invalid parameter: capacity %f", capacity);
1275 return NULL;
1276 }
1277 size=(int)(size*capacity);
1278 return CreateMemoryFile(size, dt, spec);
1279}
1280
1281int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1282 const char* key, int option)
1283{
3a7c0444 1284 // see header file for function documentation
79c114b5 1285 int iResult=0;
1286 if (pFile && pObject) {
1287 pFile->cd();
1288 iResult=pObject->Write(key, option);
1289 if (iResult>0) {
1290 // success
1291 } else {
1292 iResult=-pFile->GetErrno();
1293 if (iResult==-ENOSPC) {
1294 HLTError("error writing memory file, buffer too small");
1295 }
1296 }
1297 } else {
1298 iResult=-EINVAL;
1299 }
1300 return iResult;
1301}
1302
1303int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1304{
3a7c0444 1305 // see header file for function documentation
79c114b5 1306 int iResult=0;
1307 if (pFile) {
2be3f004 1308 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1309 int i=0;
1310 while (element!=fMemFiles.end() && iResult>=0) {
1311 if (*element && *element==pFile) {
29312178 1312 iResult=pFile->CloseMemoryFile();
79c114b5 1313
1314 // sync memory files and descriptors
1315 if (iResult>=0) {
1316 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1317 }
1318 delete *element;
1319 *element=NULL;
1320 return iResult;
1321 }
1322 element++; i++;
1323 }
1324 HLTError("can not find memory file %p", pFile);
1325 iResult=-ENOENT;
1326 } else {
1327 iResult=-EINVAL;
1328 }
1329 return iResult;
1330}
1331
eafbc306 1332int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
a655eae3 1333{
1334 // see header file for function documentation
eafbc306 1335 int iResult=0;
1336
1337 AliHLTComponentEventDoneData* newEDD = NULL;
1338
1339 unsigned long newSize=edd.fDataSize;
1340 if (fEventDoneData)
1341 newSize += fEventDoneData->fDataSize;
1342
1343 if (newSize>fEventDoneDataSize) {
1344 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1345 if (!newEDD)
1346 return -ENOMEM;
1347 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1348 newEDD->fDataSize = newSize;
1349 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1350 unsigned long long offset = 0;
1351 if (fEventDoneData) {
1352 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1353 offset += fEventDoneData->fDataSize;
1354 }
1355 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1356 if (fEventDoneData)
1357 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1358 fEventDoneData = newEDD;
1359 fEventDoneDataSize = newSize;
1360 }
1361 else {
1362 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1363 fEventDoneData->fDataSize += edd.fDataSize;
1364 }
a655eae3 1365 return iResult;
1366}
1367
3cde846d 1368int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1369 const AliHLTComponentBlockData* blocks,
1370 AliHLTComponentTriggerData& trigData,
1371 AliHLTUInt8_t* outputPtr,
1372 AliHLTUInt32_t& size,
1373 AliHLTUInt32_t& outputBlockCnt,
1374 AliHLTComponentBlockData*& outputBlocks,
1375 AliHLTComponentEventDoneData*& edd )
1376{
70ed7d01 1377 // see header file for function documentation
b2065764 1378 HLTLogKeyword(GetComponentID());
90ebac25 1379 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1380 int iResult=0;
1381 fCurrentEvent=evtData.fEventID;
a655eae3 1382 fCurrentEventData=evtData;
1383 fpInputBlocks=blocks;
1384 fCurrentInputBlock=-1;
1385 fSearchDataType=kAliHLTAnyDataType;
1386 fpOutputBuffer=outputPtr;
1387 fOutputBufferSize=size;
1388 fOutputBufferFilled=0;
1389 fOutputBlocks.clear();
96f9673a 1390 outputBlockCnt=0;
1391 outputBlocks=NULL;
438635e3 1392
1393 AliHLTComponentBlockDataList forwardedBlocks;
1394
1395 // optional component statistics
a0aeb701 1396 AliHLTComponentStatisticsList compStats;
438635e3 1397 bool bAddComponentTableEntry=false;
abb52c8f 1398 vector<AliHLTUInt32_t> parentComponentTables;
a0aeb701 1399#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1400 AliHLTComponentStatistics outputStat;
1401 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
48abe484 1402 outputStat.fId=fChainIdCrc;
a0aeb701 1403 compStats.push_back(outputStat);
1404 if (fpBenchmark) {
1405 fpBenchmark->Reset();
1406 fpBenchmark->Start();
1407 }
1408#endif
559631d5 1409
48abe484 1410 // data processing is skipped
1411 // - if there are only steering events in the block list.
1412 // For the sake of data source components data processing
1413 // is not skipped if there is no block list at all or if it
1414 // just contains the eventType block
1415 // - always skipped if the event is of type
1416 // - gkAliEventTypeConfiguration
1417 // - gkAliEventTypeReadPreprocessor
45c0a780 1418 const unsigned int skipModeDefault=0x1;
1419 const unsigned int skipModeForce=0x2;
1420 unsigned int bSkipDataProcessing=skipModeDefault;
1421
559631d5 1422 // find special events
45c0a780 1423 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1424 // first look for all special events and execute in the appropriate
1425 // sequence afterwords
1426 int indexComConfEvent=-1;
b543e186 1427 int indexUpdtDCSEvent=-1;
579d9eb7 1428 int indexSOREvent=-1;
1429 int indexEOREvent=-1;
83fec083 1430 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1431 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1432 indexSOREvent=i;
45c0a780 1433 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1434 bSkipDataProcessing&=~skipModeDefault;
1435 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1436 // run type string
1437 // handling is not clear yet
1438 if (fpInputBlocks[i].fPtr) {
1439 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1440 }
579d9eb7 1441 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1442 indexEOREvent=i;
45c0a780 1443 // the calibration processor relies on the SOR and EOR events
1444 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1445 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1446 // DDL list
1447 // this event is most likely deprecated
1448 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1449 indexComConfEvent=i;
b543e186 1450 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1451 indexUpdtDCSEvent=i;
1452 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1453 fEventType=fpInputBlocks[i].fSpecification;
1454
1455 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1456 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1457
1458 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1459 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1460
1461 // never skip if the event type block is the only block
1462 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1463
a0aeb701 1464 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1465 if (compStats.size()>0) {
1466 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1467 for (AliHLTUInt32_t offset=0;
1468 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1469 offset+=sizeof(AliHLTComponentStatistics)) {
1470 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1471 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1472 compStats[0].fLevel=pStat->fLevel+1;
1473 }
1474 compStats.push_back(*pStat);
1475 }
1476 }
438635e3 1477 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1478 forwardedBlocks.push_back(fpInputBlocks[i]);
abb52c8f 1479 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
45c0a780 1480 } else {
1481 // the processing function is called if there is at least one
1482 // non-steering data block. Steering blocks are not filtered out
1483 // for sake of performance
1484 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1485 if (compStats.size()>0) {
1486 compStats[0].fInputBlockCount++;
1487 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1488 }
579d9eb7 1489 }
1490 }
45c0a780 1491
579d9eb7 1492 if (indexSOREvent>=0) {
1493 // start of run
438635e3 1494 bAddComponentTableEntry=true;
579d9eb7 1495 if (fpRunDesc==NULL) {
1496 fpRunDesc=new AliHLTRunDesc;
48abe484 1497 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1498 }
1499 if (fpRunDesc) {
1500 AliHLTRunDesc rundesc;
1501 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1502 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1503 *fpRunDesc=rundesc;
579d9eb7 1504 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1505 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1506 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1507 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1508 }
559631d5 1509 }
579d9eb7 1510 } else {
45c0a780 1511 iResult=-ENOMEM;
579d9eb7 1512 }
1513 }
1514 if (indexEOREvent>=0) {
438635e3 1515 bAddComponentTableEntry=true;
579d9eb7 1516 if (fpRunDesc!=NULL) {
1517 if (fpRunDesc) {
1518 AliHLTRunDesc rundesc;
1519 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1520 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1521 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1522 } else {
1523 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1524 }
559631d5 1525 }
579d9eb7 1526 AliHLTRunDesc* pRunDesc=fpRunDesc;
1527 fpRunDesc=NULL;
1528 delete pRunDesc;
559631d5 1529 }
579d9eb7 1530 } else {
1531 HLTWarning("did not receive SOR, ignoring EOR");
1532 }
1533 }
48abe484 1534 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1535 TString cdbEntry;
b543e186 1536 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1537 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1538 }
1539 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1540 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1541 if (tmpResult<0) {
1542 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1543 }
1544 }
48abe484 1545 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1546 TString modules;
1547 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1548 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1549 }
d6b69874 1550 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1551 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1552 if (tmpResult<0) {
1553 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1554 }
1555 }
45c0a780 1556 } else {
1557 // processing function needs to be called if there are no input data
1558 // blocks in order to make data source components working.
1559 bSkipDataProcessing&=~skipModeDefault;
559631d5 1560 }
a0aeb701 1561
1562 // data processing is not skipped if the component explicitly asks
1563 // for the private blocks
1564 if (fRequireSteeringBlocks) bSkipDataProcessing=0;
1565
2be3f004 1566 AliHLTComponentBlockDataList blockData;
45c0a780 1567 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1568 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1569 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1570 // in order to avoid 'shadowed variable' warning
1571 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1572 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1573 } // end of the scope of the stopwatch guard
b543e186 1574 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1575 if (fOutputBlocks.size()>0) {
df61f928 1576 // High Level interface
1577
1578 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1579 // sync memory files and descriptors
2be3f004 1580 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1581 int i=0;
1582 while (element!=fMemFiles.end() && iResult>=0) {
1583 if (*element) {
1584 if ((*element)->IsClosed()==0) {
1585 HLTWarning("memory file has not been closed, force flush");
1586 iResult=CloseMemoryFile(*element);
1587 }
1588 }
1589 element++; i++;
1590 }
1591
1592 if (iResult>=0) {
1593 // create the descriptor list
1594 if (blockData.size()>0) {
1595 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1596 iResult=-EFAULT;
1597 } else {
abb52c8f 1598 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 1599 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1600 if (offset>0) fOutputBufferFilled+=offset;
1601 }
438635e3 1602 if (bAddComponentTableEntry) {
abb52c8f 1603 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
438635e3 1604 if (offset>0) size+=offset;
1605 }
1606 if (forwardedBlocks.size()>0) {
1607 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1608 }
79c114b5 1609 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1610 size=fOutputBufferFilled;
1611 }
a655eae3 1612 }
1613 } else {
df61f928 1614 // Low Level interface
a0aeb701 1615 if (compStats.size()>0) {
1616 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1617 if (offset>0) size+=offset;
1618 }
438635e3 1619 if (bAddComponentTableEntry) {
abb52c8f 1620 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
438635e3 1621 if (offset>0) size+=offset;
1622 }
1623 if (forwardedBlocks.size()>0) {
1624 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1625 }
a655eae3 1626 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1627 }
1628 if (iResult<0) {
1629 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1630 }
1631 }
b543e186 1632 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1633 outputBlockCnt=0;
1634 outputBlocks=NULL;
1635 }
8451168b 1636 CleanupInputObjects();
48abe484 1637 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1638 IncrementEventCounter();
1639 }
96f9673a 1640 if (outputBlockCnt==0) {
1641 // no output blocks, set size to 0
1642 size=0;
1643 }
4646c6e3 1644 FillEventData(fCurrentEventData);
3cde846d 1645 return iResult;
1646}
a655eae3 1647
a0aeb701 1648int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1649 AliHLTUInt8_t* buffer,
1650 AliHLTUInt32_t bufferSize,
1651 AliHLTUInt32_t offset,
1652 AliHLTComponentStatisticsList& stats) const
1653{
1654 // see header file for function documentation
1655 int iResult=0;
438635e3 1656#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
a0aeb701 1657 if (stats.size()==0) return -ENOENT;
1658 stats[0].fTotalOutputSize=offset;
1659 stats[0].fOutputBlockCount=blocks.size();
1660 if (fpBenchmark) {
1661 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*1000000);
1662 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*1000000);
1663 }
1664 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1665 AliHLTComponentBlockData bd;
1666 FillBlockData( bd );
1667 bd.fOffset = offset;
1668 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1669 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1670 bd.fSpecification = kAliHLTVoidDataSpec;
1671 unsigned int master=0;
1672 for (unsigned int i=1; i<blocks.size(); i++) {
1673 if (blocks[i].fSize>blocks[master].fSize &&
1674 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1675 master=i;
1676 }
1677 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1678 // take the data origin of the biggest block as specification
1679 // this is similar to the treatment in the HOMER interface. For traditional
1680 // reasons, the bytes are swapped there on a little endian architecture, so
1681 // we do it as well.
1682 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1683#ifdef R__BYTESWAP // set on little endian architectures
1684 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1685 ((bd.fSpecification & 0xFF00ULL) << 8) |
1686 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1687 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1688#endif
1689 }
1690 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1691 blocks.push_back(bd);
1692 iResult=bd.fSize;
1693 }
bd6cac58 1694#else
1695 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
1696 // get rid of warning
1697 }
438635e3 1698#endif
1699 return iResult;
1700}
1701
1702int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1703 AliHLTUInt8_t* buffer,
1704 AliHLTUInt32_t bufferSize,
abb52c8f 1705 AliHLTUInt32_t offset,
1706 const vector<AliHLTUInt32_t>& parents) const
438635e3 1707{
1708 // see header file for function documentation
1709 int iResult=0;
1710#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
abb52c8f 1711 // the payload consists of the AliHLTComponentTableEntry struct,
1712 // followed by a an array of 32bit crc chain ids and the component
1713 // description string
1714 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
1715 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
1716
1717 // the component description has the following format:
1718 // chain-id{component-id:arguments}
1719 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
1720 unsigned int descriptionSize=fChainId.size()+1;
1721 descriptionSize+=2; // the '{}' around the component id
1722 descriptionSize+=strlen(componentId);
1723 descriptionSize+=1; // the ':' between component id and arguments
1724 descriptionSize+=fComponentArgs.size();
1725
1726 payloadSize+=descriptionSize;
1727 if (buffer && (offset+payloadSize<=bufferSize)) {
1728 AliHLTUInt8_t* pTgt=buffer+offset;
1729 memset(pTgt, 0, payloadSize);
1730
1731 // write entry
1732 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
1733 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
1734 pEntry->fNofParents=parents.size();
1735 pEntry->fSizeDescription=descriptionSize;
1736 pTgt=pEntry->fBuffer;
1737
1738 // write array of parents
1739 if (parents.size()>0) {
1740 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
1741 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
1742 pTgt+=copy;
1743 }
1744
1745 // write component description
1746 memcpy(pTgt, fChainId.c_str(), fChainId.size());
1747 pTgt+=fChainId.size();
1748 *pTgt++='{';
1749 memcpy(pTgt, componentId, strlen(componentId));
1750 pTgt+=strlen(componentId);
1751 *pTgt++=':';
1752 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
1753 pTgt+=fComponentArgs.size();
1754 *pTgt++='}';
1755 *pTgt++=0;
1756
438635e3 1757 AliHLTComponentBlockData bd;
1758 FillBlockData( bd );
1759 bd.fOffset = offset;
abb52c8f 1760 bd.fSize = payloadSize;
438635e3 1761 bd.fDataType = kAliHLTDataTypeComponentTable;
1762 bd.fSpecification = fChainIdCrc;
438635e3 1763 blocks.push_back(bd);
1764 iResult=bd.fSize;
1765 }
bd6cac58 1766#else
1767 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
1768 // get rid of warning
1769 }
438635e3 1770 #endif
a0aeb701 1771 return iResult;
1772}
1773
90ebac25 1774AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1775 :
1776 fpStopwatch(NULL),
1777 fpPrec(NULL)
1778{
1779 // standard constructor (not for use)
1780}
1781
1782AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1783 :
1784 fpStopwatch(pStopwatch),
1785 fpPrec(NULL)
1786{
1787 // constructor
1788
1789 // check for already existing guard
1790 if (fgpCurrent) fpPrec=fgpCurrent;
1791 fgpCurrent=this;
1792
1793 // stop the preceeding guard if it controls a different stopwatch
1794 int bStart=1;
1795 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1796
1797 // start the stopwatch if the current guard controls a different one
1798 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1799}
1800
e419b223 1801AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 1802 :
1803 fpStopwatch(NULL),
1804 fpPrec(NULL)
1805{
e419b223 1806 //
1807 // copy constructor not for use
1808 //
1809}
1810
1811AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1812{
1813 //
1814 // assignment operator not for use
1815 //
1816 fpStopwatch=NULL;
1817 fpPrec=NULL;
1818 return *this;
90ebac25 1819}
1820
1821AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1822
1823AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1824{
1825 // destructor
1826
1827 // resume the preceeding guard if it controls a different stopwatch
1828 int bStop=1;
1829 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1830
1831 // stop the stopwatch if the current guard controls a different one
1832 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1833
1834 // resume to the preceeding guard
1835 fgpCurrent=fpPrec;
1836}
1837
1838int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1839{
1840 // see header file for function documentation
1841 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1842 return fpStopwatch!=pSucc?1:0;
1843}
1844
1845int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1846{
1847 // see header file for function documentation
1848 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1849 return fpStopwatch!=pSucc?1:0;
1850}
1851
1852int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
1853{
1854 // see header file for function documentation
1855 int iResult=0;
1856 if (pSW!=NULL && type<kSWTypeCount) {
1857 if (fpStopwatches) {
1858 TObject* pObj=fpStopwatches->At((int)type);
1859 if (pSW==NULL // explicit reset
1860 || pObj==NULL) { // explicit set
1861 fpStopwatches->AddAt(pSW, (int)type);
1862 } else if (pObj!=pSW) {
1863 HLTWarning("stopwatch %d already set, reset first", (int)type);
1864 iResult=-EBUSY;
1865 }
1866 }
1867 } else {
1868 iResult=-EINVAL;
1869 }
1870 return iResult;
1871}
1872
1873int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1874{
1875 // see header file for function documentation
1876 if (pStopwatches==NULL) return -EINVAL;
1877
1878 int iResult=0;
1879 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1880 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1881 return iResult;
1882}
559631d5 1883
1884AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1885{
29312178 1886 // see header file for function documentation
45c0a780 1887 if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
559631d5 1888 return fpRunDesc->fRunNo;
1889}
1890
1891AliHLTUInt32_t AliHLTComponent::GetRunType() const
1892{
29312178 1893 // see header file for function documentation
45c0a780 1894 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 1895 return fpRunDesc->fRunType;
1896}
1897
48abe484 1898bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
1899{
1900 // see header file for function documentation
1901 if (pTgt) *pTgt=fEventType;
1902 return (fEventType==gkAliEventTypeData ||
1903 fEventType==gkAliEventTypeDataReplay ||
1904 fEventType==gkAliEventTypeCalibration);
1905}
1906
83fec083 1907int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 1908 const char* structname, const char* eventname)
1909{
29312178 1910 // see header file for function documentation
559631d5 1911 int iResult=0;
1912 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1913 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1914 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1915 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 1916 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 1917 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 1918 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 1919 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1920 }
1921 if (copy!=iStructSize) {
c5123824 1922 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 1923 if (copy>iStructSize) {
1924 copy=iStructSize;
1925 } else {
1926 memset(pTgt, 0, iStructSize);
1927 }
1928 }
3294f81a 1929 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 1930 *pTgt=iStructSize;
1931 iResult=copy;
1932 } else {
1933 HLTWarning("%s event: missing data block", eventname);
1934 }
1935 } else {
1936 iResult=-ENODATA;
1937 }
1938 } else {
1939 HLTError("invalid struct");
1940 iResult=-EINVAL;
1941 }
1942 return iResult;
1943}
ed504011 1944
1945void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1946{
1947 // see header file for function documentation
1948
1949 // -- Detector offset
1950 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
1951
1952 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
1953 Int_t wordBase = 0;
1954
1955 if ( ddlIdBase <= 3 )
1956 wordBase = ddlIdBase;
1957 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1958 wordBase = ddlIdBase + 7;
1959 else
1960 wordBase = ddlIdBase + 9;
1961
1962 // -- Bit index in Word
1963 Int_t bitIdx = ddlId % 32;
1964
1965 // -- Index of word
1966 Int_t wordIdx = wordBase;
1967
1968 // -- if TPC (3) or TOD (5) add word idx
1969 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1970 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1971 }
1972
1973 // -- Set -- 'OR' word with bit mask;
1974 if ( state )
1975 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1976 // -- Unset -- 'AND' word with bit mask;
1977 else
1978 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1979}
1980
1981Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1982{
1983 // see header file for function documentation
1984
1985 Int_t iResult = -1;
1986
1987 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1988
1989 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1990 // check for special cases TPC and TOF
1991 if ( wordNdx > 3 && wordNdx <= 10 ) {
1992 wordNdx = 10;
1993 iResult = 3;
1994 }
1995 else if ( wordNdx > 12 && wordNdx <= 14 ) {
1996 wordNdx = 14;
1997 iResult = 12;
1998 }
1999 else
2000 iResult = wordNdx;
2001 }
2002 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
2003 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
2004 iResult = -1;
2005 break;
2006 }
2007 }
2008
2009 return iResult;
2010}
48abe484 2011
2012AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2013{
2014 // see header file for function documentation
2015 AliHLTUInt32_t remainder = 0;
2016 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2017 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2018 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2019
2020 // code from
2021 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2022
2023 /*
2024 * Perform modulo-2 division, a byte at a time.
2025 */
2026 for (int byte = 0; byte < size; ++byte)
2027 {
2028 /*
2029 * Bring the next byte into the remainder.
2030 */
2031 remainder ^= (buffer[byte] << (crcwidth - 8));
2032
2033 /*
2034 * Perform modulo-2 division, a bit at a time.
2035 */
2036 for (uint8_t bit = 8; bit > 0; --bit)
2037 {
2038 /*
2039 * Try to divide the current data bit.
2040 */
2041 if (remainder & topbit)
2042 {
2043 remainder = (remainder << 1) ^ polynomial;
2044 }
2045 else
2046 {
2047 remainder = (remainder << 1);
2048 }
2049 }
2050 }
2051
2052 /*
2053 * The final remainder is the CRC result.
2054 */
2055 return (remainder);
2056}
abb52c8f 2057
2058int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2059 string& retChainId, string& retCompId, string& retCompArgs,
2060 vector<AliHLTUInt32_t>& parents)
2061{
2062 // see header file for function documentation
2063 retChainId.clear();
2064 retCompId.clear();
2065 retCompArgs.clear();
2066 parents.clear();
2067 if (!pBuffer || size==0) return 0;
2068
2069 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2070 if (size<8/* the initial size of the structure*/ ||
2071 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2072 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2073 const AliHLTUInt8_t* pEnd=pBuffer+size;
2074
2075 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2076 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2077 parents.push_back(*pParents);
2078 }
2079
2080 const char* pDescription=reinterpret_cast<const char*>(pParents);
2081 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2082 *(pDescription+pEntry->fSizeDescription)!=0) {
2083 return -EBADF;
2084 }
2085
2086 TString descriptor=reinterpret_cast<const char*>(pDescription);
2087 TString chainId;
2088 TString compId;
2089 TString compArgs;
2090 TObjArray* pTokens=descriptor.Tokenize("{");
2091 if (pTokens) {
2092 int n=0;
2093 if (pTokens->GetEntries()>n) {
2094 retChainId=((TObjString*)pTokens->At(n++))->GetString();
2095 }
2096 if (pTokens->GetEntries()>n) {
2097 compId=((TObjString*)pTokens->At(n++))->GetString();
2098 }
2099 delete pTokens;
2100 }
2101 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2102 int n=0;
2103 if (pTokens->GetEntries()>n) {
2104 compId=((TObjString*)pTokens->At(n++))->GetString();
2105 }
2106 if (pTokens->GetEntries()>n) {
2107 compArgs=((TObjString*)pTokens->At(n++))->GetString();
2108 }
2109 delete pTokens;
2110 }
2111 compId.ReplaceAll("}", "");
2112 compArgs.ReplaceAll("}", "");
2113
2114 retCompId=compId;
2115 retCompArgs=compArgs;
2116
2117 if (retChainId.size()==0) return -ENODATA;
2118
2119 return 1;
2120}