]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
Bug Fix.
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2 //**************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project        * 
4 //* ALICE Experiment at CERN, All rights reserved.                         *
5 //*                                                                        *
6 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
7 //*                  for The ALICE HLT Project.                            *
8 //*                                                                        *
9 //* Permission to use, copy, modify and distribute this software and its   *
10 //* documentation strictly for non-commercial purposes is hereby granted   *
11 //* without fee, provided that the above copyright notice appears in all   *
12 //* copies and that both the copyright notice and this permission notice   *
13 //* appear in the supporting documentation. The authors make no claims     *
14 //* about the suitability of this software for any purpose. It is          *
15 //* provided "as is" without express or implied warranty.                  *
16 //**************************************************************************
17
18 /** @file   AliHLTSystem.cxx
19     @author Matthias Richter
20     @date   
21     @brief  Implementation of HLT module management.
22 */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include <cassert>
29 #include "AliHLTStdIncludes.h"
30 #include "AliHLTSystem.h"
31 #include "AliHLTComponentHandler.h"
32 #include "AliHLTComponent.h"
33 #include "AliHLTConfiguration.h"
34 #include "AliHLTConfigurationHandler.h"
35 #include "AliHLTTask.h"
36 #include "AliHLTModuleAgent.h"
37 #include "AliHLTOfflineInterface.h"
38 #include "AliHLTDataSource.h"
39 #include "AliHLTOUT.h"
40 #include "AliHLTOUTHandler.h"
41 #include "AliHLTOUTTask.h"
42 #include "AliHLTControlTask.h"
43 #include "AliHLTDataBuffer.h"
44 #include "AliHLTMisc.h"
45 #include <TObjArray.h>
46 #include <TObjString.h>
47 #include <TStopwatch.h>
48 #include <TList.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   "libAliHLTRCU.so", 
57   "libAliHLTTPC.so", 
58   //  "libAliHLTSample.so",
59   //  "libAliHLTPHOS.so",
60   "libAliHLTMUON.so",
61   "libAliHLTTRD.so",
62   "libAliHLTITS.so",
63   "libAliHLTVZERO.so",
64   "libAliHLTZDC.so",
65   "libAliHLTGlobal.so",
66   "libAliHLTTrigger.so",
67   NULL
68 };
69
70 /** ROOT macro for the implementation of ROOT specific class methods */
71 ClassImp(AliHLTSystem)
72
73 AliHLTSystem::AliHLTSystem(AliHLTComponentLogSeverity loglevel, const char* name,
74                            AliHLTComponentHandler* pCompHandler,
75                            AliHLTConfigurationHandler* pConfHandler
76                            )
77   : fpComponentHandler(pCompHandler==NULL?AliHLTComponentHandler::CreateHandler():pCompHandler)
78   , fpConfigurationHandler(pConfHandler==NULL?AliHLTConfigurationHandler::CreateHandler():pConfHandler),
79   fTaskList(),
80   fState(0),
81   fChains(),
82   fStopwatches(new TObjArray),
83   fEventCount(-1),
84   fGoodEvents(-1),
85   fpChainHandlers(NULL),
86   fpEsdHandlers(NULL),
87   fpProprietaryHandlers(NULL),
88   fpHLTOUTTask(NULL),
89   fpControlTask(NULL),
90   fName(name)
91   , fECSParams()
92   , fUseHLTOUTComponentTypeGlobal(true)
93 {
94   // see header file for class documentation
95   // or
96   // refer to README to build package
97   // or
98   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
99
100   if (fgNofInstances++>0) {
101     // July 2008: multiple instances are now allowed
102     // AliHLTSystem is used in multiple instances for the kChain HLTOUT handler
103     //HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
104   }
105
106   SetGlobalLoggingLevel(loglevel);
107   SetFrameworkLog(loglevel);
108   if (fpComponentHandler) {
109     AliHLTAnalysisEnvironment env;
110     memset(&env, 0, sizeof(AliHLTAnalysisEnvironment));
111     env.fStructSize=sizeof(AliHLTAnalysisEnvironment);
112     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
113     env.fGetEventDoneDataFunc=AliHLTSystem::AllocEventDoneData;
114     env.fLoggingFunc=NULL;
115     fpComponentHandler->SetEnvironment(&env);
116     InitAliLogFunc(fpComponentHandler);
117     if (fgNofInstances==1) {
118     fpComponentHandler->AnnounceVersion();
119     }
120   } else {
121     HLTFatal("can not create Component Handler");
122   }
123   if (fpConfigurationHandler) {
124     AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
125   } else {
126     HLTFatal("can not create Configuration Handler");
127   }
128 }
129
130 AliHLTSystem::~AliHLTSystem()
131 {
132   // see header file for class documentation
133   fgNofInstances--;
134   CleanHLTOUT();
135   CleanTaskList();
136   AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
137   if (fpConfigurationHandler) {
138     fpConfigurationHandler->Destroy();
139   }
140   fpConfigurationHandler=NULL;
141   
142   if (fpComponentHandler) {
143     fpComponentHandler->Destroy();
144   }
145   fpComponentHandler=NULL;
146   delete fStopwatches;
147
148   // note: fpHLTOUTTask and fpControlTask are deleted by
149   // CleanTaskList
150 }
151
152 int AliHLTSystem::fgNofInstances=0;
153
154 int AliHLTSystem::BuildTaskList(const char* id)
155 {
156   // see header file for class documentation
157   int iResult=0;
158   if (id) {
159     if (fpConfigurationHandler) {
160       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(id);
161       if (pConf) {
162         iResult=BuildTaskList(pConf);
163       } else {
164         HLTError("unknown configuration \"%s\"", id);
165         iResult=-EEXIST;
166       }
167     } else {
168       iResult=-EFAULT;
169     }
170   } else {
171     iResult=-EINVAL;
172   }
173   return iResult;
174 }
175
176 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
177 {
178   // see header file for class documentation
179   int iResult=0;
180   if (pConf) {
181     AliHLTTask* pTask=NULL;
182     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
183       if (pTask->GetConf()!=pConf) {
184         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);
185         iResult=-EEXIST;
186       }
187       // task for this configuration exists, terminate
188       pTask=NULL;
189     // check first if the configuration has all sources resolved, try to extract otherwise
190     } else if (pConf->SourcesResolved()!=1 && pConf->ExtractSources()!=1) {
191         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
192         iResult=-ENOLINK;
193     } else {
194       pTask=new AliHLTTask(pConf);
195       if (pTask==NULL) {
196         iResult=-ENOMEM;
197       } else {
198         pTask->SetLocalLoggingLevel(GetLocalLoggingLevel());
199       }
200     }
201     static int iterationLevel=0;
202     if (pTask && iResult>=0) {
203       // check for circular dependencies
204       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
205         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
206         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
207         HLTError("aborted ...");
208         iResult=-ELOOP;
209       }
210       if (iResult>=0) {
211         // check whether all dependencies are already in the task list
212         // create the missing ones
213         // this step is an iterative process which calls this function again for the missing
214         // configurations, in order to avoid the currently processed task to be created
215         // again it is added to the list temporarily and removed afterwards
216         // This is of high importance to preserve the order of the tasks. Furthermore, the
217         // InsertTask method has to be used in order to set all the cross links right 
218         fTaskList.Add(pTask);
219         AliHLTConfiguration* pDep=pConf->GetFirstSource();
220         while (pDep!=NULL && iResult>=0) {
221           HLTDebug("iteration %d: checking dependency %s (%p)", iterationLevel, pDep->GetName(), pDep);
222           if (FindTask(pDep->GetName())==NULL) {
223             HLTDebug("iteration %d: building task list for configuration %s (%p)", iterationLevel, pDep->GetName(), pDep);
224             iterationLevel++;
225             iResult=BuildTaskList(pDep);
226             iterationLevel--;
227           }
228           pDep=pConf->GetNextSource();
229         }
230         // remove the temporarily added task
231         fTaskList.Remove(pTask);
232
233         // insert the task and set the cross-links
234         if (iResult>=0) {
235           HLTDebug("iteration %d: inserting task %s (%p)", iterationLevel, pTask->GetName(), pTask);
236           iResult=InsertTask(pTask);
237         }
238       } else {
239         delete pTask;
240         pTask=NULL;
241       }
242     }
243   } else {
244     iResult=-EINVAL;
245   }
246   return iResult;
247 }
248
249 int AliHLTSystem::CleanTaskList()
250 {
251   // see header file for class documentation
252   int iResult=0;
253   fpHLTOUTTask=NULL;
254   fpControlTask=NULL;
255   TObjLink* lnk=NULL;
256   while ((lnk=fTaskList.LastLink())!=NULL) {
257     delete (lnk->GetObject());
258     fTaskList.Remove(lnk);
259   }
260
261   return iResult;
262 }
263
264 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
265 {
266   // see header file for class documentation
267   int iResult=0;
268   if (fpControlTask==NULL) {
269     fpControlTask=new AliHLTControlTask;
270     if (!fpControlTask) return -ENOMEM;
271     fTaskList.AddFirst(fpControlTask);
272   }
273   TObjLink *controlLnk=NULL;
274   TObjLink *lnk = fTaskList.FirstLink();
275   assert(!lnk || lnk->GetObject()==fpControlTask || fpControlTask==NULL);
276   if (lnk && lnk->GetObject()==fpControlTask) {
277     if (pTask->GetConf() && pTask->GetConf()->GetFirstSource()==NULL) {
278       pTask->SetDependency(fpControlTask);
279       fpControlTask->SetTarget(pTask);
280     }
281     controlLnk=lnk;
282     lnk=lnk->Next();
283   }
284   if ((iResult=pTask->CheckDependencies())<=0)
285     lnk=NULL;
286   while (lnk && iResult>0) {
287     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
288     //HLTDebug("checking  \"%s\"", pCurr->GetName());
289     iResult=pTask->Depends(pCurr);
290     if (iResult>0) {
291       iResult=pTask->SetDependency(pCurr);
292       pCurr->SetTarget(pTask);
293       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
294     }
295     if (pCurr->Depends(pTask)) {
296       // circular dependency
297       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
298       iResult=-ELOOP;
299     } else if ((iResult=pTask->CheckDependencies())>0) {
300       lnk = lnk->Next();
301     }
302   }
303   if (iResult==0) {
304       if (lnk) {
305         fTaskList.AddAfter(lnk, pTask);
306       } else if (controlLnk) {
307         fTaskList.AddAfter(controlLnk, pTask);
308       } else {
309         fTaskList.AddFirst(pTask);
310       }
311       HLTDebug("task \"%s\" (%p) inserted (size %d)", pTask->GetName(), pTask, sizeof(AliHLTTask));
312   } else if (iResult>0) {
313     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
314     iResult=-ENOLINK;
315   }
316   return iResult;
317 }
318
319 AliHLTTask* AliHLTSystem::FindTask(const char* id)
320 {
321   // see header file for class documentation
322   AliHLTTask* pTask=NULL;
323   if (id) {
324     pTask=dynamic_cast<AliHLTTask*>(fTaskList.FindObject(id)); 
325   }
326   return pTask;
327 }
328
329 void AliHLTSystem::PrintTaskList()
330 {
331   // see header file for class documentation
332   HLTLogKeyword("task list");
333   TObjLink *lnk = NULL;
334   HLTMessage("Task List");
335   lnk=fTaskList.FirstLink();
336   while (lnk) {
337     TObject* obj=lnk->GetObject();
338     if (obj) {
339       HLTMessage("  %s - status:", obj->GetName());
340       AliHLTTask* pTask=(AliHLTTask*)obj;
341       pTask->PrintStatus();
342     } else {
343     }
344     lnk = lnk->Next();
345   }
346 }
347
348 int AliHLTSystem::Run(Int_t iNofEvents, int bStop, AliHLTUInt64_t trgMask,
349                       AliHLTUInt32_t timestamp, AliHLTUInt32_t eventtype,
350                       AliHLTUInt32_t participatingDetectors)
351 {
352   // see header file for class documentation
353   int iResult=0;
354   int iCount=0;
355   SetStatusFlags(kRunning);
356   if (fEventCount>=0 || (iResult=InitTasks())>=0) {
357     if (fEventCount>=0 || (iResult=StartTasks())>=0) {
358       if (fEventCount==0) {
359         InitBenchmarking(fStopwatches);
360       } else {
361         // Matthias Oct 11 2008 this is a bug
362         // By resuming the stopwatches at this point, all continued counting, but the
363         // starting and stopping is controlled by the AliHLTStopwatchGuard
364         //ResumeBenchmarking(fStopwatches);    
365       }
366       for (int i=fEventCount; i<fEventCount+iNofEvents && iResult>=0; i++) {
367         if (fpHLTOUTTask) {
368           if (iNofEvents>1 && i==fEventCount) {
369             HLTWarning("can not add more than one event to the HLTOUT, skipping all but last block");
370           }
371           // reset and prepare for new data
372           fpHLTOUTTask->Reset();
373         }
374         if (eventtype == 0) {
375           eventtype = gkAliEventTypeData;
376           participatingDetectors = 0x0;
377         }
378         if ((iResult=ProcessTasks(i, trgMask, timestamp, eventtype, participatingDetectors))>=0) {
379           fGoodEvents++;
380           iCount++;
381         } else {
382           // TODO: define different running modes to either ignore errors in
383           // event processing or not
384           // currently ignored 
385           iResult=0;
386         }
387         AliHLTDataBuffer::SetGlobalEventCount(iCount);
388       }
389       fEventCount+=iNofEvents;
390       if (bStop) StopTasks();
391       else PauseBenchmarking(fStopwatches);
392     }
393     if (bStop) DeinitTasks();
394   }
395   if (iResult>=0) {
396     iResult=iCount;
397   } else  if (iResult==-126 /*ENOKEY*/) {
398     iResult=0; // do not propagate the error
399   }
400   ClearStatusFlags(kRunning);
401   AliHLTDataBuffer::PrintStatistics();
402   return iResult;
403 }
404
405 int AliHLTSystem::InitTasks()
406 {
407   // see header file for class documentation
408   int iResult=0;
409   TObjLink *lnk=fTaskList.FirstLink();
410
411   if (lnk==NULL) {
412     HLTInfo("Task list is empty, skipping HLT");
413     return -126 /*ENOKEY*/;
414   }
415   while (lnk && iResult>=0) {
416     TObject* obj=lnk->GetObject();
417     if (obj) {
418       AliHLTTask* pTask=(AliHLTTask*)obj;
419       iResult=pTask->Init(NULL, fpComponentHandler);
420 //       ProcInfo_t ProcInfo;
421 //       gSystem->GetProcInfo(&ProcInfo);
422 //       HLTInfo("task %s initialized (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
423     } else {
424     }
425     lnk = lnk->Next();
426   }
427   if (iResult<0) {
428     HLTError("can not initialize task list, error %d", iResult);
429   }
430
431   return iResult;
432 }
433
434 int AliHLTSystem::InitBenchmarking(TObjArray* pStopwatches)
435 {
436   // see header file for class documentation
437   int iResult=0;
438   if (pStopwatches==NULL) return 0;
439
440   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
441     TStopwatch* pStopwatch= new TStopwatch;
442     if (pStopwatch) {
443       pStopwatch->Reset();
444       pStopwatches->AddAt(pStopwatch, i);
445     } else {
446       iResult=-ENOMEM;
447       break;
448     }
449   }
450
451   TObjLink *lnk=fTaskList.FirstLink();
452   while (lnk && iResult>=0) {
453     TObject* obj=lnk->GetObject();
454     if (obj) {
455       AliHLTTask* pTask=(AliHLTTask*)obj;
456       AliHLTComponent* pComp=NULL;
457       if (iResult>=0 && (pComp=pTask->GetComponent())!=NULL) {
458         switch (pComp->GetComponentType()) {
459         case AliHLTComponent::kProcessor:
460           pComp->SetStopwatches(pStopwatches);
461           break;
462         case AliHLTComponent::kSource:
463           {
464             // this switch determines whether the time consumption of the
465             // AliHLTComponent base methods should be counted to the input
466             // stopwatch or base stopwatch.
467             //int inputBase=(int)AliHLTComponent::kSWBase;
468             int inputBase=(int)AliHLTComponent::kSWInput;
469             pComp->SetStopwatch(pStopwatches->At(inputBase), AliHLTComponent::kSWBase);
470             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWInput), AliHLTComponent::kSWDA);
471           }
472           break;
473         case AliHLTComponent::kSink:
474           {
475             // this switch determines whether the time consumption of the
476             // AliHLTComponent base methods should be counted to the output
477             // stopwatch or base stopwatch.
478             //int outputBase=(int)AliHLTComponent::kSWBase;
479             int outputBase=(int)AliHLTComponent::kSWOutput;
480             pComp->SetStopwatch(pStopwatches->At(outputBase), AliHLTComponent::kSWBase);
481             pComp->SetStopwatch(pStopwatches->At((int)AliHLTComponent::kSWOutput), AliHLTComponent::kSWDA);
482           }
483           break;
484         default:
485           HLTWarning("unknown component type %d", (int)pComp->GetComponentType());
486         }
487       }
488     } else {
489     }
490     lnk = lnk->Next();
491   }
492   return iResult;
493 }
494
495 int AliHLTSystem::PauseBenchmarking(TObjArray* pStopwatches) const
496 {
497   // see header file for class documentation
498   if (pStopwatches==NULL) return 0;
499
500   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
501     if (!pStopwatches->At(i)) continue;
502     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
503     if (pSw) pSw->Stop();
504   }
505   return 0;
506 }
507
508 int AliHLTSystem::ResumeBenchmarking(TObjArray* pStopwatches) const
509 {
510   // see header file for class documentation
511   if (pStopwatches==NULL) return 0;
512
513   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
514     if (!pStopwatches->At(i)) continue;
515     TStopwatch* pSw=dynamic_cast<TStopwatch*>(pStopwatches->At(i));
516     if (pSw) pSw->Continue();
517   }
518   return 0;
519 }
520
521 int AliHLTSystem::PrintBenchmarking(TObjArray* pStopwatches, int bClean) const
522 {
523   // see header file for class documentation
524   int iInitialized=1;
525   if (pStopwatches==NULL) return 0;
526
527   for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
528     if (!dynamic_cast<TStopwatch*>(pStopwatches->At(i))) {
529       iInitialized=0;
530       break;
531     }
532   }
533
534   if (iInitialized!=0) {
535     HLTImportant("HLT statistics:\n"
536             "    base:              R:%.3fs C:%.3fs\n"
537             "    input:             R:%.3fs C:%.3fs\n"
538             "    output:            R:%.3fs C:%.3fs\n"
539             "    event processing : R:%.3fs C:%.3fs"
540             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->RealTime()
541             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWBase))->CpuTime()
542             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->RealTime()
543             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWInput))->CpuTime()
544             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->RealTime()
545             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWOutput))->CpuTime()
546             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->RealTime()
547             , dynamic_cast<TStopwatch*>(pStopwatches->At(AliHLTComponent::kSWDA))->CpuTime()
548             );
549   }
550
551   if (bClean) {
552     for (int i=0; i<(int)AliHLTComponent::kSWTypeCount; i++) {
553       TObject* pObj=pStopwatches->RemoveAt(i);
554       if (pObj) delete pObj;
555     }
556   }
557   return 0;
558 }
559
560 int AliHLTSystem::StartTasks()
561 {
562   // see header file for class documentation
563   int iResult=0;
564   TObjLink *lnk=fTaskList.FirstLink();
565   while (lnk && iResult>=0) {
566     TObject* obj=lnk->GetObject();
567     if (obj) {
568       AliHLTTask* pTask=(AliHLTTask*)obj;
569       iResult=pTask->StartRun();
570 //       ProcInfo_t ProcInfo;
571 //       gSystem->GetProcInfo(&ProcInfo);
572 //       HLTInfo("task %s started (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
573     } else {
574     }
575     lnk = lnk->Next();
576   }
577   if (iResult<0) {
578     HLTError("can not start task list, error %d", iResult);
579   } else {
580     SetStatusFlags(kStarted);
581     fEventCount=0;
582     fGoodEvents=0;
583     if ((iResult=SendControlEvent(kAliHLTDataTypeSOR))<0) {
584       HLTError("can not send SOR event: error %d", iResult);
585     }
586   }
587   return iResult;
588 }
589
590 int AliHLTSystem::ProcessTasks(Int_t eventNo, AliHLTUInt64_t trgMask,
591           AliHLTUInt32_t timestamp, AliHLTUInt32_t eventtype,
592           AliHLTUInt32_t participatingDetectors)
593 {
594   // see header file for class documentation
595   int iResult=0;
596   HLTDebug("processing event no %d", eventNo);
597   TObjLink *lnk=fTaskList.FirstLink();
598   while (lnk) {
599     TObject* obj=lnk->GetObject();
600     if (obj) {
601       AliHLTTask* pTask=(AliHLTTask*)obj;
602       if (iResult>=0) {
603       iResult=pTask->ProcessTask(eventNo, eventtype, trgMask, timestamp, participatingDetectors);
604 //       ProcInfo_t ProcInfo;
605 //       gSystem->GetProcInfo(&ProcInfo);
606 //       HLTInfo("task %s processed (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
607       } else {
608         pTask->SubscribeSourcesAndSkip();
609       }
610     } else {
611     }
612     lnk = lnk->Next();
613   }
614
615   if (iResult>=0) {
616     HLTImportant("Event %d successfully finished (%d)", eventNo, iResult);
617     iResult=0;
618   } else {
619     HLTError("Processing of event %d failed (%d)", eventNo, iResult);
620   }
621
622   return iResult;
623 }
624
625 int AliHLTSystem::StopTasks()
626 {
627   // see header file for class documentation
628   int iResult=0;
629   if ((iResult=SendControlEvent(kAliHLTDataTypeEOR))<0) {
630     HLTError("can not send EOR event");
631   }
632
633   // cleanup blocks from the last event. This is a bit awkward. All output
634   // blocks from the chains need to be stored in the HLTOUT task. Though,
635   // we do not know, whether HLTOUT is going to be processed or not.
636   if (fpHLTOUTTask)
637     fpHLTOUTTask->Reset();
638
639   TObjLink *lnk=fTaskList.FirstLink();
640   while (lnk) {
641     TObject* obj=lnk->GetObject();
642     if (obj) {
643       AliHLTTask* pTask=(AliHLTTask*)obj;
644       int locResult=pTask->EndRun();
645       if (iResult>=0 && locResult<0) iResult=locResult;
646 //       ProcInfo_t ProcInfo;
647 //       gSystem->GetProcInfo(&ProcInfo);
648 //       HLTInfo("task %s stopped (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
649     } else {
650     }
651     lnk = lnk->Next();
652   }
653   PrintBenchmarking(fStopwatches, 1 /*clean*/);
654   ClearStatusFlags(kStarted);
655   return iResult;
656 }
657
658 int AliHLTSystem::SendControlEvent(AliHLTComponentDataType dt)
659 {
660   // see header file for class documentation
661   int iResult=0;
662
663   AliHLTComponentBlockDataList controlBlocks;
664   AliHLTComponentBlockData bd;
665
666   // run decriptor block of type kAliHLTDataTypeSOR/kAliHLTDataTypeEOR 
667   AliHLTComponent::FillBlockData(bd);
668   AliHLTRunDesc runDesc;
669   memset(&runDesc, 0, sizeof(AliHLTRunDesc));
670   runDesc.fStructSize=sizeof(AliHLTRunDesc);
671   runDesc.fRunNo=AliHLTMisc::Instance().GetCDBRunNo();
672   bd.fPtr=&runDesc;
673   bd.fSize=sizeof(AliHLTRunDesc);
674   bd.fDataType=dt;
675   bd.fSpecification=kAliHLTVoidDataSpec;
676   controlBlocks.push_back(bd);
677
678   // ECS parameter of type kAliHLTDataTypeECSParam
679   if (fECSParams.IsNull())
680     fECSParams="CTP_TRIGGER_CLASS=00:DUMMY-TRIGGER-ALL:00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17";
681   AliHLTComponent::FillBlockData(bd);
682   bd.fPtr=(void*)fECSParams.Data();
683   bd.fSize=fECSParams.Length()+1;
684   bd.fDataType=kAliHLTDataTypeECSParam;
685   bd.fSpecification=kAliHLTVoidDataSpec;
686   controlBlocks.push_back(bd);  
687
688   AliHLTControlTask::AliHLTControlEventGuard g(fpControlTask, controlBlocks);
689   HLTDebug("sending event %s, run descriptor %p", AliHLTComponent::DataType2Text(dt).c_str(), &runDesc);
690   TObjLink *lnk=fTaskList.FirstLink();
691   while (lnk && iResult>=0) {
692     TObject* obj=lnk->GetObject();
693     if (obj) {
694       AliHLTTask* pTask=(AliHLTTask*)obj;
695       AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
696       if (dt==kAliHLTDataTypeSOR) eventType=gkAliEventTypeStartOfRun;
697       else if (dt==kAliHLTDataTypeEOR) eventType=gkAliEventTypeEndOfRun;
698       else HLTWarning("unknown control event %s", AliHLTComponent::DataType2Text(dt).c_str());
699       iResult=pTask->ProcessTask(-1, eventType, 0, 0);
700     } else {
701     }
702     lnk = lnk->Next();
703   }
704
705   // control events are not supposed to go into the HLTOUT
706   if (fpHLTOUTTask)
707     fpHLTOUTTask->Reset();
708
709   HLTDebug("event %s done (%d)", AliHLTComponent::DataType2Text(dt).c_str(), iResult);
710   return iResult;
711 }
712
713 int AliHLTSystem::DeinitTasks()
714 {
715   // see header file for class documentation
716   int iResult=0;
717   TObjLink *lnk=fTaskList.LastLink();
718   while (lnk) {
719     TObject* obj=lnk->GetObject();
720     if (obj) {
721       AliHLTTask* pTask=(AliHLTTask*)obj;
722       int localRes=pTask->Deinit();
723       if (iResult>=0) iResult=localRes;
724 //       ProcInfo_t ProcInfo;
725 //       gSystem->GetProcInfo(&ProcInfo);
726 //       HLTInfo("task %s cleaned (%d), current memory usage %d %d", pTask->GetName(), iResult, ProcInfo.fMemResident, ProcInfo.fMemVirtual);
727     } else {
728     }
729     lnk = lnk->Prev();
730   }
731   fEventCount=-1;
732   fGoodEvents=-1;
733
734   return iResult;
735 }
736
737 int AliHLTSystem::CleanHLTOUT()
738 {
739   // see header file for class documentation
740   if (fpChainHandlers) {
741     AliHLTOUT::AliHLTOUTHandlerListEntryVector* pHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpChainHandlers);
742     fpChainHandlers=NULL;
743     if (pHandlers) {
744       AliHLTOUT::InvalidateBlocks(*pHandlers);
745       AliHLTOUT::RemoveEmptyDuplicateHandlers(*pHandlers);
746     }
747     assert(pHandlers->size()==0);
748     delete pHandlers;
749   }
750
751   if (fpEsdHandlers) {
752     AliHLTOUT::AliHLTOUTHandlerListEntryVector* pHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpEsdHandlers);
753     fpEsdHandlers=NULL;
754     if (pHandlers) {
755       AliHLTOUT::InvalidateBlocks(*pHandlers);
756       AliHLTOUT::RemoveEmptyDuplicateHandlers(*pHandlers);
757     }
758     assert(pHandlers->size()==0);
759     delete pHandlers;
760   }
761
762   if (fpProprietaryHandlers) {
763     AliHLTOUT::AliHLTOUTHandlerListEntryVector* pHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpProprietaryHandlers);
764     fpProprietaryHandlers=NULL;
765     if (pHandlers) {
766       AliHLTOUT::InvalidateBlocks(*pHandlers);
767       AliHLTOUT::RemoveEmptyDuplicateHandlers(*pHandlers);
768     }
769     assert(pHandlers->size()==0);
770     delete pHandlers;
771   }
772   return 0;
773 }
774
775 void* AliHLTSystem::AllocMemory( void* /*param*/, unsigned long size )
776 {
777   // see header file for class documentation
778   void* p=NULL;
779   try {
780     p=(void*)new char[size];
781   }
782   catch (...) {
783     AliHLTLogging log;
784     log.LoggingVarargs(kHLTLogError, "AliHLTSystem" , "AllocMemory" , __FILE__ , __LINE__ , "exeption during memory allocation" );
785   }
786   return p;
787 }
788
789 int AliHLTSystem::AllocEventDoneData( void* /*param*/, AliHLTEventID_t /*eventID*/, unsigned long size, AliHLTComponentEventDoneData** edd )
790 {
791   // see header file for class documentation
792   unsigned long blocksize=sizeof(AliHLTComponentEventDoneData)+size;
793   void* block=AllocMemory(NULL, blocksize);
794   if (!block) return -ENOMEM;
795   memset(block, 0, blocksize);
796   *edd=reinterpret_cast<AliHLTComponentEventDoneData*>(block);
797   (*edd)->fStructSize=sizeof(AliHLTComponentEventDoneData);
798   (*edd)->fDataSize=size;
799   (*edd)->fData=reinterpret_cast<AliHLTUInt8_t*>(block)+sizeof(AliHLTComponentEventDoneData);
800   
801   return 0;
802 }
803
804 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
805                               AliRawReader* rawReader)
806 {
807   // see header file for class documentation
808   int iResult=0;
809   if (runLoader || rawReader || nofEvents==0) {
810     if (nofEvents>0) {HLTInfo("Run Loader %p, Raw Reader %p , %d event(s)", runLoader, rawReader, nofEvents);}
811     if (CheckStatus(kReady)) {
812       if (nofEvents==0) {
813         // special case to close the reconstruction
814         if (!CheckStatus(kError)) {
815         StopTasks();
816         DeinitTasks();
817         CleanHLTOUT();
818         }
819       } else {
820       if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
821         AliHLTUInt64_t trgMask=0x1;
822         AliHLTUInt32_t timestamp=0;
823         AliHLTUInt32_t eventtype=0;
824         if (runLoader==NULL) {
825           // this is a quick workaround for the case of simulation
826           // the trigger framework is still under development, secondly, AliHLTSimulation
827           // does not yet add the emulated ECS parameters, so no CTP trigger is known in the HLT
828           // AliHLTTask will initialize one dummy CTP trigger class with bit 0, that's why the
829           // default trigger mask is 0x1
830           trgMask=AliHLTMisc::Instance().GetTriggerMask(rawReader);
831
832           // get the timestamp and type of the event from the raw reader
833           // this is currently only meaningfull for reconstruction (runloader==NULL)
834           timestamp=AliHLTMisc::Instance().GetTimeStamp(rawReader);
835           eventtype=AliHLTMisc::Instance().GetEventType(rawReader);
836         }
837         // the system always remains started after event processing, a specific
838         // call with nofEvents==0 is needed to execute the stop sequence
839         if ((iResult=Run(nofEvents, 0, trgMask, timestamp, eventtype))<0) SetStatusFlags(kError);
840       }
841       }
842     } else {
843       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
844     }
845   } else {
846     HLTError("missing RunLoader (%p)/RawReader (%p) instance", runLoader, rawReader);
847     iResult=-EINVAL;
848   }
849   return iResult;
850 }
851
852 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* esd)
853 {
854   // see header file for class documentation
855   int iResult=0;
856   if (runLoader || esd) {
857     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
858     iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
859   } else {
860     HLTError("missing run loader/ESD instance(s)");
861     iResult=-EINVAL;
862   }
863   return iResult;
864 }
865
866 int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
867 {
868   // see header file for class documentation
869   int iResult=0;
870   if (!pHLTOUT) return -EINVAL;
871   HLTDebug("processing %d HLT data blocks", pHLTOUT->GetNofDataBlocks());
872
873   // add the current HLTOUT task to the collection
874   if (fpHLTOUTTask) {
875     AliHLTOUT* pTask=dynamic_cast<AliHLTOUT*>(fpHLTOUTTask);
876     if (pTask && (iResult=pTask->Init())>=0) {
877       if (pTask->GetNofDataBlocks()>0) {
878         pHLTOUT->AddSubCollection(pTask);
879       }
880     } else {
881       HLTWarning("can not initialize HLTOUT sub collection %s for reconstruction chain (%d), data blocks are lost", pTask?fpHLTOUTTask->GetName():"nil", iResult);
882       iResult=0;
883     }
884   }
885
886   
887   //
888   // process all kChain handlers first
889   //
890   if ((iResult=ProcessHLTOUTkChain(pHLTOUT))<0) {
891     HLTWarning("Processing of kChain-type data blocks failed with error code %d", iResult);
892     iResult=0;
893   } 
894
895   if (!fpEsdHandlers)
896     fpEsdHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
897   if (!fpProprietaryHandlers)
898     fpProprietaryHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
899
900   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pEsdHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpEsdHandlers);
901   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pProprietaryHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpProprietaryHandlers);
902   if (!pEsdHandlers || !pProprietaryHandlers) return -ENOMEM;
903
904   // invalidate all blocks
905   AliHLTOUT::InvalidateBlocks(*pEsdHandlers);
906   AliHLTOUT::InvalidateBlocks(*pProprietaryHandlers);
907
908   AliHLTComponentDataTypeList esdBlocks;
909
910   for (iResult=pHLTOUT->SelectFirstDataBlock();
911        iResult>=0;
912        iResult=pHLTOUT->SelectNextDataBlock()) {
913     AliHLTComponentDataType dt=kAliHLTVoidDataType;
914     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
915     pHLTOUT->GetDataBlockDescription(dt, spec);
916     AliHLTOUTHandler* pHandler=pHLTOUT->GetHandler();
917     AliHLTModuleAgent::AliHLTOUTHandlerType handlerType=pHLTOUT->GetDataBlockHandlerType();
918
919     // default handling for ESD data blocks does not require an explicite handler
920     if (!pHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
921       handlerType=AliHLTModuleAgent::kEsd;
922     }
923     const char* pMsg="invalid";
924     switch (handlerType) {
925     case AliHLTModuleAgent::kEsd:
926       {
927         if (pHandler) {
928           // schedule for later processing
929           pHLTOUT->InsertHandler(*pEsdHandlers, pHLTOUT->GetDataBlockHandlerDesc());
930         } else {
931           AliHLTComponentDataTypeList::iterator element=esdBlocks.begin();
932           for (; element!=esdBlocks.end(); element++) {
933             if (*element==dt) {
934               HLTWarning("multiple ESDs of identical data type %s, please add appropriate handler to merge ESDs", AliHLTComponent::DataType2Text(dt).c_str());
935               break;
936             }
937           }
938           if (element==esdBlocks.end()) esdBlocks.push_back(dt);
939
940           // write directly
941           const AliHLTUInt8_t* pBuffer=NULL;
942           AliHLTUInt32_t size=0;
943           if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
944             pHLTOUT->WriteESD(pBuffer, size, dt, esd);
945             pHLTOUT->ReleaseDataBuffer(pBuffer);
946           }
947           pHLTOUT->MarkDataBlockProcessed();
948         }
949       }
950       break;
951     case AliHLTModuleAgent::kRawReader:
952       // handled in the AliRawReaderHLT
953       break;
954     case AliHLTModuleAgent::kRawStream:
955       HLTWarning("HLTOUT handler type 'kRawStream' not yet implemented: agent %s, data type %s, specification %#x",
956                  pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
957                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
958       break;
959     case AliHLTModuleAgent::kChain:
960       HLTWarning("HLTOUT handler type 'kChain' has already been processed: agent %s, data type %s, specification %#x\n"
961                  "New block of this type added by the chain? Skipping data block ...",
962                  pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
963                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
964       break;
965     case AliHLTModuleAgent::kProprietary:
966       HLTDebug("processing proprietary data: agent %s, data type %s, specification %#x",
967                  pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
968                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
969       if (pHandler) {
970         AliHLTOUT::AliHLTOUTLockGuard g(pHLTOUT);
971         int res=pHandler->ProcessData(pHLTOUT);
972         if (res<0) {
973           HLTWarning("processing proprietary data failed (%d): agent %s, data type %s, specification %#x",
974                      res, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
975                      AliHLTComponent::DataType2Text(dt).c_str(), spec);
976         }
977       }
978       break;
979     case AliHLTModuleAgent::kUnknownOutput:
980       pMsg="unknown";
981       // fall trough intended
982     default:
983       HLTWarning("%s handler type: agent %s, data type %s, specification %#x, ... skipping data block",
984                  pMsg, pHLTOUT->GetAgent()?pHLTOUT->GetAgent()->GetModuleId():"<invalid>",
985                  AliHLTComponent::DataType2Text(dt).c_str(), spec);
986     }
987   }
988   // TODO: the return value of SelectFirst/NextDataBlock must be
989   // changed in order to avoid this check
990   if (iResult==-ENOENT) iResult=0;
991
992   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator handler;
993
994   // process and write all esd data blocks
995   for (handler=pEsdHandlers->begin(); handler!=pEsdHandlers->end() && iResult>=0; handler++) {
996     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*handler));     
997     AliHLTOUTHandler* pHandler=*handler;
998     const AliHLTUInt8_t* pBuffer=NULL;
999     AliHLTUInt32_t size=0;
1000     pHandler->ProcessData(pHLTOUT);
1001     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
1002       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*handler;
1003       AliHLTComponentDataType dt=desc;
1004       pHLTOUT->WriteESD(pBuffer, size, dt, esd);
1005       pHandler->ReleaseProcessedData(pBuffer, size);
1006     }
1007     pHLTOUT->MarkDataBlocksProcessed(&(*handler));
1008   }
1009
1010   // process all kProprietary data blocks
1011   for (handler=pProprietaryHandlers->begin(); handler!=pProprietaryHandlers->end() && iResult>=0; handler++) {
1012     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*handler));     
1013     AliHLTOUTHandler* pHandler=*handler;
1014     const AliHLTUInt8_t* pBuffer=NULL;
1015     AliHLTUInt32_t size=0;
1016     pHandler->ProcessData(pHLTOUT);
1017     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
1018       HLTWarning("data produced by kProprietary handler ignored");
1019       pHandler->ReleaseProcessedData(pBuffer, size);
1020     }
1021     pHLTOUT->MarkDataBlocksProcessed(&(*handler));
1022   }
1023
1024   // remove all empty handlers form the list (handlers which did not get a block this time)
1025   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pEsdHandlers);
1026   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pProprietaryHandlers);
1027
1028   return iResult;
1029 }
1030
1031 int AliHLTSystem::ProcessHLTOUTkChain(AliHLTOUT* pHLTOUT)
1032 {
1033   // see header file for class documentation
1034   int iResult=0;
1035   if (!pHLTOUT) return -EINVAL;
1036
1037   if (!fpChainHandlers)
1038     fpChainHandlers=new AliHLTOUT::AliHLTOUTHandlerListEntryVector;
1039
1040   AliHLTOUT::AliHLTOUTHandlerListEntryVector* pChainHandlers=reinterpret_cast<AliHLTOUT::AliHLTOUTHandlerListEntryVector*>(fpChainHandlers);
1041   if (!pChainHandlers) return -ENOMEM;
1042
1043   // invalidate all blocks
1044   AliHLTOUT::InvalidateBlocks(*pChainHandlers);
1045
1046   // fill the list
1047   pHLTOUT->FillHandlerList(*pChainHandlers, AliHLTModuleAgent::kChain);
1048
1049   // process all defined chain handlers
1050   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator chainHandler;
1051   for (chainHandler=pChainHandlers->begin(); chainHandler!=pChainHandlers->end() && iResult>=0; chainHandler++) {
1052     if (chainHandler->IsEmpty()) continue;
1053     AliHLTOUT::AliHLTOUTSelectionGuard g(pHLTOUT, &(*chainHandler));        
1054     AliHLTOUTHandler* pHandler=*chainHandler;
1055     const AliHLTUInt8_t* pBuffer=NULL;
1056     AliHLTUInt32_t size=0;
1057     pHandler->ProcessData(pHLTOUT);
1058     if ((size=pHandler->GetProcessedData(pBuffer))>0) {
1059       AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*chainHandler;
1060       //AliHLTComponentDataType dt=desc;
1061
1062       pHandler->ReleaseProcessedData(pBuffer, size);
1063     }
1064     pHLTOUT->MarkDataBlocksProcessed(&(*chainHandler));
1065   }
1066
1067   // remove all empty handlers form the list (handlers which did not get a block this time)
1068   AliHLTOUT::RemoveEmptyDuplicateHandlers(*pChainHandlers);
1069
1070   return iResult;
1071 }
1072
1073 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
1074 {
1075   // see header file for class documentation
1076   int iResult=0;
1077   if (libraries) {
1078     if (fpComponentHandler) {
1079       TString libs(libraries);
1080       TObjArray* pTokens=libs.Tokenize(" ");
1081       if (pTokens) {
1082         int iEntries=pTokens->GetEntriesFast();
1083         for (int i=0; i<iEntries && iResult>=0; i++) {
1084           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
1085         }
1086         delete pTokens;
1087       }
1088       if (iResult>=0) {
1089         SetStatusFlags(kLibrariesLoaded);
1090       } else {
1091         // lets see if we need this, probably not
1092         //fpComponentHandler->UnloadLibraries();
1093         ClearStatusFlags(kLibrariesLoaded);
1094       }
1095     } else {
1096       iResult=-EFAULT;
1097       HLTFatal("no component handler available");
1098     }
1099   } else {
1100     iResult=-EINVAL;
1101   }
1102   return iResult;
1103 }
1104
1105 int AliHLTSystem::Configure(AliRunLoader* runloader)
1106 {
1107   // see header file for class documentation
1108   return Configure(NULL, runloader);
1109 }
1110
1111 int AliHLTSystem::Configure(AliRawReader* rawReader, AliRunLoader* runloader)
1112 {
1113   // see header file for class documentation
1114   int iResult=0;
1115   if (CheckStatus(kRunning)) {
1116     HLTError("HLT system in running state, can not configure");
1117     return -EBUSY;
1118   }
1119   ClearStatusFlags(kTaskListCreated);
1120   if (CheckFilter(kHLTLogDebug))
1121     AliHLTModuleAgent::PrintStatus();
1122   if (CheckStatus(kConfigurationLoaded)==0) {
1123     iResult=LoadConfigurations(rawReader, runloader);
1124   } else {
1125     if (fChains.Length()==0) {
1126       HLTError("custom configuration(s) specified, but no configuration to run in local reconstruction, use \'chains=<chain,...>\' option");
1127       iResult=-ENOENT;
1128     }
1129   }
1130   if (iResult>=0) {
1131     SetStatusFlags(kConfigurationLoaded);
1132     if (CheckFilter(kHLTLogDebug))
1133       fpConfigurationHandler->PrintConfigurations();
1134     iResult=BuildTaskListsFromReconstructionChains(rawReader, runloader);
1135     if (iResult>=0) {
1136       SetStatusFlags(kTaskListCreated);
1137     }
1138   }
1139   if (iResult<0) SetStatusFlags(kError);
1140   
1141   return iResult;
1142 }
1143
1144 int AliHLTSystem::ScanOptions(const char* options)
1145 {
1146   // see header file for class documentation
1147   int iResult=0;
1148   if (options) {
1149     //AliHLTComponentHandler::TLibraryMode libMode=AliHLTComponentHandler::kDynamic;
1150     TString libs("");
1151     TString excludelibs("");
1152     TString alloptions(options);
1153     TObjArray* pTokens=alloptions.Tokenize(" ");
1154     if (pTokens) {
1155       int iEntries=pTokens->GetEntriesFast();
1156       for (int i=0; i<iEntries; i++) {
1157         TString token=(((TObjString*)pTokens->At(i))->GetString());
1158         if (token.Contains("loglevel=")) {
1159           TString param=token.ReplaceAll("loglevel=", "");
1160           if (param.IsDigit()) {
1161             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
1162           } else if (param.BeginsWith("0x") &&
1163                      param.Replace(0,2,"",0).IsHex()) {
1164             int severity=0;
1165             sscanf(param.Data(),"%x", &severity);
1166             SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
1167           } else {
1168             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
1169           }
1170         } else if (token.Contains("frameworklog=")) {
1171           TString param=token.ReplaceAll("frameworklog=", "");
1172           if (param.IsDigit()) {
1173             SetFrameworkLog((AliHLTComponentLogSeverity)param.Atoi());
1174           } else if (param.BeginsWith("0x") &&
1175                      param.Replace(0,2,"",0).IsHex()) {
1176             int severity=0;
1177             sscanf(param.Data(),"%x", &severity);
1178             SetFrameworkLog((AliHLTComponentLogSeverity)severity);
1179           } else {
1180             HLTWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
1181           }
1182         } else if (token.Contains("alilog=off")) {
1183           SwitchAliLog(0);
1184         } else if (token.Contains("config=")) {
1185           TString param=token.ReplaceAll("config=", "");
1186           Int_t error=0;
1187           gROOT->Macro(param.Data(), &error);
1188           if (error==0) {
1189             SetStatusFlags(kConfigurationLoaded);
1190           } else {
1191             HLTError("can not execute macro \'%s\'", param.Data());
1192             iResult=-EBADF;
1193           }
1194         } else if (token.Contains("chains=")) {
1195           TString param=token.ReplaceAll("chains=", "");
1196           fChains=param.ReplaceAll(",", " ");
1197           if (fChains.IsNull()) fChains=" "; // disable all chains
1198         } else if (token.Contains("libmode=")) {
1199           TString param=token.ReplaceAll("libmode=", "");
1200           param.ReplaceAll(",", " ");
1201           if (fpComponentHandler) {
1202             if (param.CompareTo("static")==0) {
1203               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
1204             } else if (param.CompareTo("dynamic")==0) {
1205               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
1206             } else {
1207               HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
1208             }
1209           }
1210         } else if (token.BeginsWith("ECS=")) {
1211           fECSParams=token.ReplaceAll("ECS=", "");
1212         } else if (token.BeginsWith("hltout-mode=")) {
1213           // The actual parameter for argument 'hltout-mode' is treated in AliSimulation.
1214           // For AliHLTSystem the occurrence with parameter 'split' signals the use of the
1215           // separated HLTOUTComponents for digit and raw data. All others indicate
1216           // HLTOUTComponent type 'global' where the data generation is steered from global
1217           // flags
1218           fUseHLTOUTComponentTypeGlobal=token.CompareTo("hltout-mode=split")==1;
1219         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
1220           libs+=token;
1221           libs+=" ";
1222         } else if (token.BeginsWith("!lib") && token.EndsWith(".so")) {
1223           excludelibs+=token;
1224           excludelibs+=" ";
1225         } else {
1226           HLTWarning("unknown option \'%s\'", token.Data());
1227         }
1228       }
1229       delete pTokens;
1230     }
1231
1232     if (iResult>=0) {
1233       if (libs.IsNull()) {
1234         const char** deflib=fgkHLTDefaultLibs;
1235         for (;*deflib; deflib++) {
1236           if (excludelibs.Contains(*deflib)) continue;
1237           libs+=*deflib;
1238           libs+=" ";
1239         }
1240       }
1241       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
1242           (LoadComponentLibraries(libs.Data())<0)) {
1243         HLTError("error while loading HLT libraries");
1244         iResult=-EFAULT;
1245       }
1246     }
1247   }
1248   return iResult;
1249 }
1250
1251 int AliHLTSystem::Reset(int bForce)
1252 {
1253   // see header file for class documentation
1254   int iResult=0;
1255   if (!bForce && CheckStatus(kRunning)) {
1256     HLTError("HLT system in running state, can not configure");
1257     return -EBUSY;
1258   }
1259   CleanTaskList();
1260   ClearStatusFlags(~kUninitialized);
1261   return iResult;
1262 }
1263
1264 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
1265 {
1266   // see header file for class documentation
1267   if (CheckStatus(kRunning)) {
1268     HLTError("HLT system in running state, can not configure");
1269     return -EBUSY;
1270   }
1271   int iResult=0;
1272   AliHLTModuleAgent* pAgent=NULL;
1273
1274   // first check for the required libraries and load those
1275   TString extralibs;
1276   for (pAgent=AliHLTModuleAgent::GetFirstAgent(); 
1277        pAgent && iResult>=0;
1278        pAgent=AliHLTModuleAgent::GetNextAgent()) {
1279     const char* deplibs=pAgent->GetRequiredComponentLibraries();
1280     if (deplibs) {
1281       HLTDebug("required libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
1282       extralibs+=" ";
1283       extralibs+=deplibs;
1284     }
1285   }
1286   if (iResult>=0) {
1287     iResult=LoadComponentLibraries(extralibs.Data());
1288   }
1289
1290   // in order to register the configurations in the correct sequence
1291   // all agents need to be ordered with respect to the required
1292   // libraries. Ordering relies on the naming convention
1293   // libAliHLT<Module>.so
1294   TList agents;
1295   for (pAgent=AliHLTModuleAgent::GetFirstAgent(); 
1296        pAgent && iResult>=0;
1297        pAgent=AliHLTModuleAgent::GetNextAgent()) {
1298     AliHLTModuleAgent* pPrevDep=NULL;
1299     TString dependencies=pAgent->GetRequiredComponentLibraries();
1300     TObjArray* pTokens=dependencies.Tokenize(" ");
1301     if (pTokens) {
1302       for (int n=0; n<pTokens->GetEntriesFast(); n++) {
1303         TString module=((TObjString*)pTokens->At(n))->GetString();
1304         HLTDebug("  checking %s", module.Data());
1305         module.ReplaceAll("libAliHLT", "");
1306         module.ReplaceAll(".so", "");
1307         
1308         for (AliHLTModuleAgent* pCurrent=dynamic_cast<AliHLTModuleAgent*>(pPrevDep==NULL?agents.First():agents.After(pPrevDep));
1309              pCurrent!=NULL; pCurrent=dynamic_cast<AliHLTModuleAgent*>(agents.After(pCurrent))) {
1310           HLTDebug("    checking %s == %s", module.Data(), pCurrent->GetModuleId());
1311
1312           if (module.CompareTo(pCurrent->GetModuleId())==0) {
1313             pPrevDep=pCurrent;
1314             break;
1315           }
1316         }
1317       }
1318       delete pTokens;
1319     }
1320
1321     if (pPrevDep) {
1322       // insert right after the last dependency
1323       agents.AddAfter(pPrevDep, pAgent);
1324       HLTDebug("insert %s after %s", pAgent->GetModuleId(), pPrevDep->GetModuleId());
1325     } else {
1326       // insert at the beginning
1327       agents.AddFirst(pAgent);
1328       HLTDebug("insert %s at beginning", pAgent->GetModuleId());
1329     }
1330   }
1331
1332   // now we load the configurations
1333   if (agents.GetEntries()) {
1334     TIter next(&agents);
1335     while ((pAgent = dynamic_cast<AliHLTModuleAgent*>(next()))) {
1336       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
1337       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
1338     }
1339   }
1340
1341   return iResult;
1342 }
1343
1344 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
1345 {
1346   // see header file for class documentation
1347   if (CheckStatus(kRunning)) {
1348     HLTError("HLT system in running state, can not configure");
1349     return -EBUSY;
1350   }
1351   if (!CheckStatus(kConfigurationLoaded)) {
1352     HLTWarning("configurations not yet loaded");
1353     return 0;
1354   }
1355
1356   int iResult=0;
1357   int bHaveOutput=0;
1358
1359   // query chains
1360   TString chains;
1361   if (fChains.Length()>0) {
1362     chains=fChains;
1363     HLTImportant("custom reconstruction chain: %s", chains.Data());
1364   } else {
1365     AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1366     while ((pAgent || fChains.Length()>0) && iResult>=0) {
1367       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
1368       if (agentchains) {
1369         if (!chains.IsNull()) chains+=" ";
1370         chains+=agentchains;
1371         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
1372       }
1373       pAgent=AliHLTModuleAgent::GetNextAgent();
1374     }
1375   }
1376
1377   // build task list for chains
1378   TObjArray* pTokens=chains.Tokenize(" ");
1379   if (pTokens) {
1380     int iEntries=pTokens->GetEntriesFast();
1381     for (int i=0; i<iEntries && iResult>=0; i++) {
1382       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
1383       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
1384       if (pConf) {
1385         iResult=BuildTaskList(pConf);
1386         if (true) { // condition was deprecated but kept for sake of svn diff
1387           // bHaveOutput variable has to be set for both running modes
1388           // AliHLTSimulation and AliHLTReconstruction
1389           assert(fpComponentHandler!=NULL);
1390           TString cid=pConf->GetComponentID();
1391           if (runloader!=NULL && cid.CompareTo("HLTOUT")==0) {
1392             // remove from the input of a global HLTOUT configuration
1393             chains.ReplaceAll(pCID, "");
1394           } else if (bHaveOutput==0) {
1395             // check whether this configuration produces data output
1396             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
1397               bHaveOutput=0;
1398               chains.ReplaceAll(pCID, "");
1399             }
1400           }
1401         }
1402       } else {
1403         HLTWarning("can not find configuration %s", pCID);
1404       }
1405     }
1406     delete pTokens;
1407   }
1408
1409   // build HLTOUT for simulation
1410   if (iResult>=0 && runloader) {
1411     if (bHaveOutput) {
1412       // there are components in the chain which produce data which need to be
1413       // piped to an HLTOUT
1414
1415       // add the SchemaEvolutionComponent which analyzes the ROOT objects in
1416       // the output stream
1417       if (fpComponentHandler->FindComponentIndex("ROOTSchemaEvolutionComponent")>=0 ||
1418           fpComponentHandler->LoadLibrary("libAliHLTUtil.so")>=0) {
1419         AliHLTConfiguration schemaevo("_schemaevolution_", "ROOTSchemaEvolutionComponent", 
1420                                       chains.Data(), "-file=HLT.StreamerInfo.root");
1421         iResult=BuildTaskList("_schemaevolution_");
1422       } else {
1423         HLTWarning("can not load libAliHLTUtil.so and ROOTSchemaEvolutionComponent");
1424       }
1425
1426       // add the HLTOUT component
1427       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
1428           fpComponentHandler->LoadLibrary("libHLTsim.so")>=0) {
1429         // for the default HLTOUTComponent type 'global' the data generation is steered
1430         // by global flags from AliSimulation. This allows for emulation of the old
1431         // AliHLTSimulation behavior where only one chain is run on either digits or
1432         // simulated raw data and the HLT digits and raw files have been generated
1433         // depending on the configuration
1434         const char* HLTOUTComponentId="HLTOUT";
1435         if (!fUseHLTOUTComponentTypeGlobal) {
1436           // choose the type of output depending  on the availability of
1437           // the raw reader
1438           if (rawReader) HLTOUTComponentId="HLTOUTraw";
1439           else HLTOUTComponentId="HLTOUTdigits";
1440         }
1441         AliHLTConfiguration globalout("_globalout_", HLTOUTComponentId, chains.Data(), NULL);
1442         iResult=BuildTaskList("_globalout_");
1443       } else {
1444         HLTError("can not load libHLTsim.so and HLTOUT component");
1445         iResult=-EFAULT;
1446       }
1447     }
1448   }
1449
1450   // build HLTOUT task for reconstruction
1451   // Matthias 08.07.2008 the rawReader is never set when running embedded into
1452   // AliReconstruction. The system is configured during AliHLTReconstructor::Init
1453   // where the RawReader is not available. It is available in the first invocation
1454   // of Reconstruct.
1455   // 
1456   // That means that policy is slightly changed:
1457   // - if the run loader is available -> AliSimulation
1458   // - no run loader available -> AliReconstruction
1459   if (iResult>=0 && !runloader) {
1460     if (bHaveOutput) {
1461       // there are components in the chain which produce data which need to be
1462       // piped to an HLTOUT sub-collection
1463       if (!fpHLTOUTTask) {
1464         iResult=AddHLTOUTTask(chains.Data());
1465       }
1466     }
1467   }
1468
1469   if (iResult>=0) SetStatusFlags(kTaskListCreated);
1470
1471   return iResult;
1472 }
1473
1474 int AliHLTSystem::AddHLTOUTTask(const char* hltoutchains)
1475 {
1476   // see header file for class documentation
1477   int iResult=0;
1478   if (!hltoutchains || hltoutchains[0]==0) return 0;
1479
1480   // check chains for output
1481   TString chains=hltoutchains;
1482   TObjArray* pTokens=chains.Tokenize(" ");
1483   if (pTokens) {
1484     int iEntries=pTokens->GetEntriesFast();
1485     for (int i=0; i<iEntries && iResult>=0; i++) {
1486       const char* token=((TObjString*)pTokens->At(i))->GetString().Data();
1487       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(token);
1488       if (pConf) {
1489         TString cid=pConf->GetComponentID();
1490         if (fpComponentHandler->HasOutputData(cid.Data())) {
1491           continue;
1492         }
1493       } else {
1494         HLTWarning("can not find configuration %s", token);
1495       }
1496       // remove from the list of hltout chains
1497       chains.ReplaceAll(token, "");
1498     }
1499     delete pTokens;
1500   }
1501
1502   // do not create the HLTOUT task if none of the chains have output
1503   if (chains.IsNull()) return 0;
1504
1505   // indicate the task to be available
1506   iResult=1;
1507
1508   if (fpHLTOUTTask) {
1509     if (strcmp(chains.Data(), fpHLTOUTTask->GetSourceChains())==0) {
1510       HLTWarning("HLTOUT task already added for chains \"%s\" %p", chains.Data(), fpHLTOUTTask);
1511     } else {
1512       HLTError("HLTOUT task already added for chains \"%s\" %p, ignoring new chains  \"%s\"",
1513                fpHLTOUTTask->GetSourceChains(), fpHLTOUTTask, chains.Data());
1514     }
1515     return iResult;
1516   }
1517
1518   fpHLTOUTTask=new AliHLTOUTTask(chains);
1519   if (fpHLTOUTTask) {
1520     if (fpHLTOUTTask->GetConf() && fpHLTOUTTask->GetConf()->SourcesResolved()>=0) {
1521       iResult=InsertTask(fpHLTOUTTask);
1522     } else {
1523       HLTError("HLTOUT task (%s) sources not resolved", fpHLTOUTTask->GetName());
1524       iResult=-ENOENT;
1525     }
1526
1527     if (iResult<0) {
1528       delete fpHLTOUTTask;
1529     }
1530
1531   } else {
1532     iResult=-ENOMEM;
1533   }
1534   return iResult;
1535 }
1536
1537 int AliHLTSystem::CheckStatus(int flag)
1538 {
1539   // see header file for class documentation
1540   if (flag==kUninitialized && flag==fState) return 1;
1541   if ((fState&flag)==flag) return 1;
1542   return 0;
1543 }
1544
1545 int AliHLTSystem::GetStatusFlags()
1546 {
1547   // see header file for class documentation
1548   return fState;
1549 }
1550
1551 int AliHLTSystem::SetStatusFlags(int flags)
1552 {
1553   // see header file for class documentation
1554   fState|=flags;
1555   return fState;
1556 }
1557
1558 int AliHLTSystem::ClearStatusFlags(int flags)
1559 {
1560   // see header file for class documentation
1561   fState&=~flags;
1562   return fState;
1563 }
1564
1565 AliHLTfctVoid AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
1566 {
1567   // see header file for class documentation
1568   if (fpComponentHandler==NULL) return NULL;
1569   return fpComponentHandler->FindSymbol(library, symbol);
1570 }
1571
1572 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
1573 {
1574   // see header file for class documentation
1575   SetLocalLoggingLevel(level);
1576   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
1577   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
1578 }
1579
1580 int AliHLTSystem::LoggingVarargs(AliHLTComponentLogSeverity severity, 
1581                                  const char* originClass, const char* originFunc,
1582                                  const char* file, int line, ... ) const
1583 {
1584   // see header file for function documentation
1585   int iResult=0;
1586
1587   va_list args;
1588   va_start(args, line);
1589
1590   if (!fName.IsNull())
1591     AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", fName.Data());
1592   iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, !fName.IsNull() /*append if non empty*/));
1593   va_end(args);
1594
1595   return iResult;
1596 }