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