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