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