]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
- AliHLTReconstructor: added helper functions to run HLTOUT processing stand alone
[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     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   return iResult;
618 }
619
620 int AliHLTSystem::SendControlEvent(AliHLTComponentDataType dt)
621 {
622   // see header file for class documentation
623
624   // disabled for the moment
625   return 0;
626
627   int iResult=0;
628   AliHLTRunDesc runDesc;
629   memset(&runDesc, 0, sizeof(AliHLTRunDesc));
630   runDesc.fStructSize=sizeof(AliHLTRunDesc);
631   AliHLTDataSource::AliSpecialEventGuard g(&runDesc, dt, kAliHLTVoidDataSpec);
632   HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
633   TObjLink *lnk=fTaskList.FirstLink();
634   while (lnk && iResult>=0) {
635     TObject* obj=lnk->GetObject();
636     if (obj) {
637       AliHLTTask* pTask=(AliHLTTask*)obj;
638       iResult=pTask->ProcessTask(-1);
639     } else {
640     }
641     lnk = lnk->Next();
642   }
643   HLTDebug("event %s done (%d)", AliHLTComponent::DataType2Text(dt).c_str(), iResult);
644   return iResult;
645 }
646
647 int AliHLTSystem::DeinitTasks()
648 {
649   // see header file for class documentation
650   int iResult=0;
651   TObjLink *lnk=fTaskList.FirstLink();
652   while (lnk && iResult>=0) {
653     TObject* obj=lnk->GetObject();
654     if (obj) {
655       AliHLTTask* pTask=(AliHLTTask*)obj;
656       iResult=pTask->Deinit();
657 //       ProcInfo_t ProcInfo;
658 //       gSystem->GetProcInfo(&ProcInfo);
659 //       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
660     } else {
661     }
662     lnk = lnk->Next();
663   }
664   fEventCount=-1;
665   fGoodEvents=-1;
666
667   return iResult;
668 }
669
670 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
671 {
672   // see header file for class documentation
673   void* p=NULL;
674   try {
675     p=(void*)new char[size];
676   }
677   catch (...) {
678     AliHLTLogging log;
679     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
680   }
681   return p;
682 }
683
684 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
685                               AliRawReader* rawReader)
686 {
687   // see header file for class documentation
688   int iResult=0;
689   if (runLoader || rawReader || nofEvents==0) {
690     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
691     if (CheckStatus(kReady)) {
692       if (nofEvents==0) {
693         // special case to close the reconstruction
694         if (!CheckStatus(kError)) {
695         StopTasks();
696         DeinitTasks();
697         }
698       } else {
699       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
700         // the system always remains started after event processing, a specific
701         // call with nofEvents==0 is needed to execute the stop sequence
702         if ((iResult=Run(nofEvents, 0))<0) SetStatusFlags(kError);
703       }
704       }
705     } else {
706       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
707     }
708   } else {
709     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
710     iResult=-EINVAL;
711   }
712   return iResult;
713 }
714
715 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
716 {
717   // see header file for class documentation
718   int iResult=0;
719   if (runLoader || esd) {
720     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
721     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
722   } else {
723     HLTError("missing run loader/ESD instance(s)");
724     iResult=-EINVAL;
725   }
726   return iResult;
727 }
728
729 int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
730 {
731   // see header file for class documentation
732   int iResult=0;
733   if (!pHLTOUT) return -EINVAL;
734
735   HLTDebug("processing %d HLT data blocks", pHLTOUT->GetNofDataBlocks());
736   AliHLTOUT::AliHLTOUTHandlerListEntryVector esdHandlers;
737
738   // first come first serve: the ESD of the first handler is also filled into
739   // the main ESD. Has to be changed later.
740   // currently, merging to the provided ESDs crashes at the level of the
741   // TTree::Fill in AliReconstruction, furthermore, the wrong ESD is passed
742   // by the framework
743   AliESDEvent* pMasterESD=NULL;
744   if (bWriteGlobalEsd) pMasterESD=esd;
745   for (iResult=pHLTOUT->SelectFirstDataBlock();
746        iResult>=0;
747        iResult=pHLTOUT->SelectNextDataBlock()) {
748     AliHLTComponentDataType dt=kAliHLTVoidDataType;
749     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
750     pHLTOUT->GetDataBlockDescription(dt, spec);
751     AliHLTOUTHandler* pHandler=pHLTOUT->GetHandler();
752     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=pHLTOUT->GetDataBlockHandlerType();
753     if (!pHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
754       handlerType=AliHLTModuleAgent::kEsd;
755     }
756     const char* pMsg="invalid";
757     switch (handlerType) {
758     case AliHLTModuleAgent::kEsd:
759       {
760         if (pHandler) {
761           // preprocess and write later
762           AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
763           pHandler->ProcessData(pHLTOUT);
764           pHLTOUT->InsertHandler(esdHandlers, pHLTOUT->GetDataBlockHandlerDesc());
765         } else {
766           // write directly
767           const AliHLTUInt8_t* pBuffer=NULL;
768           AliHLTUInt32_t size=0;
769           if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
770             pHLTOUT->WriteESD(pBuffer, size, dt);
771             if (pMasterESD) {
772               pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
773               pMasterESD=NULL;
774             }
775             pHLTOUT->ReleaseDataBuffer(pBuffer);
776           }
777         }
778       }
779       break;
780     case AliHLTModuleAgent::kRawReader:
781       // handled in the AliRawReaderHLT
782       break;
783     case AliHLTModuleAgent::kRawStream:
784       HLTWarning("HLTOUT handler type 'kRawStream' not yet implemented: agent %s, data type %s, specification %#x",
785                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
786                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
787       break;
788     case AliHLTModuleAgent::kChain:
789       HLTWarning("HLTOUT handler type 'kChain' not yet implemented: agent %s, data type %s, specification %#x",
790                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
791                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
792       break;
793     case AliHLTModuleAgent::kProprietary:
794       HLTDebug("processing proprietary data: agent %s, data type %s, specification %#x",
795                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
796                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
797       if (pHandler) {
798         AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
799         int res=pHandler->ProcessData(pHLTOUT);
800         if (res<0) {
801           HLTWarning("processing proprietary data failed (%d): agent %s, data type %s, specification %#x",
802                      res, pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
803                      AliHLTComponent::DataType2Text(dt).c_str(), spec);
804         }
805       }
806       break;
807     case AliHLTModuleAgent::kUnknownOutput:
808       pMsg="unknown";
809       // fall trough intended
810     default:
811       HLTWarning("%s handler type: agent %s, data type %s, specification %#x, ... skipping data block",
812                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"invalid",
813                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
814     }
815   }
816   // TODO: the return value of SelectFirst/NextDataBlock must be
817   // changed in order to avoid this check
818   if (iResult==-ENOENT) iResult=0;
819
820   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator esdHandler;
821   // write all postponed esd data blocks
822   for (esdHandler=esdHandlers.begin(); esdHandler!=esdHandlers.end() && iResult>=0; esdHandler++) {
823     AliHLTOUTHandler* pHandler=*esdHandler;
824     const AliHLTUInt8_t* pBuffer=NULL;
825     AliHLTUInt32_t size=0;
826     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
827       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*esdHandler;
828       AliHLTComponentDataType dt=desc;
829       pHLTOUT->WriteESD(pBuffer, size, dt);
830       if (pMasterESD) {
831         pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
832         pMasterESD=NULL;
833       }
834       pHandler->ReleaseProcessedData(pBuffer, size);
835     }
836   }
837
838   return iResult;
839 }
840
841 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
842 {
843   // see header file for class documentation
844   int iResult=0;
845   if (libraries) {
846     if (fpComponentHandler) {
847       TString libs(libraries);
848       TObjArray* pTokens=libs.Tokenize(" ");
849       if (pTokens) {
850         int iEntries=pTokens->GetEntries();
851         for (int i=0; i<iEntries && iResult>=0; i++) {
852           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
853         }
854         delete pTokens;
855       }
856       if (iResult>=0) {
857         SetStatusFlags(kLibrariesLoaded);
858       } else {
859         // lets see if we need this, probably not
860         //fpComponentHandler->UnloadLibraries();
861         ClearStatusFlags(kLibrariesLoaded);
862       }
863     } else {
864       iResult=-EFAULT;
865       HLTFatal("no component handler available");
866     }
867   } else {
868     iResult=-EINVAL;
869   }
870   return iResult;
871 }
872
873 int AliHLTSystem::Configure(AliRunLoader* runloader)
874 {
875   // see header file for class documentation
876   return Configure(NULL, runloader);
877 }
878
879 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
880 {
881   // see header file for class documentation
882   int iResult=0;
883   if (CheckStatus(kRunning)) {
884     HLTError("HLT system in running state, can not configure");
885     return -EBUSY;
886   }
887   ClearStatusFlags(kTaskListCreated);
888   if (CheckFilter(kHLTLogDebug))
889     AliHLTModuleAgent::PrintStatus();
890   if (CheckStatus(kConfigurationLoaded)==0) {
891     iResult=LoadConfigurations(rawReader, runloader);
892   } else {
893     if (fChains.Length()==0) {
894       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'localrec=<conf>\' option");
895       iResult=-ENOENT;
896     }
897   }
898   if (iResult>=0) {
899     SetStatusFlags(kConfigurationLoaded);
900     if (CheckFilter(kHLTLogDebug))
901       fpConfigurationHandler->PrintConfigurations();
902     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
903     if (iResult>=0) {
904       SetStatusFlags(kTaskListCreated);
905     }
906   }
907   if (iResult<0) SetStatusFlags(kError);
908   
909   return iResult;
910 }
911
912 int AliHLTSystem::ScanOptions(const char* options)
913 {
914   // see header file for class documentation
915   int iResult=0;
916   if (options) {
917     //AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
918     TString libs("");
919     TString alloptions(options);
920     TObjArray* pTokens=alloptions.Tokenize(" ");
921     if (pTokens) {
922       int iEntries=pTokens->GetEntries();
923       for (int i=0; i<iEntries; i++) {
924         TString token=(((TObjString*)pTokens->At(i))->GetString());
925         if (token.Contains("loglevel=")) {
926           TString param=token.ReplaceAll("loglevel=", "");
927           if (param.IsDigit()) {
928             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
929           } else if (param.BeginsWith("0x") &&
930                      param.Replace(0,2,"",0).IsHex()) {
931             int severity=0;
932             sscanf(param.Data(),"%x", &severity);
933             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
934           } else {
935             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
936           }
937         } else if (token.Contains("frameworklog=")) {
938           TString param=token.ReplaceAll("frameworklog=", "");
939           if (param.IsDigit()) {
940             SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
941           } else if (param.BeginsWith("0x") &&
942                      param.Replace(0,2,"",0).IsHex()) {
943             int severity=0;
944             sscanf(param.Data(),"%x", &severity);
945             SetFrameworkLog((AliHLTComponentLogSeverity)severity);
946           } else {
947             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
948           }
949         } else if (token.Contains("alilog=off")) {
950           SwitchAliLog(0);
951         } else if (token.Contains("config=")) {
952           TString param=token.ReplaceAll("config=", "");
953           Int_t error=0;
954           gROOT->Macro(param.Data(), &error);
955           if (error==0) {
956             SetStatusFlags(kConfigurationLoaded);
957           } else {
958             HLTError("can not execute macro \'%s\'", param.Data());
959             iResult=-EBADF;
960           }
961         } else if (token.Contains("chains=")) {
962           TString param=token.ReplaceAll("chains=", "");
963           fChains=param.ReplaceAll(",", " ");
964         } else if (token.Contains("libmode=")) {
965           TString param=token.ReplaceAll("libmode=", "");
966           param.ReplaceAll(",", " ");
967           if (fpComponentHandler) {
968             if (param.CompareTo("static")==0) {
969               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
970             } else if (param.CompareTo("dynamic")==0) {
971               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
972             } else {
973               HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
974             }
975           }
976         } else if (token.Contains("globalesd")) {
977           bWriteGlobalEsd=true;
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   while (pAgent && iResult>=0) {
1029     const char* deplibs=pAgent->GetRequiredComponentLibraries();
1030     if (deplibs) {
1031       HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
1032       iResult=LoadComponentLibraries(deplibs);
1033     }
1034     if (iResult>=0) {
1035       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
1036       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
1037       pAgent=AliHLTModuleAgent::GetNextAgent();
1038     }
1039   }
1040   return iResult;
1041 }
1042
1043 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
1044 {
1045   // see header file for class documentation
1046   if (CheckStatus(kRunning)) {
1047     HLTError("HLT system in running state, can not configure");
1048     return -EBUSY;
1049   }
1050   if (!CheckStatus(kConfigurationLoaded)) {
1051     HLTWarning("configurations not yet loaded");
1052     return 0;
1053   }
1054
1055   int iResult=0;
1056   int bHaveOutput=0;
1057
1058   // query chains
1059   TString chains;
1060   if (fChains.Length()>0) {
1061     chains=fChains;
1062     HLTImportant("custom reconstruction chain: %s", chains.Data());
1063   } else {
1064     AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1065     while ((pAgent || fChains.Length()>0) && iResult>=0) {
1066       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
1067       if (agentchains) {
1068         if (!chains.IsNull()) chains+="";
1069         chains+=agentchains;
1070         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
1071       }
1072       pAgent=AliHLTModuleAgent::GetNextAgent();
1073     }
1074   }
1075
1076   // build task list for chains
1077   TObjArray* pTokens=chains.Tokenize(" ");
1078   if (pTokens) {
1079     int iEntries=pTokens->GetEntries();
1080     for (int i=0; i<iEntries && iResult>=0; i++) {
1081       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
1082       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
1083       if (pConf) {
1084         iResult=BuildTaskList(pConf);
1085         if (runloader) {
1086           assert(fpComponentHandler!=NULL);
1087           TString cid=pConf->GetComponentID();
1088           if (cid.CompareTo("HLTOUT")==0) {
1089             // remove from the input of a global HLTOUT configuration
1090             chains.ReplaceAll(pCID, "");
1091           } else if (bHaveOutput==0) {
1092             // check whether this configuration produces data output
1093             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
1094               bHaveOutput=0;
1095               chains.ReplaceAll(pCID, "");
1096             }
1097           }
1098         }
1099       } else {
1100         HLTWarning("can not find configuration %s", pCID);
1101       }
1102     }
1103     delete pTokens;
1104   }
1105
1106   // build HLTOUT for simulation
1107   if (iResult>=0 && runloader) {
1108     if (bHaveOutput) {
1109       // there are components in the chain which produce data which need to be
1110       // piped to an HLTOUT
1111       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
1112           LoadComponentLibraries("libHLTsim.so")>=0) {
1113         AliHLTConfiguration globalout("_globalout_", "HLTOUT", chains.Data(), NULL);
1114         iResult=BuildTaskList("_globalout_");
1115       } else {
1116         HLTError("can not load libHLTsim.so and HLTOUT component");
1117         iResult=-EFAULT;
1118       }
1119     }
1120   }
1121
1122   if (iResult>=0) SetStatusFlags(kTaskListCreated);
1123
1124   return iResult;
1125 }
1126
1127 int AliHLTSystem::CheckStatus(int flag)
1128 {
1129   // see header file for class documentation
1130   if (flag==kUninitialized && flag==fState) return 1;
1131   if ((fState&flag)==flag) return 1;
1132   return 0;
1133 }
1134
1135 int AliHLTSystem::GetStatusFlags()
1136 {
1137   // see header file for class documentation
1138   return fState;
1139 }
1140
1141 int AliHLTSystem::SetStatusFlags(int flags)
1142 {
1143   // see header file for class documentation
1144   fState|=flags;
1145   return fState;
1146 }
1147
1148 int AliHLTSystem::ClearStatusFlags(int flags)
1149 {
1150   // see header file for class documentation
1151   fState&=~flags;
1152   return fState;
1153 }
1154
1155 void* AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
1156 {
1157   // see header file for class documentation
1158   if (fpComponentHandler==NULL) return NULL;
1159   return fpComponentHandler->FindSymbol(library, symbol);
1160 }
1161
1162 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
1163 {
1164   // see header file for class documentation
1165   SetLocalLoggingLevel(level);
1166   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
1167   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
1168 }