]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
bubgfix: skip configurations fram agent if config file was specified; SetFrameworkLog...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2
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  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTSystem.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Implementation of HLT module management.
23 */
24
25 #if __GNUC__>= 3
26 using namespace std;
27 #endif
28
29 #include <cassert>
30 #include "AliHLTStdIncludes.h"
31 #include "AliHLTSystem.h"
32 #include "AliHLTComponentHandler.h"
33 #include "AliHLTComponent.h"
34 #include "AliHLTConfiguration.h"
35 #include "AliHLTConfigurationHandler.h"
36 #include "AliHLTTask.h"
37 #include "AliHLTModuleAgent.h"
38 #include "AliHLTOfflineInterface.h"
39 #include <TObjArray.h>
40 #include <TObjString.h>
41 #include <TStopwatch.h>
42 //#include <TSystem.h>
43 #include <TROOT.h>
44 #include <TInterpreter.h>
45
46 /** HLT default component libraries */
47 const char* kHLTDefaultLibs[]= {
48   "libAliHLTUtil.so", 
49   "libAliHLTTPC.so", 
50   //  "libAliHLTSample.so",
51   //"libAliHLTPHOS.so",
52   //"libAliHLTMUON.so",
53   "libAliHLTTRD.so",
54   NULL
55 };
56
57 /** ROOT macro for the implementation of ROOT specific class methods */
58 ClassImp(AliHLTSystem)
59
60 AliHLTSystem::AliHLTSystem()
61   :
62   fpComponentHandler(new AliHLTComponentHandler()),
63   fpConfigurationHandler(new AliHLTConfigurationHandler()),
64   fTaskList(),
65   fState(0),
66   fChains(),
67   fStopwatches(new TObjArray),
68   fEventCount(-1),
69   fGoodEvents(-1)
70 {
71   // see header file for class documentation
72   // or
73   // refer to README to build package
74   // or
75   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
76
77   if (fgNofInstances++>0)
78     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
79
80   SetGlobalLoggingLevel(kHLTLogDefault);
81   SetFrameworkLog(kHLTLogDefault);
82   if (fpComponentHandler) {
83     AliHLTComponentEnvironment env;
84     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
85     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
86     env.fLoggingFunc=NULL;
87     fpComponentHandler->SetEnvironment(&env);
88     InitAliLogFunc(fpComponentHandler);
89     fpComponentHandler->AnnounceVersion();
90   } else {
91     HLTFatal("can not create Component Handler");
92   }
93   if (fpConfigurationHandler) {
94     AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
95   } else {
96     HLTFatal("can not create Configuration Handler");
97   }
98 }
99
100 AliHLTSystem::~AliHLTSystem()
101 {
102   // see header file for class documentation
103   fgNofInstances--;
104   CleanTaskList();
105   AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
106   if (fpConfigurationHandler) {
107     delete fpConfigurationHandler;
108   }
109   fpConfigurationHandler=NULL;
110   
111   if (fpComponentHandler) {
112     delete fpComponentHandler;
113   }
114   fpComponentHandler=NULL;
115 }
116
117 int AliHLTSystem::fgNofInstances=0;
118
119 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
120 {
121   // see header file for class documentation
122   int iResult=0;
123   if (pConf) {
124   } else {
125     iResult=-EINVAL;
126   }
127   return iResult;
128 }
129
130 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
131 {
132   // see header file for class documentation
133   int iResult=0;
134   if (pConf) {
135     if (pPrec) {
136       // find the position
137     }
138   } else {
139     iResult=-EINVAL;
140   }
141   return iResult;
142 }
143
144 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
145 {
146   // see header file for class documentation
147   int iResult=0;
148   if (pConf) {
149   } else {
150     iResult=-EINVAL;
151   }
152   return iResult;
153 }
154
155 int AliHLTSystem::BuildTaskList(const char* id)
156 {
157   // see header file for class documentation
158   int iResult=0;
159   if (id) {
160     if (fpConfigurationHandler) {
161       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
162       if (pConf) {
163         iResult=BuildTaskList(pConf);
164       } else {
165         HLTError("unknown configuration \"%s\"", id);
166         iResult=-EEXIST;
167       }
168     } else {
169       iResult=-EFAULT;
170     }
171   } else {
172     iResult=-EINVAL;
173   }
174   return iResult;
175 }
176
177 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
178 {
179   // see header file for class documentation
180   int iResult=0;
181   if (pConf) {
182     AliHLTTask* pTask=NULL;
183     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
184       if (pTask->GetConf()!=pConf) {
185         HLTError("configuration missmatch, there is already a task with configuration name \"%s\", but it is different. Most likely configuration %p is not registered properly", pConf->GetName(), pConf);
186         iResult=-EEXIST;
187       }
188       // task for this configuration exists, terminate
189       pTask=NULL;
190     } else if (pConf->SourcesResolved(1)!=1) {
191         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
192         iResult=-ENOLINK;
193     } else {
194       pTask=new AliHLTTask(pConf);
195       if (pTask==NULL) {
196         iResult=-ENOMEM;
197       } else {
198         pTask->SetLocalLoggingLevel(GetLocalLoggingLevel());
199       }
200     }
201     static int iterationLevel=0;
202     if (pTask && iResult>=0) {
203       // check for circular dependencies
204       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
205         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
206         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
207         HLTError("aborted ...");
208         iResult=-ELOOP;
209       }
210       if (iResult>=0) {
211         // check whether all dependencies are already in the task list
212         // create the missing ones
213         // this step is an iterative process which calls this function again for the missing
214         // configurations, in order to avoid the currently processed task to be created
215         // again it is added to the list temporarily and removed afterwards
216         // This is of high importance to preserve the order of the tasks. Furthermore, the
217         // InsertTask method has to be used in order to set all the cross links right 
218         fTaskList.Add(pTask);
219         AliHLTConfiguration* pDep=pConf->GetFirstSource();
220         while (pDep!=NULL && iResult>=0) {
221           HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
222           if (FindTask(pDep->GetName())==NULL) {
223             HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
224             iterationLevel++;
225             iResult=BuildTaskList(pDep);
226             iterationLevel--;
227           }
228           pDep=pConf->GetNextSource();
229         }
230         // remove the temporarily added task
231         fTaskList.Remove(pTask);
232
233         // insert the task and set the cross-links
234         if (iResult>=0) {
235           HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
236           iResult=InsertTask(pTask);
237         }
238       } else {
239         delete pTask;
240         pTask=NULL;
241       }
242     }
243   } else {
244     iResult=-EINVAL;
245   }
246   return iResult;
247 }
248
249 int AliHLTSystem::CleanTaskList()
250 {
251   // see header file for class documentation
252   int iResult=0;
253   TObjLink* lnk=NULL;
254   while ((lnk=fTaskList.LastLink())!=NULL) {
255     delete (lnk->GetObject());
256     fTaskList.Remove(lnk);
257   }
258   return iResult;
259 }
260
261 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
262 {
263   // see header file for class documentation
264   int iResult=0;
265   TObjLink *lnk = NULL;
266   if ((iResult=pTask->CheckDependencies())>0)
267     lnk=fTaskList.FirstLink();
268   while (lnk && iResult>0) {
269     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
270     //HLTDebug("checking  \"%s\"", pCurr->GetName());
271     iResult=pTask->Depends(pCurr);
272     if (iResult>0) {
273       iResult=pTask->SetDependency(pCurr);
274       pCurr->SetTarget(pTask);
275       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
276     }
277     if (pCurr->Depends(pTask)) {
278       // circular dependency
279       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
280       iResult=-ELOOP;
281     } else if ((iResult=pTask->CheckDependencies())>0) {
282       lnk = lnk->Next();
283     }
284   }
285   if (iResult==0) {
286       if (lnk) {
287         fTaskList.AddAfter(lnk, pTask);
288       } else {
289         fTaskList.AddFirst(pTask);
290       }
291       HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
292   } else if (iResult>0) {
293     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
294     iResult=-ENOLINK;
295   }
296   return iResult;
297 }
298
299 AliHLTTask* AliHLTSystem::FindTask(const char* id)
300 {
301   // see header file for class documentation
302   AliHLTTask* pTask=NULL;
303   if (id) {
304     pTask=dynamic_cast<AliHLTTask*>(fTaskList.FindObject(id)); 
305   }
306   return pTask;
307 }
308
309 void AliHLTSystem::PrintTaskList()
310 {
311   // see header file for class documentation
312   HLTLogKeyword("task list");
313   TObjLink *lnk = NULL;
314   HLTMessage("Task List");
315   lnk=fTaskList.FirstLink();
316   while (lnk) {
317     TObject* obj=lnk->GetObject();
318     if (obj) {
319       HLTMessage("  %s - status:", obj->GetName());
320       AliHLTTask* pTask=(AliHLTTask*)obj;
321       pTask->PrintStatus();
322     } else {
323     }
324     lnk = lnk->Next();
325   }
326 }
327
328 int AliHLTSystem::Run(Int_t iNofEvents, int bStop)
329 {
330   // see header file for class documentation
331   int iResult=0;
332   int iCount=0;
333   SetStatusFlags(kRunning);
334   if (fEventCount>=0 || (iResult=InitTasks())>=0) {
335     if (fEventCount>=0 || (iResult=StartTasks())>=0) {
336       if (fEventCount==0) {
337         InitBenchmarking(fStopwatches);
338       } else {
339         //ResumeBenchmarking(fStopwatches);    
340       }
341       for (int i=fEventCount; i<fEventCount+iNofEvents && iResult>=0; i++) {
342         if ((iResult=ProcessTasks(i))>=0) {
343           fGoodEvents++;
344           iCount++;
345         } else {
346           // TODO: define different running modes to either ignore errors in
347           // event processing or not
348           // currently ignored 
349           iResult=0;
350         }
351       }
352       fEventCount+=iNofEvents;
353       if (bStop) StopTasks();
354       //else PauseBenchmarking(fStopwatches);
355     }
356     if (bStop) DeinitTasks();
357   }
358   if (iResult>=0) {
359     iResult=iCount;
360   } else  if (iResult==-126 /*ENOKEY*/) {
361     iResult=0; // do not propagate the error
362   }
363   ClearStatusFlags(kRunning);
364   return iResult;
365 }
366
367 int AliHLTSystem::InitTasks()
368 {
369   // see header file for class documentation
370   int iResult=0;
371   TObjLink *lnk=fTaskList.FirstLink();
372
373   if (lnk==NULL) {
374     HLTWarning("Task list is empty, aborting ...");
375     return -126 /*ENOKEY*/;
376   }
377   while (lnk && iResult>=0) {
378     TObject* obj=lnk->GetObject();
379     if (obj) {
380       AliHLTTask* pTask=(AliHLTTask*)obj;
381       iResult=pTask->Init(NULL, fpComponentHandler);
382 //       ProcInfo_t ProcInfo;
383 //       gSystem->GetProcInfo(&ProcInfo);
384 //       HLTInfo("task %s initialized (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
385     } else {
386     }
387     lnk = lnk->Next();
388   }
389   if (iResult<0) {
390     HLTError("can not initialize task list, error %d", iResult);
391   }
392
393   return iResult;
394 }
395
396 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
397 {
398   // see header file for class documentation
399   int iResult=0;
400   if (pStopwatches==NULL) return 0;
401
402   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
403     TStopwatch* pStopwatch= new TStopwatch;
404     if (pStopwatch) {
405       pStopwatch->Reset();
406       pStopwatches->AddAt(pStopwatch, i);
407     } else {
408       iResult=-ENOMEM;
409       break;
410     }
411   }
412
413   TObjLink *lnk=fTaskList.FirstLink();
414   while (lnk && iResult>=0) {
415     TObject* obj=lnk->GetObject();
416     if (obj) {
417       AliHLTTask* pTask=(AliHLTTask*)obj;
418       AliHLTComponent* pComp=NULL;
419       if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
420         switch (pComp->GetComponentType()) {
421         case AliHLTComponent::kProcessor:
422           pComp->SetStopwatches(pStopwatches);
423           break;
424         case AliHLTComponent::kSource:
425           {
426             // this switch determines whether the time consumption of the
427             // AliHLTComponent base methods should be counted to the input
428             // stopwatch or base stopwatch.
429             //int inputBase=(int)AliHLTComponent::kSWBase;
430             int inputBase=(int)AliHLTComponent::kSWInput;
431             pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
432             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
433           }
434           break;
435         case AliHLTComponent::kSink:
436           {
437             // this switch determines whether the time consumption of the
438             // AliHLTComponent base methods should be counted to the output
439             // stopwatch or base stopwatch.
440             //int outputBase=(int)AliHLTComponent::kSWBase;
441             int outputBase=(int)AliHLTComponent::kSWOutput;
442             pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
443             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
444           }
445           break;
446         default:
447           HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
448         }
449       }
450     } else {
451     }
452     lnk = lnk->Next();
453   }
454   return iResult;
455 }
456
457 int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean)
458 {
459   // see header file for class documentation
460   int iInitialized=1;
461   if (pStopwatches==NULL) return 0;
462
463   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
464     if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
465       iInitialized=0;
466       break;
467     }
468   }
469
470   if (iInitialized!=0) {
471     HLTInfo("HLT statistics:\n"
472             "    base:              R:%.3fs C:%.3fs\n"
473             "    input:             R:%.3fs C:%.3fs\n"
474             "    output:            R:%.3fs C:%.3fs\n"
475             "    event processing : R:%.3fs C:%.3fs"
476             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
477             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
478             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
479             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
480             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
481             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
482             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
483             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
484             );
485   }
486
487   if (bClean) {
488     for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
489       TObject* pObj=pStopwatches->RemoveAt(i);
490       if (pObj) delete pObj;
491     }
492   }
493   return 0;
494 }
495
496 int AliHLTSystem::StartTasks()
497 {
498   // see header file for class documentation
499   int iResult=0;
500   TObjLink *lnk=fTaskList.FirstLink();
501   while (lnk && iResult>=0) {
502     TObject* obj=lnk->GetObject();
503     if (obj) {
504       AliHLTTask* pTask=(AliHLTTask*)obj;
505       iResult=pTask->StartRun();
506 //       ProcInfo_t ProcInfo;
507 //       gSystem->GetProcInfo(&ProcInfo);
508 //       HLTInfo("task %s started (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
509     } else {
510     }
511     lnk = lnk->Next();
512   }
513   if (iResult<0) {
514     HLTError("can not start task list, error %d", iResult);
515   } else {
516     fEventCount=0;
517     fGoodEvents=0;
518   }
519   return iResult;
520 }
521
522 int AliHLTSystem::ProcessTasks(Int_t eventNo)
523 {
524   // see header file for class documentation
525   int iResult=0;
526   HLTDebug("processing event no %d", eventNo);
527   TObjLink *lnk=fTaskList.FirstLink();
528   while (lnk && iResult>=0) {
529     TObject* obj=lnk->GetObject();
530     if (obj) {
531       AliHLTTask* pTask=(AliHLTTask*)obj;
532       iResult=pTask->ProcessTask(eventNo);
533 //       ProcInfo_t ProcInfo;
534 //       gSystem->GetProcInfo(&ProcInfo);
535 //       HLTInfo("task %s processed (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
536     } else {
537     }
538     lnk = lnk->Next();
539   }
540
541   if (iResult>=0) {
542     HLTInfo("Event %d successfully finished (%d)", eventNo, iResult);
543     iResult=0;
544   } else {
545     HLTError("Processing of event %d failed (%d)", eventNo, iResult);
546   }
547
548   return iResult;
549 }
550
551 int AliHLTSystem::StopTasks()
552 {
553   // see header file for class documentation
554   int iResult=0;
555   TObjLink *lnk=fTaskList.FirstLink();
556   while (lnk && iResult>=0) {
557     TObject* obj=lnk->GetObject();
558     if (obj) {
559       AliHLTTask* pTask=(AliHLTTask*)obj;
560       iResult=pTask->EndRun();
561 //       ProcInfo_t ProcInfo;
562 //       gSystem->GetProcInfo(&ProcInfo);
563 //       HLTInfo("task %s stopped (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
564     } else {
565     }
566     lnk = lnk->Next();
567   }
568   PrintBenchmarking(fStopwatches, 1 /*clean*/);
569   return iResult;
570 }
571
572 int AliHLTSystem::DeinitTasks()
573 {
574   // see header file for class documentation
575   int iResult=0;
576   TObjLink *lnk=fTaskList.FirstLink();
577   while (lnk && iResult>=0) {
578     TObject* obj=lnk->GetObject();
579     if (obj) {
580       AliHLTTask* pTask=(AliHLTTask*)obj;
581       iResult=pTask->Deinit();
582 //       ProcInfo_t ProcInfo;
583 //       gSystem->GetProcInfo(&ProcInfo);
584 //       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
585     } else {
586     }
587     lnk = lnk->Next();
588   }
589   fEventCount=-1;
590   fGoodEvents=-1;
591
592   return iResult;
593 }
594
595 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
596 {
597   // see header file for class documentation
598   void* p=NULL;
599   try {
600     p=(void*)new char[size];
601   }
602   catch (...) {
603     AliHLTLogging log;
604     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
605   }
606   return p;
607 }
608
609 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
610                               AliRawReader* rawReader)
611 {
612   // see header file for class documentation
613   int iResult=0;
614   if (runLoader || rawReader || nofEvents==0) {
615     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
616     if (CheckStatus(kReady)) {
617       if (nofEvents==0) {
618         // special case to close the reconstruction
619         if (!CheckStatus(kError)) {
620         StopTasks();
621         DeinitTasks();
622         }
623       } else {
624       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
625         // the system always remains started after event processing, a specific
626         // call with nofEvents==0 is needed to execute the stop sequence
627         if ((iResult=Run(nofEvents, 0))<0) SetStatusFlags(kError);
628       }
629       }
630     } else {
631       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
632     }
633   } else {
634     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
635     iResult=-EINVAL;
636   }
637   return iResult;
638 }
639
640 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
641 {
642   // see header file for class documentation
643   int iResult=0;
644   if (runLoader || esd) {
645     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
646     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
647   } else {
648     HLTError("missing run loader/ESD instance(s)");
649     iResult=-EINVAL;
650   }
651   return iResult;
652 }
653
654 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
655 {
656   // see header file for class documentation
657   int iResult=0;
658   if (libraries) {
659     if (fpComponentHandler) {
660       TString libs(libraries);
661       TObjArray* pTokens=libs.Tokenize(" ");
662       if (pTokens) {
663         int iEntries=pTokens->GetEntries();
664         for (int i=0; i<iEntries && iResult>=0; i++) {
665           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
666         }
667         delete pTokens;
668       }
669       if (iResult>=0) {
670         SetStatusFlags(kLibrariesLoaded);
671       } else {
672         // lets see if we need this, probably not
673         //fpComponentHandler->UnloadLibraries();
674         ClearStatusFlags(kLibrariesLoaded);
675       }
676     } else {
677       iResult=-EFAULT;
678       HLTFatal("no component handler available");
679     }
680   } else {
681     iResult=-EINVAL;
682   }
683   return iResult;
684 }
685
686 int AliHLTSystem::Configure(AliRunLoader* runloader)
687 {
688   // see header file for class documentation
689   return Configure(NULL, runloader);
690 }
691
692 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
693 {
694   // see header file for class documentation
695   int iResult=0;
696   if (CheckStatus(kRunning)) {
697     HLTError("HLT system in running state, can not configure");
698     return -EBUSY;
699   }
700   ClearStatusFlags(kTaskListCreated);
701   if (CheckFilter(kHLTLogDebug))
702     AliHLTModuleAgent::PrintStatus();
703   if (CheckStatus(kConfigurationLoaded)==0) {
704     iResult=LoadConfigurations(rawReader, runloader);
705   } else {
706     if (fChains.Length()==0) {
707       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'localrec=<conf>\' option");
708       iResult=-ENOENT;
709     }
710   }
711   if (iResult>=0) {
712     SetStatusFlags(kConfigurationLoaded);
713     if (CheckFilter(kHLTLogDebug))
714       fpConfigurationHandler->PrintConfigurations();
715     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
716     if (iResult>=0) {
717       SetStatusFlags(kTaskListCreated);
718     }
719   }
720   if (iResult<0) SetStatusFlags(kError);
721   
722   return iResult;
723 }
724
725 int AliHLTSystem::ScanOptions(const char* options)
726 {
727   // see header file for class documentation
728   int iResult=0;
729   if (options) {
730     AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
731     TString libs("");
732     TString alloptions(options);
733     TObjArray* pTokens=alloptions.Tokenize(" ");
734     if (pTokens) {
735       int iEntries=pTokens->GetEntries();
736       for (int i=0; i<iEntries; i++) {
737         TString token=(((TObjString*)pTokens->At(i))->GetString());
738         if (token.Contains("loglevel=")) {
739           TString param=token.ReplaceAll("loglevel=", "");
740           if (param.IsDigit()) {
741             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
742           } else if (param.BeginsWith("0x") &&
743                      param.Replace(0,2,"",0).IsHex()) {
744             int severity=0;
745             sscanf(param.Data(),"%x", &severity);
746             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
747           } else {
748             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
749           }
750         } else if (token.Contains("frameworklog=")) {
751           TString param=token.ReplaceAll("frameworklog=", "");
752           if (param.IsDigit()) {
753             SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
754           } else if (param.BeginsWith("0x") &&
755                      param.Replace(0,2,"",0).IsHex()) {
756             int severity=0;
757             sscanf(param.Data(),"%x", &severity);
758             SetFrameworkLog((AliHLTComponentLogSeverity)severity);
759           } else {
760             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
761           }
762         } else if (token.Contains("alilog=off")) {
763           SwitchAliLog(0);
764         } else if (token.Contains("config=")) {
765           TString param=token.ReplaceAll("config=", "");
766           Int_t error=0;
767           gROOT->Macro(param.Data(), &error);
768           if (error==0) {
769             SetStatusFlags(kConfigurationLoaded);
770           } else {
771             HLTError("can not execute macro \'%s\'", param.Data());
772             iResult=-EBADF;
773           }
774         } else if (token.Contains("chains=")) {
775           TString param=token.ReplaceAll("chains=", "");
776           fChains=param.ReplaceAll(",", " ");
777         } else if (token.Contains("libmode=")) {
778           TString param=token.ReplaceAll("libmode=", "");
779           param.ReplaceAll(",", " ");
780           if (fpComponentHandler) {
781             if (param.CompareTo("static")==0) {
782               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
783             } else if (param.CompareTo("dynamic")==0) {
784               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
785             } else {
786               HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
787             }
788           }
789         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
790           libs+=token;
791           libs+=" ";
792         } else {
793           HLTWarning("unknown option \'%s\'", token.Data());
794         }
795       }
796       delete pTokens;
797     }
798
799     if (iResult>=0) {
800       if (libs.IsNull()) {
801         const char** deflib=kHLTDefaultLibs;
802         while (*deflib) {
803           libs+=*deflib++;
804           libs+=" ";
805         }
806       }
807       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
808           (LoadComponentLibraries(libs.Data())<0)) {
809         HLTError("error while loading HLT libraries");
810         iResult=-EFAULT;
811       }
812     }
813   }
814   return iResult;
815 }
816
817 int AliHLTSystem::Reset(int bForce)
818 {
819   // see header file for class documentation
820   int iResult=0;
821   if (!bForce && CheckStatus(kRunning)) {
822     HLTError("HLT system in running state, can not configure");
823     return -EBUSY;
824   }
825   CleanTaskList();
826   ClearStatusFlags(~kUninitialized);
827   return iResult;
828 }
829
830 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
831 {
832   // see header file for class documentation
833   if (CheckStatus(kRunning)) {
834     HLTError("HLT system in running state, can not configure");
835     return -EBUSY;
836   }
837   int iResult=0;
838   AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
839   while (pAgent && iResult>=0) {
840     const char* deplibs=pAgent->GetRequiredComponentLibraries();
841     if (deplibs) {
842       HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
843       iResult=LoadComponentLibraries(deplibs);
844     }
845     if (iResult>=0) {
846       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
847       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
848       pAgent=AliHLTModuleAgent::GetNextAgent();
849     }
850   }
851   return iResult;
852 }
853
854 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
855 {
856   // see header file for class documentation
857   if (CheckStatus(kRunning)) {
858     HLTError("HLT system in running state, can not configure");
859     return -EBUSY;
860   }
861   if (!CheckStatus(kConfigurationLoaded)) {
862     HLTWarning("configurations not yet loaded");
863     return 0;
864   }
865
866   int iResult=0;
867   int bHaveOutput=0;
868
869   // query chains
870   TString chains;
871   if (fChains.Length()>0) {
872     chains=fChains;
873     HLTInfo("custom reconstruction chain: %s", chains.Data());
874   } else {
875     AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
876     while ((pAgent || fChains.Length()>0) && iResult>=0) {
877       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
878       if (agentchains) {
879         if (!chains.IsNull()) chains+="";
880         chains+=agentchains;
881         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
882       }
883       pAgent=AliHLTModuleAgent::GetNextAgent();
884     }
885   }
886
887   // build task list for chains
888   TObjArray* pTokens=chains.Tokenize(" ");
889   if (pTokens) {
890     int iEntries=pTokens->GetEntries();
891     for (int i=0; i<iEntries && iResult>=0; i++) {
892       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
893       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
894       if (pConf) {
895         iResult=BuildTaskList(pConf);
896         if (runloader) {
897           assert(fpComponentHandler!=NULL);
898           TString cid=pConf->GetComponentID();
899           if (cid.CompareTo("HLTOUT")==0) {
900             // remove from the input of a global HLTOUT configuration
901             chains.ReplaceAll(pCID, "");
902           } else if (bHaveOutput==0) {
903             // check whether this configuration produces data output
904             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
905               bHaveOutput=0;
906               chains.ReplaceAll(pCID, "");
907             }
908           }
909         }
910       } else {
911         HLTWarning("can not find configuration %s", pCID);
912       }
913     }
914     delete pTokens;
915   }
916
917   // build HLTOUT for simulation
918   if (iResult>=0 && runloader) {
919     if (bHaveOutput) {
920       // there are components in the chain which produce data which need to be
921       // piped to an HLTOUT
922       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
923           LoadComponentLibraries("libHLTsim.so")>=0) {
924         AliHLTConfiguration globalout("_globalout_", "HLTOUT", chains.Data(), NULL);
925         iResult=BuildTaskList("_globalout_");
926       } else {
927         HLTError("can not load libHLTsim.so and HLTOUT component");
928         iResult=-EFAULT;
929       }
930     }
931   }
932
933   if (iResult>=0) SetStatusFlags(kTaskListCreated);
934
935   return iResult;
936 }
937
938 int AliHLTSystem::CheckStatus(int flag)
939 {
940   // see header file for class documentation
941   if (flag==kUninitialized && flag==fState) return 1;
942   if ((fState&flag)==flag) return 1;
943   return 0;
944 }
945
946 int AliHLTSystem::GetStatusFlags()
947 {
948   // see header file for class documentation
949   return fState;
950 }
951
952 int AliHLTSystem::SetStatusFlags(int flags)
953 {
954   // see header file for class documentation
955   fState|=flags;
956   return fState;
957 }
958
959 int AliHLTSystem::ClearStatusFlags(int flags)
960 {
961   // see header file for class documentation
962   fState&=~flags;
963   return fState;
964 }
965
966 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
967 {
968   // see header file for class documentation
969   if (fpComponentHandler==NULL) return NULL;
970   return fpComponentHandler->FindSymbol(library, symbol);
971 }
972
973 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
974 {
975   SetLocalLoggingLevel(level);
976   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
977   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
978 }