]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
fe2bcf30f85485212ef670580b5e84d32fcf98da
[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()
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   bWriteGlobalEsd(false)
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 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);
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, skipping HLT");
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::PauseBenchmarking(TObjArray* pStopwatches) const
473 {
474   // see header file for class documentation
475   if (pStopwatches==NULL) return 0;
476
477   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
478     if (!pStopwatches->At(i)) continue;
479     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
480     if (pSw) pSw->Stop();
481   }
482   return 0;
483 }
484
485 int AliHLTSystem::ResumeBenchmarking(TObjArray* pStopwatches) const
486 {
487   // see header file for class documentation
488   if (pStopwatches==NULL) return 0;
489
490   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
491     if (!pStopwatches->At(i)) continue;
492     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
493     if (pSw) pSw->Continue();
494   }
495   return 0;
496 }
497
498 int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean) const
499 {
500   // see header file for class documentation
501   int iInitialized=1;
502   if (pStopwatches==NULL) return 0;
503
504   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
505     if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
506       iInitialized=0;
507       break;
508     }
509   }
510
511   if (iInitialized!=0) {
512     HLTImportant("HLT statistics:\n"
513             "    base:              R:%.3fs C:%.3fs\n"
514             "    input:             R:%.3fs C:%.3fs\n"
515             "    output:            R:%.3fs C:%.3fs\n"
516             "    event processing : R:%.3fs C:%.3fs"
517             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
518             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
519             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
520             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
521             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
522             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
523             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
524             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
525             );
526   }
527
528   if (bClean) {
529     for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
530       TObject* pObj=pStopwatches->RemoveAt(i);
531       if (pObj) delete pObj;
532     }
533   }
534   return 0;
535 }
536
537 int AliHLTSystem::StartTasks()
538 {
539   // see header file for class documentation
540   int iResult=0;
541   TObjLink *lnk=fTaskList.FirstLink();
542   while (lnk && iResult>=0) {
543     TObject* obj=lnk->GetObject();
544     if (obj) {
545       AliHLTTask* pTask=(AliHLTTask*)obj;
546       iResult=pTask->StartRun();
547 //       ProcInfo_t ProcInfo;
548 //       gSystem->GetProcInfo(&ProcInfo);
549 //       HLTInfo("task %s started (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
550     } else {
551     }
552     lnk = lnk->Next();
553   }
554   if (iResult<0) {
555     HLTError("can not start task list, error %d", iResult);
556   } else {
557     SetStatusFlags(kStarted);
558     fEventCount=0;
559     fGoodEvents=0;
560     if ((iResult=SendControlEvent(kAliHLTDataTypeSOR))<0) {
561       HLTError("can not send SOR event");
562     }
563   }
564   return iResult;
565 }
566
567 int AliHLTSystem::ProcessTasks(Int_t eventNo)
568 {
569   // see header file for class documentation
570   int iResult=0;
571   HLTDebug("processing event no %d", eventNo);
572   TObjLink *lnk=fTaskList.FirstLink();
573   while (lnk && iResult>=0) {
574     TObject* obj=lnk->GetObject();
575     if (obj) {
576       AliHLTTask* pTask=(AliHLTTask*)obj;
577       iResult=pTask->ProcessTask(eventNo);
578 //       ProcInfo_t ProcInfo;
579 //       gSystem->GetProcInfo(&ProcInfo);
580 //       HLTInfo("task %s processed (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
581     } else {
582     }
583     lnk = lnk->Next();
584   }
585
586   if (iResult>=0) {
587     HLTImportant("Event %d successfully finished (%d)", eventNo, iResult);
588     iResult=0;
589   } else {
590     HLTError("Processing of event %d failed (%d)", eventNo, iResult);
591   }
592
593   return iResult;
594 }
595
596 int AliHLTSystem::StopTasks()
597 {
598   // see header file for class documentation
599   int iResult=0;
600   if ((iResult=SendControlEvent(kAliHLTDataTypeEOR))<0) {
601     HLTError("can not send EOR event");
602   }
603   TObjLink *lnk=fTaskList.FirstLink();
604   while (lnk) {
605     TObject* obj=lnk->GetObject();
606     if (obj) {
607       AliHLTTask* pTask=(AliHLTTask*)obj;
608       int locResult=pTask->EndRun();
609       if (iResult>=0 && locResult<0) iResult=locResult;
610 //       ProcInfo_t ProcInfo;
611 //       gSystem->GetProcInfo(&ProcInfo);
612 //       HLTInfo("task %s stopped (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
613     } else {
614     }
615     lnk = lnk->Next();
616   }
617   PrintBenchmarking(fStopwatches, 1 /*clean*/);
618   ClearStatusFlags(kStarted);
619   return iResult;
620 }
621
622 int AliHLTSystem::SendControlEvent(AliHLTComponentDataType dt)
623 {
624   // see header file for class documentation
625
626   // disabled for the moment
627   return 0;
628
629   int iResult=0;
630   AliHLTRunDesc runDesc;
631   memset(&runDesc, 0, sizeof(AliHLTRunDesc));
632   runDesc.fStructSize=sizeof(AliHLTRunDesc);
633   AliHLTDataSource::AliSpecialEventGuard g(&runDesc, dt, kAliHLTVoidDataSpec);
634   HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
635   TObjLink *lnk=fTaskList.FirstLink();
636   while (lnk && iResult>=0) {
637     TObject* obj=lnk->GetObject();
638     if (obj) {
639       AliHLTTask* pTask=(AliHLTTask*)obj;
640       iResult=pTask->ProcessTask(-1);
641     } else {
642     }
643     lnk = lnk->Next();
644   }
645   HLTDebug("event %s done (%d)", AliHLTComponent::DataType2Text(dt).c_str(), iResult);
646   return iResult;
647 }
648
649 int AliHLTSystem::DeinitTasks()
650 {
651   // see header file for class documentation
652   int iResult=0;
653   TObjLink *lnk=fTaskList.FirstLink();
654   while (lnk && iResult>=0) {
655     TObject* obj=lnk->GetObject();
656     if (obj) {
657       AliHLTTask* pTask=(AliHLTTask*)obj;
658       iResult=pTask->Deinit();
659 //       ProcInfo_t ProcInfo;
660 //       gSystem->GetProcInfo(&ProcInfo);
661 //       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
662     } else {
663     }
664     lnk = lnk->Next();
665   }
666   fEventCount=-1;
667   fGoodEvents=-1;
668
669   return iResult;
670 }
671
672 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
673 {
674   // see header file for class documentation
675   void* p=NULL;
676   try {
677     p=(void*)new char[size];
678   }
679   catch (...) {
680     AliHLTLogging log;
681     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
682   }
683   return p;
684 }
685
686 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
687                               AliRawReader* rawReader)
688 {
689   // see header file for class documentation
690   int iResult=0;
691   if (runLoader || rawReader || nofEvents==0) {
692     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
693     if (CheckStatus(kReady)) {
694       if (nofEvents==0) {
695         // special case to close the reconstruction
696         if (!CheckStatus(kError)) {
697         StopTasks();
698         DeinitTasks();
699         }
700       } else {
701       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
702         // the system always remains started after event processing, a specific
703         // call with nofEvents==0 is needed to execute the stop sequence
704         if ((iResult=Run(nofEvents, 0))<0) SetStatusFlags(kError);
705       }
706       }
707     } else {
708       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
709     }
710   } else {
711     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
712     iResult=-EINVAL;
713   }
714   return iResult;
715 }
716
717 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
718 {
719   // see header file for class documentation
720   int iResult=0;
721   if (runLoader || esd) {
722     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
723     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
724   } else {
725     HLTError("missing run loader/ESD instance(s)");
726     iResult=-EINVAL;
727   }
728   return iResult;
729 }
730
731 int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
732 {
733   // see header file for class documentation
734   int iResult=0;
735   if (!pHLTOUT) return -EINVAL;
736
737   HLTDebug("processing %d HLT data blocks", pHLTOUT->GetNofDataBlocks());
738   AliHLTOUT::AliHLTOUTHandlerListEntryVector esdHandlers;
739
740   // first come first serve: the ESD of the first handler is also filled into
741   // the main ESD. Has to be changed later.
742   // currently, merging to the provided ESDs crashes at the level of the
743   // TTree::Fill in AliReconstruction, furthermore, the wrong ESD is passed
744   // by the framework
745   AliESDEvent* pMasterESD=NULL;
746   if (bWriteGlobalEsd) pMasterESD=esd;
747   for (iResult=pHLTOUT->SelectFirstDataBlock();
748        iResult>=0;
749        iResult=pHLTOUT->SelectNextDataBlock()) {
750     AliHLTComponentDataType dt=kAliHLTVoidDataType;
751     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
752     pHLTOUT->GetDataBlockDescription(dt, spec);
753     AliHLTOUTHandler* pHandler=pHLTOUT->GetHandler();
754     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=pHLTOUT->GetDataBlockHandlerType();
755     if (!pHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
756       handlerType=AliHLTModuleAgent::kEsd;
757     }
758     const char* pMsg="invalid";
759     switch (handlerType) {
760     case AliHLTModuleAgent::kEsd:
761       {
762         if (pHandler) {
763           // preprocess and write later
764           AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
765           pHandler->ProcessData(pHLTOUT);
766           pHLTOUT->InsertHandler(esdHandlers, pHLTOUT->GetDataBlockHandlerDesc());
767         } else {
768           // write directly
769           const AliHLTUInt8_t* pBuffer=NULL;
770           AliHLTUInt32_t size=0;
771           if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
772             pHLTOUT->WriteESD(pBuffer, size, dt);
773             if (pMasterESD) {
774               pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
775               pMasterESD=NULL;
776             }
777             pHLTOUT->ReleaseDataBuffer(pBuffer);
778           }
779         }
780       }
781       break;
782     case AliHLTModuleAgent::kRawReader:
783       // handled in the AliRawReaderHLT
784       break;
785     case AliHLTModuleAgent::kRawStream:
786       HLTWarning("HLTOUT handler type 'kRawStream' not yet implemented: agent %s, data type %s, specification %#x",
787                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
788                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
789       break;
790     case AliHLTModuleAgent::kChain:
791       HLTWarning("HLTOUT handler type 'kChain' not yet implemented: agent %s, data type %s, specification %#x",
792                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
793                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
794       break;
795     case AliHLTModuleAgent::kProprietary:
796       HLTDebug("processing proprietary data: agent %s, data type %s, specification %#x",
797                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
798                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
799       if (pHandler) {
800         AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
801         int res=pHandler->ProcessData(pHLTOUT);
802         if (res<0) {
803           HLTWarning("processing proprietary data failed (%d): agent %s, data type %s, specification %#x",
804                      res, pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
805                      AliHLTComponent::DataType2Text(dt).c_str(), spec);
806         }
807       }
808       break;
809     case AliHLTModuleAgent::kUnknownOutput:
810       pMsg="unknown";
811       // fall trough intended
812     default:
813       HLTWarning("%s handler type: agent %s, data type %s, specification %#x, ... skipping data block",
814                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
815                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
816     }
817   }
818   // TODO: the return value of SelectFirst/NextDataBlock must be
819   // changed in order to avoid this check
820   if (iResult==-ENOENT) iResult=0;
821
822   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator esdHandler;
823   // write all postponed esd data blocks
824   for (esdHandler=esdHandlers.begin(); esdHandler!=esdHandlers.end() && iResult>=0; esdHandler++) {
825     AliHLTOUTHandler* pHandler=*esdHandler;
826     const AliHLTUInt8_t* pBuffer=NULL;
827     AliHLTUInt32_t size=0;
828     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
829       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*esdHandler;
830       AliHLTComponentDataType dt=desc;
831       pHLTOUT->WriteESD(pBuffer, size, dt);
832       if (pMasterESD) {
833         pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
834         pMasterESD=NULL;
835       }
836       pHandler->ReleaseProcessedData(pBuffer, size);
837     }
838   }
839
840   return iResult;
841 }
842
843 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
844 {
845   // see header file for class documentation
846   int iResult=0;
847   if (libraries) {
848     if (fpComponentHandler) {
849       TString libs(libraries);
850       TObjArray* pTokens=libs.Tokenize(" ");
851       if (pTokens) {
852         int iEntries=pTokens->GetEntries();
853         for (int i=0; i<iEntries && iResult>=0; i++) {
854           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
855         }
856         delete pTokens;
857       }
858       if (iResult>=0) {
859         SetStatusFlags(kLibrariesLoaded);
860       } else {
861         // lets see if we need this, probably not
862         //fpComponentHandler->UnloadLibraries();
863         ClearStatusFlags(kLibrariesLoaded);
864       }
865     } else {
866       iResult=-EFAULT;
867       HLTFatal("no component handler available");
868     }
869   } else {
870     iResult=-EINVAL;
871   }
872   return iResult;
873 }
874
875 int AliHLTSystem::Configure(AliRunLoader* runloader)
876 {
877   // see header file for class documentation
878   return Configure(NULL, runloader);
879 }
880
881 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
882 {
883   // see header file for class documentation
884   int iResult=0;
885   if (CheckStatus(kRunning)) {
886     HLTError("HLT system in running state, can not configure");
887     return -EBUSY;
888   }
889   ClearStatusFlags(kTaskListCreated);
890   if (CheckFilter(kHLTLogDebug))
891     AliHLTModuleAgent::PrintStatus();
892   if (CheckStatus(kConfigurationLoaded)==0) {
893     iResult=LoadConfigurations(rawReader, runloader);
894   } else {
895     if (fChains.Length()==0) {
896       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'localrec=<conf>\' option");
897       iResult=-ENOENT;
898     }
899   }
900   if (iResult>=0) {
901     SetStatusFlags(kConfigurationLoaded);
902     if (CheckFilter(kHLTLogDebug))
903       fpConfigurationHandler->PrintConfigurations();
904     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
905     if (iResult>=0) {
906       SetStatusFlags(kTaskListCreated);
907     }
908   }
909   if (iResult<0) SetStatusFlags(kError);
910   
911   return iResult;
912 }
913
914 int AliHLTSystem::ScanOptions(const char* options)
915 {
916   // see header file for class documentation
917   int iResult=0;
918   if (options) {
919     //AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
920     TString libs("");
921     TString alloptions(options);
922     TObjArray* pTokens=alloptions.Tokenize(" ");
923     if (pTokens) {
924       int iEntries=pTokens->GetEntries();
925       for (int i=0; i<iEntries; i++) {
926         TString token=(((TObjString*)pTokens->At(i))->GetString());
927         if (token.Contains("loglevel=")) {
928           TString param=token.ReplaceAll("loglevel=", "");
929           if (param.IsDigit()) {
930             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
931           } else if (param.BeginsWith("0x") &&
932                      param.Replace(0,2,"",0).IsHex()) {
933             int severity=0;
934             sscanf(param.Data(),"%x", &severity);
935             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
936           } else {
937             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
938           }
939         } else if (token.Contains("frameworklog=")) {
940           TString param=token.ReplaceAll("frameworklog=", "");
941           if (param.IsDigit()) {
942             SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
943           } else if (param.BeginsWith("0x") &&
944                      param.Replace(0,2,"",0).IsHex()) {
945             int severity=0;
946             sscanf(param.Data(),"%x", &severity);
947             SetFrameworkLog((AliHLTComponentLogSeverity)severity);
948           } else {
949             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
950           }
951         } else if (token.Contains("alilog=off")) {
952           SwitchAliLog(0);
953         } else if (token.Contains("config=")) {
954           TString param=token.ReplaceAll("config=", "");
955           Int_t error=0;
956           gROOT->Macro(param.Data(), &error);
957           if (error==0) {
958             SetStatusFlags(kConfigurationLoaded);
959           } else {
960             HLTError("can not execute macro \'%s\'", param.Data());
961             iResult=-EBADF;
962           }
963         } else if (token.Contains("chains=")) {
964           TString param=token.ReplaceAll("chains=", "");
965           fChains=param.ReplaceAll(",", " ");
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.Contains("globalesd")) {
979           bWriteGlobalEsd=true;
980         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
981           libs+=token;
982           libs+=" ";
983         } else {
984           HLTWarning("unknown option \'%s\'", token.Data());
985         }
986       }
987       delete pTokens;
988     }
989
990     if (iResult>=0) {
991       if (libs.IsNull()) {
992         const char** deflib=fgkHLTDefaultLibs;
993         while (*deflib) {
994           libs+=*deflib++;
995           libs+=" ";
996         }
997       }
998       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
999           (LoadComponentLibraries(libs.Data())<0)) {
1000         HLTError("error while loading HLT libraries");
1001         iResult=-EFAULT;
1002       }
1003     }
1004   }
1005   return iResult;
1006 }
1007
1008 int AliHLTSystem::Reset(int bForce)
1009 {
1010   // see header file for class documentation
1011   int iResult=0;
1012   if (!bForce && CheckStatus(kRunning)) {
1013     HLTError("HLT system in running state, can not configure");
1014     return -EBUSY;
1015   }
1016   CleanTaskList();
1017   ClearStatusFlags(~kUninitialized);
1018   return iResult;
1019 }
1020
1021 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
1022 {
1023   // see header file for class documentation
1024   if (CheckStatus(kRunning)) {
1025     HLTError("HLT system in running state, can not configure");
1026     return -EBUSY;
1027   }
1028   int iResult=0;
1029   AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1030   while (pAgent && iResult>=0) {
1031     const char* deplibs=pAgent->GetRequiredComponentLibraries();
1032     if (deplibs) {
1033       HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
1034       iResult=LoadComponentLibraries(deplibs);
1035     }
1036     if (iResult>=0) {
1037       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
1038       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
1039       pAgent=AliHLTModuleAgent::GetNextAgent();
1040     }
1041   }
1042   return iResult;
1043 }
1044
1045 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
1046 {
1047   // see header file for class documentation
1048   if (CheckStatus(kRunning)) {
1049     HLTError("HLT system in running state, can not configure");
1050     return -EBUSY;
1051   }
1052   if (!CheckStatus(kConfigurationLoaded)) {
1053     HLTWarning("configurations not yet loaded");
1054     return 0;
1055   }
1056
1057   int iResult=0;
1058   int bHaveOutput=0;
1059
1060   // query chains
1061   TString chains;
1062   if (fChains.Length()>0) {
1063     chains=fChains;
1064     HLTImportant("custom reconstruction chain: %s", chains.Data());
1065   } else {
1066     AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1067     while ((pAgent || fChains.Length()>0) && iResult>=0) {
1068       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
1069       if (agentchains) {
1070         if (!chains.IsNull()) chains+="";
1071         chains+=agentchains;
1072         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
1073       }
1074       pAgent=AliHLTModuleAgent::GetNextAgent();
1075     }
1076   }
1077
1078   // build task list for chains
1079   TObjArray* pTokens=chains.Tokenize(" ");
1080   if (pTokens) {
1081     int iEntries=pTokens->GetEntries();
1082     for (int i=0; i<iEntries && iResult>=0; i++) {
1083       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
1084       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
1085       if (pConf) {
1086         iResult=BuildTaskList(pConf);
1087         if (runloader) {
1088           assert(fpComponentHandler!=NULL);
1089           TString cid=pConf->GetComponentID();
1090           if (cid.CompareTo("HLTOUT")==0) {
1091             // remove from the input of a global HLTOUT configuration
1092             chains.ReplaceAll(pCID, "");
1093           } else if (bHaveOutput==0) {
1094             // check whether this configuration produces data output
1095             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
1096               bHaveOutput=0;
1097               chains.ReplaceAll(pCID, "");
1098             }
1099           }
1100         }
1101       } else {
1102         HLTWarning("can not find configuration %s", pCID);
1103       }
1104     }
1105     delete pTokens;
1106   }
1107
1108   // build HLTOUT for simulation
1109   if (iResult>=0 && runloader) {
1110     if (bHaveOutput) {
1111       // there are components in the chain which produce data which need to be
1112       // piped to an HLTOUT
1113       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
1114           LoadComponentLibraries("libHLTsim.so")>=0) {
1115         AliHLTConfiguration globalout("_globalout_", "HLTOUT", chains.Data(), NULL);
1116         iResult=BuildTaskList("_globalout_");
1117       } else {
1118         HLTError("can not load libHLTsim.so and HLTOUT component");
1119         iResult=-EFAULT;
1120       }
1121     }
1122   }
1123
1124   if (iResult>=0) SetStatusFlags(kTaskListCreated);
1125
1126   return iResult;
1127 }
1128
1129 int AliHLTSystem::CheckStatus(int flag)
1130 {
1131   // see header file for class documentation
1132   if (flag==kUninitialized && flag==fState) return 1;
1133   if ((fState&flag)==flag) return 1;
1134   return 0;
1135 }
1136
1137 int AliHLTSystem::GetStatusFlags()
1138 {
1139   // see header file for class documentation
1140   return fState;
1141 }
1142
1143 int AliHLTSystem::SetStatusFlags(int flags)
1144 {
1145   // see header file for class documentation
1146   fState|=flags;
1147   return fState;
1148 }
1149
1150 int AliHLTSystem::ClearStatusFlags(int flags)
1151 {
1152   // see header file for class documentation
1153   fState&=~flags;
1154   return fState;
1155 }
1156
1157 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
1158 {
1159   // see header file for class documentation
1160   if (fpComponentHandler==NULL) return NULL;
1161   return fpComponentHandler->FindSymbol(library, symbol);
1162 }
1163
1164 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
1165 {
1166   // see header file for class documentation
1167   SetLocalLoggingLevel(level);
1168   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
1169   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
1170 }