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