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