]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTConfiguration.cxx
workaround for ROOT bug: in order to avoid crashes when unloading
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTConfiguration.cxx
CommitLineData
3495cce2 1// $Id$
2
3/**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * for The ALICE Off-line Project. *
8 * *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
b22e91eb 18/** @file AliHLTConfiguration.cxx
19 @author Matthias Richter
20 @date
21 @brief Implementation of HLT configuration handler.
22*/
3495cce2 23
0c0c9d99 24#if __GNUC__>= 3
3495cce2 25using namespace std;
26#endif
27
a5854ddd 28#include <cerrno>
3495cce2 29#include "AliHLTConfiguration.h"
c38ba6f9 30#include "AliHLTConfigurationHandler.h"
31#include "AliHLTTask.h"
3495cce2 32#include "AliHLTComponent.h"
33#include "AliHLTComponentHandler.h"
34#include <iostream>
a5854ddd 35#include <string>
70ed7d01 36#include "TList.h"
3495cce2 37
b22e91eb 38/** ROOT macro for the implementation of ROOT specific class methods */
3495cce2 39ClassImp(AliHLTConfiguration)
40
41AliHLTConfiguration::AliHLTConfiguration()
85869391 42 :
52c1c164 43 fID(""),
44 fComponent(""),
45 fStringSources(""),
85869391 46 fNofSources(-1),
53feaef5 47 fListSources(),
48 fListSrcElement(),
52c1c164 49 fArguments(""),
85869391 50 fArgc(-1),
53feaef5 51 fArgv(NULL)
3495cce2 52{
70ed7d01 53 // see header file for function documentation
3495cce2 54 fListSrcElement=fListSources.begin();
55}
56
57AliHLTConfiguration::AliHLTConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
85869391 58 :
59 fID(id),
60 fComponent(component),
61 fStringSources(sources),
62 fNofSources(-1),
53feaef5 63 fListSources(),
64 fListSrcElement(),
85869391 65 fArguments(arguments),
66 fArgc(-1),
53feaef5 67 fArgv(NULL)
3495cce2 68{
70ed7d01 69 // see header file for function documentation
85869391 70 fListSrcElement=fListSources.begin();
3495cce2 71 if (id && component) {
70ed7d01 72 if (fgConfigurationHandler) {
73 fgConfigurationHandler->RegisterConfiguration(this);
85465857 74 } else {
75 HLTError("no configuration handler set, abort registration");
76 }
3495cce2 77 }
78}
79
fc455fba 80AliHLTConfiguration::AliHLTConfiguration(const AliHLTConfiguration& src)
85869391 81 :
53feaef5 82 TObject(),
83 AliHLTLogging(),
fc455fba 84 fID(src.fID),
85 fComponent(src.fComponent),
86 fStringSources(src.fStringSources),
85869391 87 fNofSources(-1),
53feaef5 88 fListSources(),
89 fListSrcElement(),
fc455fba 90 fArguments(src.fArguments),
85869391 91 fArgc(-1),
53feaef5 92 fArgv(NULL)
85869391 93{
70ed7d01 94 // see header file for function documentation
85869391 95 fListSrcElement=fListSources.begin();
85869391 96}
97
fc455fba 98AliHLTConfiguration& AliHLTConfiguration::operator=(const AliHLTConfiguration& src)
85869391 99{
70ed7d01 100 // see header file for function documentation
fc455fba 101 fID=src.fID;
102 fComponent=src.fComponent;
103 fStringSources=src.fStringSources;
104 fNofSources=-1;
105 fArguments=src.fArguments;
106 fArgc=-1;
107 fArgv=NULL;
85869391 108 return *this;
109}
110
3495cce2 111AliHLTConfiguration::~AliHLTConfiguration()
112{
70ed7d01 113 // see header file for function documentation
114 if (fgConfigurationHandler) {
52c1c164 115 if (fgConfigurationHandler->FindConfiguration(fID.Data())!=NULL) {
70ed7d01 116 fgConfigurationHandler->RemoveConfiguration(this);
85465857 117 }
3495cce2 118 }
119 if (fArgv != NULL) {
120 if (fArgc>0) {
121 for (int i=0; i<fArgc; i++) {
122 delete[] fArgv[i];
123 }
124 }
125 delete[] fArgv;
126 fArgv=NULL;
127 }
a742f6f8 128
129 vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
130 while (element!=fListSources.end()) {
131 fListSources.erase(element);
132 element=fListSources.begin();
133 }
3495cce2 134}
135
b22e91eb 136/* the global configuration handler which is used to automatically register the configuration
137 */
70ed7d01 138AliHLTConfigurationHandler* AliHLTConfiguration::fgConfigurationHandler=NULL;
b22e91eb 139
85465857 140int AliHLTConfiguration::GlobalInit(AliHLTConfigurationHandler* pHandler)
141{
70ed7d01 142 // see header file for function documentation
85465857 143 int iResult=0;
70ed7d01 144 if (fgConfigurationHandler!=NULL) {
fc455fba 145 fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalInit", HLT_DEFAULT_LOG_KEYWORD, "configuration handler already initialized, overriding object %p with %p", fgConfigurationHandler, pHandler);
85465857 146 }
70ed7d01 147 fgConfigurationHandler=pHandler;
85465857 148 return iResult;
149}
150
fc455fba 151int AliHLTConfiguration::GlobalDeinit(AliHLTConfigurationHandler* pHandler)
85465857 152{
70ed7d01 153 // see header file for function documentation
85465857 154 int iResult=0;
fc455fba 155 if (pHandler!=NULL && fgConfigurationHandler!=pHandler) {
156 fgConfigurationHandler->Logging(kHLTLogWarning, "AliHLTConfiguration::GlobalDeinit", HLT_DEFAULT_LOG_KEYWORD, "handler %p is not set, skip ...", pHandler);
157 return -EBADF;
158 }
70ed7d01 159 fgConfigurationHandler=NULL;
85465857 160 return iResult;
161}
162
70ed7d01 163const char* AliHLTConfiguration::GetName() const
164{
165 // see header file for function documentation
52c1c164 166 if (!fID.IsNull())
167 return fID.Data();
3495cce2 168 return TObject::GetName();
169}
170
171AliHLTConfiguration* AliHLTConfiguration::GetSource(const char* id)
172{
70ed7d01 173 // see header file for function documentation
3495cce2 174 AliHLTConfiguration* pSrc=NULL;
175 if (id) {
176 // first check the current element
177 if (fListSrcElement!=fListSources.end() && strcmp(id, (*fListSrcElement)->GetName())==0) {
178 pSrc=*fListSrcElement;
179 } else {
180 // check the list
181
182 pSrc=GetFirstSource();
183 while (pSrc) {
184 if (strcmp(id, pSrc->GetName())==0)
185 break;
186 pSrc=GetNextSource();
187 }
188 }
189 }
190 return pSrc;
191}
192
193AliHLTConfiguration* AliHLTConfiguration::GetFirstSource()
194{
70ed7d01 195 // see header file for function documentation
3495cce2 196 AliHLTConfiguration* pSrc=NULL;
197 if (fNofSources>=0 || ExtractSources()) {
198 fListSrcElement=fListSources.begin();
199 if (fListSrcElement!=fListSources.end()) pSrc=*fListSrcElement;
200 }
201 return pSrc;
202}
203
204AliHLTConfiguration* AliHLTConfiguration::GetNextSource()
205{
70ed7d01 206 // see header file for function documentation
3495cce2 207 AliHLTConfiguration* pSrc=NULL;
208 if (fNofSources>0) {
209 if (fListSrcElement!=fListSources.end() && (++fListSrcElement)!=fListSources.end())
210 pSrc=*fListSrcElement;
211 }
212 return pSrc;
213}
214
215int AliHLTConfiguration::SourcesResolved(int bAuto)
216{
70ed7d01 217 // see header file for function documentation
3495cce2 218 int iResult=0;
219 if (fNofSources>=0 || bAuto && (iResult=ExtractSources())>=0) {
85465857 220 //HLTDebug("fNofSources=%d", fNofSources);
221 //HLTDebug("list size = %d", fListSources.size());
3495cce2 222 iResult=fNofSources==(int)fListSources.size();
223 }
224 return iResult;
225}
226
227int AliHLTConfiguration::InvalidateSource(AliHLTConfiguration* pConf)
228{
70ed7d01 229 // see header file for function documentation
3495cce2 230 int iResult=0;
231 if (pConf) {
232 vector<AliHLTConfiguration*>::iterator element=fListSources.begin();
233 while (element!=fListSources.end()) {
234 if (*element==pConf) {
235 fListSources.erase(element);
236 fListSrcElement=fListSources.end();
237 // there is no need to re-evaluate until there was a new configuration registered
238 // -> postpone the invalidation, its done in AliHLTConfigurationHandler::RegisterConfiguration
239 //InvalidateSources();
240 break;
241 }
242 element++;
243 }
244 } else {
245 iResult=-EINVAL;
246 }
247 return iResult;
248}
249
250void AliHLTConfiguration::PrintStatus()
251{
70ed7d01 252 // see header file for function documentation
85465857 253 HLTLogKeyword("configuration status");
254 HLTMessage("status of configuration \"%s\" (%p)", GetName(), this);
52c1c164 255 if (!fComponent.IsNull()) HLTMessage(" - component: \"%s\"", fComponent.Data());
85465857 256 else HLTMessage(" - component string invalid");
52c1c164 257 if (!fStringSources.IsNull()) HLTMessage(" - sources: \"%s\"", fStringSources.Data());
85465857 258 else HLTMessage(" - no sources");
3495cce2 259 if (SourcesResolved(1)<=0)
85465857 260 HLTMessage(" there are unresolved sources");
3495cce2 261 AliHLTConfiguration* pSrc=GetFirstSource();
262 while (pSrc) {
85465857 263 HLTMessage(" source \"%s\" (%p) resolved", pSrc->GetName(), pSrc);
3495cce2 264 pSrc=GetNextSource();
265 }
266}
267
0c0c9d99 268int AliHLTConfiguration::GetArguments(const char*** pArgv)
3495cce2 269{
70ed7d01 270 // see header file for function documentation
3495cce2 271 int iResult=0;
0c0c9d99 272 if (pArgv) {
9ce4bf4a 273 if (fArgc==-1) {
274 if ((iResult=ExtractArguments())<0) {
275 HLTError("error extracting arguments for configuration %s", GetName());
276 fArgc=-EINVAL;
277 }
278 } else if (fArgc<0) {
279 HLTError("previous argument extraction failed");
280 }
281 //HLTDebug("%s fArgc %d", GetName(), fArgc);
0c0c9d99 282 iResult=fArgc;
3495cce2 283 *pArgv=(const char**)fArgv;
284 } else {
9ce4bf4a 285 HLTError("invalid parameter");
3495cce2 286 iResult=-EINVAL;
287 }
288 return iResult;
289}
290
291
292int AliHLTConfiguration::ExtractSources()
293{
70ed7d01 294 // see header file for function documentation
3495cce2 295 int iResult=0;
296 fNofSources=0;
52c1c164 297 if (!fStringSources.IsNull()) {
3495cce2 298 vector<char*> tgtList;
299 fListSources.clear();
52c1c164 300 if ((iResult=InterpreteString(fStringSources.Data(), tgtList))>=0) {
3495cce2 301 fNofSources=tgtList.size();
302 vector<char*>::iterator element=tgtList.begin();
85465857 303 while ((element=tgtList.begin())!=tgtList.end()) {
70ed7d01 304 if (fgConfigurationHandler) {
305 AliHLTConfiguration* pConf=fgConfigurationHandler->FindConfiguration(*element);
85465857 306 if (pConf) {
a742f6f8 307 //HLTDebug("configuration %s (%p): source \"%s\" (%p) inserted", GetName(), this, pConf->GetName(), pConf);
85465857 308 fListSources.push_back(pConf);
309 } else {
310 HLTError("can not find source \"%s\"", (*element));
311 iResult=-ENOENT;
312 }
313 } else if (iResult>=0) {
314 iResult=-EFAULT;
315 HLTFatal("global configuration handler not initialized, can not resolve sources");
3495cce2 316 }
317 delete[] (*element);
318 tgtList.erase(element);
319 }
320 fListSrcElement=fListSources.begin();
321 }
322 }
323 return iResult;
324}
325
326int AliHLTConfiguration::ExtractArguments()
327{
70ed7d01 328 // see header file for function documentation
3495cce2 329 int iResult=0;
52c1c164 330 if (!fArguments.IsNull()) {
3495cce2 331 vector<char*> tgtList;
332 if ((iResult=InterpreteString(fArguments, tgtList))>=0) {
333 fArgc=tgtList.size();
9ce4bf4a 334 //HLTDebug("configuration %s: extracted %d arguments from \"%s\"", GetName(), fArgc, fArguments);
3495cce2 335 if (fArgc>0) {
336 fArgv = new char*[fArgc];
337 if (fArgv) {
338 vector<char*>::iterator element=tgtList.begin();
339 int i=0;
340 while (element!=tgtList.end()) {
85465857 341 //HLTDebug("assign arguments %d (%s)", i, *element);
3495cce2 342 fArgv[i++]=(*element);
343 element++;
344 }
345 } else {
346 iResult=-ENOMEM;
347 }
348 }
349 }
9ce4bf4a 350 } else {
351 // there are zero arguments
352 fArgc=0;
3495cce2 353 }
354 return iResult;
355}
356
357int AliHLTConfiguration::InterpreteString(const char* arg, vector<char*>& argList)
358{
70ed7d01 359 // see header file for function documentation
3495cce2 360 int iResult=0;
361 if (arg) {
85465857 362 //HLTDebug("interprete \"%s\"", arg);
3495cce2 363 int i=0;
364 int prec=-1;
5f5b708b 365 int bQuote=0;
3495cce2 366 do {
5f5b708b 367 //HLTDebug("%d %x", i, arg[i]);
368 if (arg[i]=='\'' && bQuote==0) {
369 bQuote=1;
370 } else if (arg[i]==0 ||
371 (arg[i]==' ' && bQuote==0) ||
372 (arg[i]=='\'' && bQuote==1)) {
373 bQuote=0;
3495cce2 374 if (prec>=0) {
375 char* pEntry= new char[i-prec+1];
376 if (pEntry) {
377 strncpy(pEntry, &arg[prec], i-prec);
378 pEntry[i-prec]=0; // terminate string
85465857 379 //HLTDebug("create string \"%s\", insert at %d", pEntry, argList.size());
3495cce2 380 argList.push_back(pEntry);
381 } else
382 iResult=-ENOMEM;
383 prec=-1;
384 }
385 } else if (prec==-1) prec=i;
386 } while (arg[i++]!=0 && iResult>=0);
387 } else {
388 iResult=-EINVAL;
389 }
390 return iResult;
391}
392
393int AliHLTConfiguration::FollowDependency(const char* id, TList* pTgtList)
394{
70ed7d01 395 // see header file for function documentation
3495cce2 396 int iResult=0;
397 if (id) {
398 AliHLTConfiguration* pDep=NULL;
399 if ((pDep=GetSource(id))!=NULL) {
400 if (pTgtList) pTgtList->Add(pDep);
401 iResult++;
402 } else {
403 pDep=GetFirstSource();
404 while (pDep && iResult==0) {
405 if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
406 if (pTgtList) pTgtList->AddFirst(pDep);
407 iResult++;
408 }
409 pDep=GetNextSource();
410 }
411 }
412 } else {
413 iResult=-EINVAL;
414 }
415 return iResult;
416}
417
418///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
419
b22e91eb 420/** ROOT macro for the implementation of ROOT specific class methods */
3495cce2 421ClassImp(AliHLTTask)
422
423AliHLTTask::AliHLTTask()
85869391 424 :
425 fpConfiguration(NULL),
426 fpComponent(NULL),
85869391 427 fpDataBuffer(NULL),
428 fListTargets(),
53feaef5 429 fListDependencies(),
430 fpBlockDataArray(NULL),
431 fBlockDataArraySize(0)
3495cce2 432{
70ed7d01 433 // see header file for function documentation
3495cce2 434}
435
53feaef5 436AliHLTTask::AliHLTTask(AliHLTConfiguration* pConf)
85869391 437 :
53feaef5 438 fpConfiguration(pConf),
85869391 439 fpComponent(NULL),
85869391 440 fpDataBuffer(NULL),
441 fListTargets(),
53feaef5 442 fListDependencies(),
443 fpBlockDataArray(NULL),
444 fBlockDataArraySize(0)
3495cce2 445{
70ed7d01 446 // see header file for function documentation
3495cce2 447}
448
85869391 449AliHLTTask::AliHLTTask(const AliHLTTask&)
450 :
53feaef5 451 TObject(),
452 AliHLTLogging(),
85869391 453 fpConfiguration(NULL),
454 fpComponent(NULL),
85869391 455 fpDataBuffer(NULL),
456 fListTargets(),
53feaef5 457 fListDependencies(),
458 fpBlockDataArray(NULL),
459 fBlockDataArraySize(0)
85869391 460{
461 HLTFatal("copy constructor untested");
462}
463
464AliHLTTask& AliHLTTask::operator=(const AliHLTTask&)
465{
70ed7d01 466 // see header file for function documentation
85869391 467 HLTFatal("assignment operator untested");
468 return *this;
469}
470
3495cce2 471AliHLTTask::~AliHLTTask()
472{
a742f6f8 473 TObjLink* lnk=fListDependencies.FirstLink();
474
475 while (lnk!=NULL) {
476 AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
477 pTask->UnsetTarget(this);
478 lnk=lnk->Next();
479 }
480 lnk=fListTargets.FirstLink();
481
482 while (lnk!=NULL) {
483 AliHLTTask* pTask=(AliHLTTask*)lnk->GetObject();
484 pTask->UnsetDependency(this);
485 lnk=lnk->Next();
486 }
487
3495cce2 488 if (fpComponent) delete fpComponent;
489 fpComponent=NULL;
490 if (fpBlockDataArray) delete[] fpBlockDataArray;
491 fpBlockDataArray=NULL;
492}
493
53feaef5 494int AliHLTTask::Init(AliHLTConfiguration* pConf, AliHLTComponentHandler* pCH)
3495cce2 495{
70ed7d01 496 // see header file for function documentation
3495cce2 497 int iResult=0;
9ce4bf4a 498 if (fpConfiguration!=NULL && pConf!=NULL && fpConfiguration!=pConf) {
2d7ff710 499 HLTWarning("overriding existing reference to configuration object %p (%s) by %p",
53feaef5 500 fpConfiguration, GetName(), pConf);
501 }
502 if (pConf!=NULL) fpConfiguration=pConf;
503 if (fpConfiguration) {
3495cce2 504 if (pCH) {
505 int argc=0;
506 const char** argv=NULL;
53feaef5 507 if ((iResult=fpConfiguration->GetArguments(&argv))>=0) {
0c0c9d99 508 argc=iResult; // just to make it clear
2d7ff710 509 // TODO: we have to think about the optional environment parameter,
510 // currently just set to NULL.
53feaef5 511 iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
9ce4bf4a 512 if (fpComponent || iResult<=0) {
a742f6f8 513 //HLTDebug("component %s (%p) created", fpComponent->GetComponentID(), fpComponent);
3495cce2 514 } else {
9ce4bf4a 515 HLTError("can not find component \"%s\" (%d)", fpConfiguration->GetComponentID(), iResult);
3495cce2 516 }
9ce4bf4a 517 } else {
518 HLTError("can not get argument list for configuration %s (%s)", fpConfiguration->GetName(), fpConfiguration->GetComponentID());
519 iResult=-EINVAL;
3495cce2 520 }
53feaef5 521 } else {
522 HLTError("component handler instance needed for task initialization");
523 iResult=-EINVAL;
3495cce2 524 }
525 } else {
53feaef5 526 HLTError("configuration object instance needed for task initialization");
3495cce2 527 iResult=-EINVAL;
528 }
529 return iResult;
530}
531
53feaef5 532int AliHLTTask::Deinit()
533{
70ed7d01 534 // see header file for function documentation
2d7ff710 535 int iResult=0;
536 AliHLTComponent* pComponent=GetComponent();
537 fpComponent=NULL;
538 if (pComponent) {
a742f6f8 539 //HLTDebug("delete component %s (%p)", pComponent->GetComponentID(), pComponent);
2d7ff710 540 pComponent->Deinit();
541 delete pComponent;
542 } else {
543 HLTWarning("task %s (%p) doesn't seem to be in initialized", GetName(), this);
544 }
545 return iResult;
53feaef5 546}
547
3495cce2 548const char *AliHLTTask::GetName() const
549{
70ed7d01 550 // see header file for function documentation
3495cce2 551 if (fpConfiguration)
552 return fpConfiguration->GetName();
553 return TObject::GetName();
554}
555
0c0c9d99 556AliHLTConfiguration* AliHLTTask::GetConf() const
3495cce2 557{
70ed7d01 558 // see header file for function documentation
3495cce2 559 return fpConfiguration;
560}
561
0c0c9d99 562AliHLTComponent* AliHLTTask::GetComponent() const
3495cce2 563{
70ed7d01 564 // see header file for function documentation
3495cce2 565 return fpComponent;
566}
567
568AliHLTTask* AliHLTTask::FindDependency(const char* id)
569{
70ed7d01 570 // see header file for function documentation
3495cce2 571 AliHLTTask* pTask=NULL;
572 if (id) {
573 pTask=(AliHLTTask*)fListDependencies.FindObject(id);
574 }
575 return pTask;
576}
577
578int AliHLTTask::FollowDependency(const char* id, TList* pTgtList)
579{
70ed7d01 580 // see header file for function documentation
3495cce2 581 int iResult=0;
582 if (id) {
583 AliHLTTask* pDep=NULL;
584 if ((pDep=(AliHLTTask*)fListDependencies.FindObject(id))!=NULL) {
585 if (pTgtList) pTgtList->Add(pDep);
586 iResult++;
587 } else {
588 TObjLink* lnk=fListDependencies.FirstLink();
589 while (lnk && iResult==0) {
590 pDep=(AliHLTTask*)lnk->GetObject();
591 if (pDep) {
592 if ((iResult=pDep->FollowDependency(id, pTgtList))>0) {
593 if (pTgtList) pTgtList->AddFirst(pDep);
594 iResult++;
595 }
596 } else {
597 iResult=-EFAULT;
598 }
599 lnk=lnk->Next();
600 }
601 }
602 } else {
603 iResult=-EINVAL;
604 }
605 return iResult;
606}
607
608void AliHLTTask::PrintDependencyTree(const char* id, int bFromConfiguration)
609{
70ed7d01 610 // see header file for function documentation
85465857 611 HLTLogKeyword("task dependencies");
3495cce2 612 int iResult=0;
613 TList tgtList;
614 if (bFromConfiguration) {
615 if (fpConfiguration)
616 iResult=fpConfiguration->FollowDependency(id, &tgtList);
617 else
618 iResult=-EFAULT;
619 } else
620 iResult=FollowDependency(id, &tgtList);
621 if (iResult>0) {
85465857 622 HLTMessage(" task \"%s\": dependency level %d ", GetName(), iResult);
3495cce2 623 TObjLink* lnk=tgtList.FirstLink();
624 int i=iResult;
625 char* pSpace = new char[iResult+1];
626 if (pSpace) {
627 memset(pSpace, 32, iResult);
628 pSpace[i]=0;
629 while (lnk) {
630 TObject* obj=lnk->GetObject();
85465857 631 HLTMessage(" %s^-- %s ", &pSpace[i--], obj->GetName());
3495cce2 632 lnk=lnk->Next();
633 }
634 delete [] pSpace;
635 } else {
636 iResult=-ENOMEM;
637 }
638 }
639}
640
3495cce2 641int AliHLTTask::SetDependency(AliHLTTask* pDep)
642{
70ed7d01 643 // see header file for function documentation
3495cce2 644 int iResult=0;
645 if (pDep) {
646 if (FindDependency(pDep->GetName())==NULL) {
647 fListDependencies.Add(pDep);
648 } else {
649 iResult=-EEXIST;
650 }
651 } else {
652 iResult=-EINVAL;
653 }
654 return iResult;
655}
656
a742f6f8 657int AliHLTTask::UnsetDependency(AliHLTTask* pDep)
658{
659 fListDependencies.Remove(pDep);
660 if (fpConfiguration) {
661 fpConfiguration->InvalidateSources();
662 }
663 return 0;
664}
665
3495cce2 666int AliHLTTask::CheckDependencies()
667{
70ed7d01 668 // see header file for function documentation
3495cce2 669 int iResult=0;
670 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
671 while (pSrc) {
672 if (FindDependency(pSrc->GetName())==NULL) {
85465857 673 //HLTDebug("dependency \"%s\" unresolved", pSrc->GetName());
3495cce2 674 iResult++;
675 }
676 pSrc=fpConfiguration->GetNextSource();
677 }
678 return iResult;
679}
680
681
682int AliHLTTask::Depends(AliHLTTask* pTask)
683{
70ed7d01 684 // see header file for function documentation
3495cce2 685 int iResult=0;
686 if (pTask) {
687 if (fpConfiguration) {
688 iResult=fpConfiguration->GetSource(pTask->GetName())!=NULL;
689 if (iResult>0) {
85465857 690 //HLTDebug("task \"%s\" depends on \"%s\"", GetName(), pTask->GetName());
3495cce2 691 } else {
85465857 692 //HLTDebug("task \"%s\" independend of \"%s\"", GetName(), pTask->GetName());
3495cce2 693 }
694 } else {
695 iResult=-EFAULT;
696 }
697 } else {
698 iResult=-EINVAL;
699 }
700 return iResult;
701}
702
703AliHLTTask* AliHLTTask::FindTarget(const char* id)
704{
70ed7d01 705 // see header file for function documentation
3495cce2 706 AliHLTTask* pTask=NULL;
707 if (id) {
708 pTask=(AliHLTTask*)fListTargets.FindObject(id);
709 }
710 return pTask;
711}
712
713int AliHLTTask::SetTarget(AliHLTTask* pTgt)
714{
70ed7d01 715 // see header file for function documentation
3495cce2 716 int iResult=0;
717 if (pTgt) {
718 if (FindTarget(pTgt->GetName())==NULL) {
719 fListTargets.Add(pTgt);
720 } else {
721 iResult=-EEXIST;
722 }
723 } else {
724 iResult=-EINVAL;
725 }
726 return iResult;
727}
728
a742f6f8 729int AliHLTTask::UnsetTarget(AliHLTTask* pTarget)
730{
731 fListTargets.Remove(pTarget);
732 return 0;
733}
734
0c0c9d99 735int AliHLTTask::StartRun()
736{
70ed7d01 737 // see header file for function documentation
0c0c9d99 738 int iResult=0;
739 int iNofInputDataBlocks=0;
740 AliHLTComponent* pComponent=GetComponent();
741 if (pComponent) {
742 // determine the number of input data blocks provided from the source tasks
743 TObjLink* lnk=fListDependencies.FirstLink();
744 while (lnk && iResult>=0) {
745 AliHLTTask* pSrcTask=(AliHLTTask*)lnk->GetObject();
746 if (pSrcTask) {
747 if ((iResult=pSrcTask->GetNofMatchingDataTypes(this))>0) {
748 iNofInputDataBlocks+=iResult;
749 } else if (iResult==0) {
750 HLTWarning("source task %s (%p) does not provide any matching data type for task %s (%p)", pSrcTask->GetName(), pSrcTask, GetName(), this);
751 } else {
752 HLTError("task %s (%p): error getting matching data types for source task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
753 iResult=-EFAULT;
754 }
755 }
756 lnk=lnk->Next();
757 }
758 if (iResult>=0) {
759 if (fpBlockDataArray) {
760 HLTWarning("block data array for task %s (%p) was not cleaned", GetName(), this);
761 delete [] fpBlockDataArray;
762 fpBlockDataArray=NULL;
763 fBlockDataArraySize=0;
764 }
765
766 // component init
2d7ff710 767 // the initialization of the component is done by the ComponentHandler after creation
768 // of the component.
0c0c9d99 769 //iResult=Init( AliHLTComponentEnvironment* environ, void* environ_param, int argc, const char** argv );
770
2d7ff710 771 // allocate internal task variables for bookkeeping aso.
9ce4bf4a 772 // we allocate the BlockData array with at least one member
773 if (iNofInputDataBlocks==0) iNofInputDataBlocks=1;
8ede8717 774 fpBlockDataArray=new AliHLTComponentBlockData[iNofInputDataBlocks];
0c0c9d99 775 if (fpBlockDataArray) {
776 fBlockDataArraySize=iNofInputDataBlocks;
777 } else {
778 HLTError("memory allocation failed");
779 iResult=-ENOMEM;
780 }
9ce4bf4a 781
782 // allocate the data buffer, which controls the output buffer and subscriptions
783 if (iResult>=0) {
784 fpDataBuffer=new AliHLTDataBuffer;
785 if (fpDataBuffer!=NULL) {
786 HLTDebug("created data buffer %p for task %s (%p)", fpDataBuffer, GetName(), this);
787 TObjLink* lnk=fListTargets.FirstLink();
788 while (lnk && iResult>=0) {
789 AliHLTTask* pTgtTask=(AliHLTTask*)lnk->GetObject();
790 if (pTgtTask) {
791 if ((iResult=fpDataBuffer->SetConsumer(pTgtTask->GetComponent()))>=0) {
792 }
793 } else {
794 break;
795 iResult=-EFAULT;
796 }
797 lnk=lnk->Next();
798 }
799 } else {
800 HLTFatal("can not create data buffer object, memory allocation failed");
801 iResult=-ENOMEM;
802 }
803 }
0c0c9d99 804 }
805 } else {
806 HLTError("task %s (%p) does not have a component", GetName(), this);
807 iResult=-EFAULT;
808 }
809 return iResult;
810}
3495cce2 811
0c0c9d99 812int AliHLTTask::EndRun()
813{
70ed7d01 814 // see header file for function documentation
0c0c9d99 815 int iResult=0;
2d7ff710 816 if (fpBlockDataArray) {
817 fBlockDataArraySize=0;
818 delete [] fpBlockDataArray;
819 fpBlockDataArray=0;
820 } else {
821 HLTWarning("task %s (%p) doesn't seem to be in running mode", GetName(), this);
822 }
9ce4bf4a 823 if (fpDataBuffer) {
824 AliHLTDataBuffer* pBuffer=fpDataBuffer;
825 fpDataBuffer=NULL;
826 delete pBuffer;
827 }
0c0c9d99 828 return iResult;
829}
3495cce2 830
9ce4bf4a 831int AliHLTTask::ProcessTask(Int_t eventNo)
0c0c9d99 832{
70ed7d01 833 // see header file for function documentation
0c0c9d99 834 int iResult=0;
2d7ff710 835 AliHLTComponent* pComponent=GetComponent();
9ce4bf4a 836 if (pComponent && fpDataBuffer) {
837 HLTDebug("Processing task %s (%p) fpDataBuffer %p", GetName(), this, fpDataBuffer);
838 fpDataBuffer->Reset();
0c0c9d99 839 int iSourceDataBlock=0;
840 int iInputDataVolume=0;
841
842 int iNofInputDataBlocks=0;
843 /* TODO: the assumption of only one output data type per component is the current constraint
844 * later it should be checked how many output blocks of the source component match the input
845 * data types of the consumer component (GetNofMatchingDataBlocks). If one assumes that a
846 * certain output block is always been produced, the initialization could be done in the
847 * StartRun. Otherwise the fpBlockDataArray has to be adapted each time.
848 */
849 iNofInputDataBlocks=fListDependencies.GetSize(); // one block per source
850 // is not been used since the allocation was done in StartRun, but check the size
851 if (iNofInputDataBlocks>fBlockDataArraySize) {
852 HLTError("block data array too small");
853 }
854
855 AliHLTTask* pSrcTask=NULL;
856 TList subscribedTaskList;
857 TObjLink* lnk=fListDependencies.FirstLink();
858
859 // subscribe to all source tasks
860 while (lnk && iResult>=0) {
861 pSrcTask=(AliHLTTask*)lnk->GetObject();
862 if (pSrcTask) {
9ce4bf4a 863 int iMatchingDB=pSrcTask->GetNofMatchingDataBlocks(this);
864 if (iMatchingDB<=fBlockDataArraySize-iSourceDataBlock) {
865 if (fpBlockDataArray) {
0c0c9d99 866 if ((iResult=pSrcTask->Subscribe(this, &fpBlockDataArray[iSourceDataBlock],fBlockDataArraySize-iSourceDataBlock))>0) {
867 for (int i=0; i<iResult; i++) {
868 iInputDataVolume+=fpBlockDataArray[i+iSourceDataBlock].fSize;
869 // put the source task as many times into the list as it provides data blocks
870 // makes the bookkeeping for the data release easier
871 subscribedTaskList.Add(pSrcTask);
872 }
873 iSourceDataBlock+=iResult;
9ce4bf4a 874 HLTDebug("Task %s (%p) successfully subscribed to %d data block(s) of task %s (%p)", GetName(), this, iResult, pSrcTask->GetName(), pSrcTask);
0c0c9d99 875 iResult=0;
876 } else {
877 HLTError("Task %s (%p): subscription to task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iResult);
878 iResult=-EFAULT;
879 }
9ce4bf4a 880 } else {
881 HLTFatal("Task %s (%p): BlockData array not allocated", GetName(), this);
882 iResult=-EFAULT;
883 }
0c0c9d99 884 } else {
885 HLTFatal("Task %s (%p): too little space in data block array for subscription to task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
9ce4bf4a 886 HLTDebug("#data types=%d, array size=%d, current index=%d", iMatchingDB, fBlockDataArraySize, iSourceDataBlock);
0c0c9d99 887 iResult=-EFAULT;
888 }
889 } else {
890 HLTFatal("fatal internal error in ROOT list handling");
891 iResult=-EFAULT;
892 }
893 lnk=lnk->Next();
894 }
895
896 // process the event
897 if (iResult>=0) {
898 long unsigned int iConstBase=0;
899 double fInputMultiplier=0;
9ce4bf4a 900 if (pComponent->GetComponentType()!=AliHLTComponent::kSink)
901 pComponent->GetOutputDataSize(iConstBase, fInputMultiplier);
0c0c9d99 902 int iOutputDataSize=int(fInputMultiplier*iInputDataVolume) + iConstBase;
9ce4bf4a 903 //HLTDebug("task %s: reqired output size %d", GetName(), iOutputDataSize);
904 AliHLTUInt8_t* pTgtBuffer=NULL;
905 if (iOutputDataSize>0) pTgtBuffer=fpDataBuffer->GetTargetBuffer(iOutputDataSize);
906 //HLTDebug("provided raw buffer %p", pTgtBuffer);
8ede8717 907 AliHLTComponentEventData evtData;
9ce4bf4a 908 AliHLTComponent::FillEventData(evtData);
909 evtData.fEventID=(AliHLTEventID_t)eventNo;
910 evtData.fBlockCnt=iSourceDataBlock;
8ede8717 911 AliHLTComponentTriggerData trigData;
0c0c9d99 912 AliHLTUInt32_t size=iOutputDataSize;
913 AliHLTUInt32_t outputBlockCnt=0;
8ede8717 914 AliHLTComponentBlockData* outputBlocks=NULL;
915 AliHLTComponentEventDoneData* edd;
0c0c9d99 916 if (pTgtBuffer!=NULL || iOutputDataSize==0) {
2d7ff710 917 iResult=pComponent->ProcessEvent(evtData, fpBlockDataArray, trigData, pTgtBuffer, size, outputBlockCnt, outputBlocks, edd);
9ce4bf4a 918 HLTDebug("task %s: component %s ProcessEvent finnished (%d): size=%d blocks=%d", GetName(), pComponent->GetComponentID(), iResult, size, outputBlockCnt);
919 if (iResult>=0 && pTgtBuffer) {
2d7ff710 920 iResult=fpDataBuffer->SetSegments(pTgtBuffer, outputBlocks, outputBlockCnt);
a742f6f8 921 delete [] outputBlocks; outputBlocks=NULL; outputBlockCnt=0;
2d7ff710 922 }
0c0c9d99 923 } else {
9ce4bf4a 924 HLTError("task %s: no target buffer available", GetName());
925 iResult=-EFAULT;
0c0c9d99 926 }
927 }
928
929 // now release all buffers which we have subscribed to
930 iSourceDataBlock=0;
931 lnk=subscribedTaskList.FirstLink();
932 while (lnk) {
933 pSrcTask=(AliHLTTask*)lnk->GetObject();
934 if (pSrcTask) {
935 int iTempRes=0;
936 if ((iTempRes=pSrcTask->Release(&fpBlockDataArray[iSourceDataBlock], this))>=0) {
937 HLTDebug("Task %s (%p) successfully released task %s (%p)", GetName(), this, pSrcTask->GetName(), pSrcTask);
938 } else {
939 HLTError("Task %s (%p): realease of task %s (%p) failed with error %d", GetName(), this, pSrcTask->GetName(), pSrcTask, iTempRes);
940 }
941 } else {
9ce4bf4a 942 HLTFatal("task %s (%p): internal error in ROOT list handling", GetName(), this);
2d7ff710 943 if (iResult>=0) iResult=-EFAULT;
0c0c9d99 944 }
945 subscribedTaskList.Remove(lnk);
946 lnk=subscribedTaskList.FirstLink();
947 iSourceDataBlock++;
948 }
949 if (subscribedTaskList.GetSize()>0) {
950 HLTError("task %s (%p): could not release all data buffers", GetName(), this);
951 }
952 } else {
9ce4bf4a 953 HLTError("task %s (%p): internal failure (not initialized component %p, data buffer %p)", GetName(), this, fpComponent, fpDataBuffer);
0c0c9d99 954 iResult=-EFAULT;
955 }
956 return iResult;
957}
958
2d7ff710 959int AliHLTTask::GetNofMatchingDataBlocks(const AliHLTTask* pConsumerTask) const
0c0c9d99 960{
70ed7d01 961 // see header file for function documentation
0c0c9d99 962 int iResult=0;
963 if (pConsumerTask) {
964 if (fpDataBuffer) {
965 iResult=fpDataBuffer->FindMatchingDataBlocks(pConsumerTask->GetComponent(), NULL);
966 } else {
967 HLTFatal("internal data buffer missing");
968 iResult=-EFAULT;
969 }
970 } else {
971 iResult=-EINVAL;
972 }
973 return iResult;
974}
975
2d7ff710 976int AliHLTTask::GetNofMatchingDataTypes(const AliHLTTask* pConsumerTask) const
0c0c9d99 977{
70ed7d01 978 // see header file for function documentation
0c0c9d99 979 int iResult=0;
980 if (pConsumerTask) {
981 AliHLTComponent* pComponent=GetComponent();
982 if (!pComponent) {
a655eae3 983 // init ?
984 HLTError("component not initialized");
985 iResult=-EFAULT;
0c0c9d99 986 }
987 if (pComponent) {
988 iResult=pComponent->FindMatchingDataTypes(pConsumerTask->GetComponent(), NULL);
989 } else {
990 HLTFatal("task initialization failed");
991 iResult=-EFAULT;
992 }
993 } else {
994 iResult=-EINVAL;
995 }
996 return iResult;
997}
998
8ede8717 999int AliHLTTask::Subscribe(const AliHLTTask* pConsumerTask, AliHLTComponentBlockData* pBlockDesc, int iArraySize)
0c0c9d99 1000{
70ed7d01 1001 // see header file for function documentation
0c0c9d99 1002 int iResult=0;
1003 if (pConsumerTask) {
1004 if (fpDataBuffer) {
1005 iResult=fpDataBuffer->Subscribe(pConsumerTask->GetComponent(), pBlockDesc, iArraySize);
1006 } else {
1007 HLTFatal("internal data buffer missing");
1008 iResult=-EFAULT;
1009 }
1010 } else {
1011 iResult=-EINVAL;
1012 }
1013 return iResult;
1014}
1015
8ede8717 1016int AliHLTTask::Release(AliHLTComponentBlockData* pBlockDesc, const AliHLTTask* pConsumerTask)
0c0c9d99 1017{
70ed7d01 1018 // see header file for function documentation
0c0c9d99 1019 int iResult=0;
1020 if (pConsumerTask && pBlockDesc) {
1021 if (fpDataBuffer) {
1022 iResult=fpDataBuffer->Release(pBlockDesc, pConsumerTask->GetComponent());
1023 } else {
1024 HLTFatal("internal data buffer missing");
1025 iResult=-EFAULT;
1026 }
1027 } else {
1028 iResult=-EINVAL;
1029 }
1030 return iResult;
1031}
3495cce2 1032
3495cce2 1033void AliHLTTask::PrintStatus()
1034{
70ed7d01 1035 // see header file for function documentation
85465857 1036 HLTLogKeyword("task properties");
2d7ff710 1037 AliHLTComponent* pComponent=GetComponent();
1038 if (pComponent) {
1039 HLTMessage(" component: %s (%p)", pComponent->GetComponentID(), pComponent);
3495cce2 1040 } else {
85465857 1041 HLTMessage(" no component set!");
3495cce2 1042 }
1043 if (fpConfiguration) {
1044 AliHLTConfiguration* pSrc=fpConfiguration->GetFirstSource();
1045 while (pSrc) {
1046 const char* pQualifier="unresolved";
1047 if (FindDependency(pSrc->GetName()))
1048 pQualifier="resolved";
85465857 1049 HLTMessage(" source: %s (%s)", pSrc->GetName(), pQualifier);
3495cce2 1050 pSrc=fpConfiguration->GetNextSource();
1051 }
1052 TObjLink* lnk = fListTargets.FirstLink();
1053 while (lnk) {
1054 TObject *obj = lnk->GetObject();
85465857 1055 HLTMessage(" target: %s", obj->GetName());
3495cce2 1056 lnk = lnk->Next();
1057 }
1058 } else {
85465857 1059 HLTMessage(" task \"%s\" not initialized", GetName());
3495cce2 1060 }
1061}
1062
1063///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1064
b22e91eb 1065/** ROOT macro for the implementation of ROOT specific class methods */
3495cce2 1066ClassImp(AliHLTConfigurationHandler)
1067
1068AliHLTConfigurationHandler::AliHLTConfigurationHandler()
88ea49c8 1069 :
1070 fgListConfigurations()
3495cce2 1071{
70ed7d01 1072 // see header file for function documentation
88ea49c8 1073 SetLocalLoggingLevel(kHLTLogInfo);
3495cce2 1074}
1075
1076AliHLTConfigurationHandler::~AliHLTConfigurationHandler()
1077{
70ed7d01 1078 // see header file for function documentation
a742f6f8 1079 TObjLink* lnk=NULL;
1080 while (lnk=fgListConfigurations.FirstLink()) {
1081 AliHLTConfiguration* pConf=(AliHLTConfiguration*)lnk->GetObject();
1082 HLTDebug("delete configuration \"%s\"", pConf->GetName());
1083 fgListConfigurations.Remove(lnk);
1084 delete pConf;
3495cce2 1085 }
1086}
1087
1088int AliHLTConfigurationHandler::RegisterConfiguration(AliHLTConfiguration* pConf)
1089{
70ed7d01 1090 // see header file for function documentation
3495cce2 1091 int iResult=0;
1092 if (pConf) {
1093 if (FindConfiguration(pConf->GetName()) == NULL) {
fc455fba 1094 AliHLTConfiguration* pClone=new AliHLTConfiguration(*pConf);
1095 fgListConfigurations.Add(pClone);
a742f6f8 1096 HLTDebug("configuration \"%s\" (%p) registered from %p", pClone->GetName(), pClone, pConf);
3495cce2 1097
1098 // mark all configurations with unresolved dependencies for re-evaluation
70ed7d01 1099 TObjLink* lnk=fgListConfigurations.FirstLink();
3495cce2 1100 while (lnk) {
1101 AliHLTConfiguration* pSrc=(AliHLTConfiguration*)lnk->GetObject();
fc455fba 1102 if (pSrc && pSrc!=pClone && pSrc->SourcesResolved()!=1) {
3495cce2 1103 pSrc->InvalidateSources();
1104 }
1105 lnk=lnk->Next();
1106 }
1107 } else {
1108 iResult=-EEXIST;
85465857 1109 HLTWarning("configuration \"%s\" already registered", pConf->GetName());
3495cce2 1110 }
1111 } else {
1112 iResult=-EINVAL;
1113 }
1114 return iResult;
1115}
1116
1117int AliHLTConfigurationHandler::CreateConfiguration(const char* id, const char* component, const char* sources, const char* arguments)
1118{
70ed7d01 1119 // see header file for function documentation
3495cce2 1120 int iResult=0;
1121 AliHLTConfiguration* pConf= new AliHLTConfiguration(id, component, sources, arguments);
1122 if (pConf) {
1123 // the configuration will be registered automatically, if this failes the configuration
1124 // is missing -> delete it
1125 if (FindConfiguration(id)==NULL) {
1126 delete pConf;
1127 pConf=NULL;
1128 iResult=-EEXIST;
3495cce2 1129 }
1130 } else {
85465857 1131 HLTError("system error: object allocation failed");
3495cce2 1132 iResult=-ENOMEM;
1133 }
1134 return iResult;
1135}
1136
1137void AliHLTConfigurationHandler::PrintConfigurations()
1138{
70ed7d01 1139 // see header file for function documentation
85465857 1140 HLTLogKeyword("configuration listing");
1141 HLTMessage("registered configurations:");
70ed7d01 1142 TObjLink *lnk = fgListConfigurations.FirstLink();
3495cce2 1143 while (lnk) {
1144 TObject *obj = lnk->GetObject();
85465857 1145 HLTMessage(" %s", obj->GetName());
3495cce2 1146 lnk = lnk->Next();
1147 }
1148}
1149
1150int AliHLTConfigurationHandler::RemoveConfiguration(const char* id)
1151{
70ed7d01 1152 // see header file for function documentation
3495cce2 1153 int iResult=0;
1154 if (id) {
1155 AliHLTConfiguration* pConf=NULL;
1156 if ((pConf=FindConfiguration(id))!=NULL) {
1157 iResult=RemoveConfiguration(pConf);
fc455fba 1158 delete pConf;
1159 pConf=NULL;
3495cce2 1160 } else {
85465857 1161 HLTWarning("can not find configuration \"%s\"", id);
3495cce2 1162 iResult=-ENOENT;
1163 }
1164 } else {
1165 iResult=-EINVAL;
1166 }
1167 return iResult;
1168}
1169
1170int AliHLTConfigurationHandler::RemoveConfiguration(AliHLTConfiguration* pConf)
1171{
70ed7d01 1172 // see header file for function documentation
3495cce2 1173 int iResult=0;
1174 if (pConf) {
1175 // remove the configuration from the list
9ce4bf4a 1176 HLTDebug("remove configuration \"%s\"", pConf->GetName());
70ed7d01 1177 fgListConfigurations.Remove(pConf);
3495cce2 1178 // remove cross links in the remaining configurations
70ed7d01 1179 TObjLink* lnk=fgListConfigurations.FirstLink();
3495cce2 1180 while (lnk && iResult>=0) {
1181 AliHLTConfiguration* pRem=(AliHLTConfiguration*)lnk->GetObject();
1182 if (pRem) {
1183 pRem->InvalidateSource(pConf);
1184 } else {
1185 iResult=-EFAULT;
1186 }
1187 lnk=lnk->Next();
1188 }
1189 }
1190 return iResult;
1191}
1192
1193AliHLTConfiguration* AliHLTConfigurationHandler::FindConfiguration(const char* id)
1194{
70ed7d01 1195 // see header file for function documentation
3495cce2 1196 AliHLTConfiguration* pConf=NULL;
1197 if (id) {
70ed7d01 1198 pConf=(AliHLTConfiguration*)fgListConfigurations.FindObject(id);
3495cce2 1199 }
1200 return pConf;
1201}
1202