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