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