]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
usin global instance of configuration handler for automatic configuration, adding...
[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 "AliHLTOnlineConfiguration.h"
36 #include "AliHLTTask.h"
37 #include "AliHLTModuleAgent.h"
38 #include "AliHLTOfflineInterface.h"
39 #include "AliHLTDataSource.h"
40 #include "AliHLTOUT.h"
41 #include "AliHLTOUTHandler.h"
42 #include "AliHLTOUTTask.h"
43 #include "AliHLTControlTask.h"
44 #include "AliHLTDataBuffer.h"
45 #include "AliHLTMisc.h"
46 #include <TObjArray.h>
47 #include <TObjString.h>
48 #include <TStopwatch.h>
49 #include <TList.h>
50 //#include <TSystem.h>
51 #include <TROOT.h>
52 //#include <TInterpreter.h>
53
54 /** HLT default component libraries */
55 const char* AliHLTSystem::fgkHLTDefaultLibs[]= {
56   "libAliHLTUtil.so", 
57   "libAliHLTRCU.so", 
58   "libAliHLTTPC.so", 
59   //  "libAliHLTSample.so",
60   "libAliHLTCalo.so",
61   "libAliHLTEMCAL.so",
62   "libAliHLTPHOS.so",
63   "libAliHLTMUON.so",
64   "libAliHLTTRD.so",
65   "libAliHLTITS.so",
66   "libAliHLTVZERO.so",
67   "libAliHLTZDC.so",
68   "libAliHLTGlobal.so",
69   "libAliHLTTrigger.so",
70   NULL
71 };
72
73 /** ROOT macro for the implementation of ROOT specific class methods */
74 ClassImp(AliHLTSystem)
75
76 AliHLTSystem::AliHLTSystem(AliHLTComponentLogSeverity loglevel, const char* name,
77                            AliHLTComponentHandler* pCompHandler,
78                            AliHLTConfigurationHandler* pConfHandler
79                            )
80   : fpComponentHandler(pCompHandler==NULL?AliHLTComponentHandler::CreateHandler():pCompHandler)
81   , fpConfigurationHandler(pConfHandler==NULL?AliHLTConfigurationHandler::CreateHandler():pConfHandler),
82   fTaskList(),
83   fState(0),
84   fChains(),
85   fStopwatches(new TObjArray),
86   fEventCount(-1),
87   fGoodEvents(-1),
88   fpChainHandlers(NULL),
89   fpEsdHandlers(NULL),
90   fpProprietaryHandlers(NULL),
91   fpHLTOUTTask(NULL),
92   fpControlTask(NULL),
93   fName(name)
94   , fECSParams()
95   , fUseHLTOUTComponentTypeGlobal(true)
96 {
97   // see header file for class documentation
98   // or
99   // refer to README to build package
100   // or
101   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
102
103   if (fgNofInstances++>0) {
104     // July 2008: multiple instances are now allowed
105     // AliHLTSystem is used in multiple instances for the kChain HLTOUT handler
106     //HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
107   }
108
109   SetGlobalLoggingLevel(loglevel);
110   SetFrameworkLog(loglevel);
111   if (fpComponentHandler) {
112     AliHLTAnalysisEnvironment env;
113     memset(&env, 0, sizeof(AliHLTAnalysisEnvironment));
114     env.fStructSize=sizeof(AliHLTAnalysisEnvironment);
115     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
116     env.fGetEventDoneDataFunc=AliHLTSystem::AllocEventDoneData;
117     env.fLoggingFunc=NULL;
118     fpComponentHandler->SetEnvironment(&env);
119     InitAliLogFunc(fpComponentHandler);
120     if (fgNofInstances==1) {
121     fpComponentHandler->AnnounceVersion();
122     }
123   } else {
124     HLTFatal("can not create Component Handler");
125   }
126   if (fpConfigurationHandler==NULL) {
127     HLTFatal("can not create Configuration Handler");
128   }
129 }
130
131 AliHLTSystem::~AliHLTSystem()
132 {
133   // see header file for class documentation
134   fgNofInstances--;
135   CleanHLTOUT();
136   CleanTaskList();
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           if (token.EndsWith(".xml", TString::kIgnoreCase)) {
1188             Int_t filesize = 0;
1189             AliHLTOnlineConfiguration conf;
1190             filesize = conf.LoadConfiguration(param.Data());
1191             if (filesize <= 0) {
1192               HLTError("can not load config \'%s\'", param.Data());
1193               iResult=-EBADF;
1194             } else {
1195               error = conf.Parse();
1196               if (error==0) {
1197                 fChains = conf.GetDefaultChains();
1198                 libs = conf.GetComponentLibraries();
1199                 libs += " ";
1200                 SetStatusFlags(kConfigurationLoaded);
1201               } else {
1202                 HLTError("can not parse config \'%s\'", param.Data());
1203                 iResult=-EBADF;
1204               }
1205             }
1206           } else {
1207             gROOT->Macro(param.Data(), &error);
1208             if (error==0) {
1209               SetStatusFlags(kConfigurationLoaded);
1210             } else {
1211               HLTError("can not execute macro \'%s\'", param.Data());
1212               iResult=-EBADF;
1213             }
1214           }     
1215         } else if (token.Contains("chains=")) {
1216           TString param=token.ReplaceAll("chains=", "");
1217           fChains=param.ReplaceAll(",", " ");
1218           if (fChains.IsNull()) fChains=" "; // disable all chains
1219         } else if (token.Contains("libmode=")) {
1220           TString param=token.ReplaceAll("libmode=", "");
1221           param.ReplaceAll(",", " ");
1222           if (fpComponentHandler) {
1223             if (param.CompareTo("static")==0) {
1224               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kStatic);
1225             } else if (param.CompareTo("dynamic")==0) {
1226               fpComponentHandler->SetLibraryMode(AliHLTComponentHandler::kDynamic);
1227             } else {
1228               HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
1229             }
1230           }
1231         } else if (token.BeginsWith("ECS=")) {
1232           fECSParams=token.ReplaceAll("ECS=", "");
1233         } else if (token.BeginsWith("hltout-mode=")) {
1234           // The actual parameter for argument 'hltout-mode' is treated in AliSimulation.
1235           // For AliHLTSystem the occurrence with parameter 'split' signals the use of the
1236           // separated HLTOUTComponents for digit and raw data. All others indicate
1237           // HLTOUTComponent type 'global' where the data generation is steered from global
1238           // flags
1239           fUseHLTOUTComponentTypeGlobal=token.CompareTo("hltout-mode=split")==1;
1240         } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
1241           libs+=token;
1242           libs+=" ";
1243         } else if (token.BeginsWith("!lib") && token.EndsWith(".so")) {
1244           excludelibs+=token;
1245           excludelibs+=" ";
1246         } else {
1247           HLTWarning("unknown option \'%s\'", token.Data());
1248         }
1249       }
1250       delete pTokens;
1251     }
1252
1253     if (iResult>=0) {
1254       if (libs.IsNull()) {
1255         const char** deflib=fgkHLTDefaultLibs;
1256         for (;*deflib; deflib++) {
1257           if (excludelibs.Contains(*deflib)) continue;
1258           libs+=*deflib;
1259           libs+=" ";
1260         }
1261       }
1262       if ((!CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
1263           (LoadComponentLibraries(libs.Data())<0)) {
1264         HLTError("error while loading HLT libraries");
1265         iResult=-EFAULT;
1266       }
1267     }
1268   }
1269   return iResult;
1270 }
1271
1272 int AliHLTSystem::Reset(int bForce)
1273 {
1274   // see header file for class documentation
1275   int iResult=0;
1276   if (!bForce && CheckStatus(kRunning)) {
1277     HLTError("HLT system in running state, can not configure");
1278     return -EBUSY;
1279   }
1280   CleanTaskList();
1281   ClearStatusFlags(~kUninitialized);
1282   return iResult;
1283 }
1284
1285 int AliHLTSystem::LoadConfigurations(AliRawReader* rawReader, AliRunLoader* runloader)
1286 {
1287   // see header file for class documentation
1288   if (CheckStatus(kRunning)) {
1289     HLTError("HLT system in running state, can not configure");
1290     return -EBUSY;
1291   }
1292   int iResult=0;
1293   AliHLTModuleAgent* pAgent=NULL;
1294
1295   // first check for the required libraries and load those
1296   TString extralibs;
1297   for (pAgent=AliHLTModuleAgent::GetFirstAgent(); 
1298        pAgent && iResult>=0;
1299        pAgent=AliHLTModuleAgent::GetNextAgent()) {
1300     const char* deplibs=pAgent->GetRequiredComponentLibraries();
1301     if (deplibs) {
1302       HLTDebug("required libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
1303       extralibs+=" ";
1304       extralibs+=deplibs;
1305     }
1306   }
1307   if (iResult>=0) {
1308     iResult=LoadComponentLibraries(extralibs.Data());
1309   }
1310
1311   // in order to register the configurations in the correct sequence
1312   // all agents need to be ordered with respect to the required
1313   // libraries. Ordering relies on the naming convention
1314   // libAliHLT<Module>.so
1315   TList agents;
1316   for (pAgent=AliHLTModuleAgent::GetFirstAgent(); 
1317        pAgent && iResult>=0;
1318        pAgent=AliHLTModuleAgent::GetNextAgent()) {
1319     AliHLTModuleAgent* pPrevDep=NULL;
1320     TString dependencies=pAgent->GetRequiredComponentLibraries();
1321     TObjArray* pTokens=dependencies.Tokenize(" ");
1322     if (pTokens) {
1323       for (int n=0; n<pTokens->GetEntriesFast(); n++) {
1324         TString module=((TObjString*)pTokens->At(n))->GetString();
1325         HLTDebug("  checking %s", module.Data());
1326         module.ReplaceAll("libAliHLT", "");
1327         module.ReplaceAll(".so", "");
1328         
1329         for (AliHLTModuleAgent* pCurrent=dynamic_cast<AliHLTModuleAgent*>(pPrevDep==NULL?agents.First():agents.After(pPrevDep));
1330              pCurrent!=NULL; pCurrent=dynamic_cast<AliHLTModuleAgent*>(agents.After(pCurrent))) {
1331           HLTDebug("    checking %s == %s", module.Data(), pCurrent->GetModuleId());
1332
1333           if (module.CompareTo(pCurrent->GetModuleId())==0) {
1334             pPrevDep=pCurrent;
1335             break;
1336           }
1337         }
1338       }
1339       delete pTokens;
1340     }
1341
1342     if (pPrevDep) {
1343       // insert right after the last dependency
1344       agents.AddAfter(pPrevDep, pAgent);
1345       HLTDebug("insert %s after %s", pAgent->GetModuleId(), pPrevDep->GetModuleId());
1346     } else {
1347       // insert at the beginning
1348       agents.AddFirst(pAgent);
1349       HLTDebug("insert %s at beginning", pAgent->GetModuleId());
1350     }
1351   }
1352
1353   // now we load the configurations
1354   if (agents.GetEntries()) {
1355     TIter next(&agents);
1356     while ((pAgent = dynamic_cast<AliHLTModuleAgent*>(next()))) {
1357       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
1358       pAgent->CreateConfigurations(fpConfigurationHandler, rawReader, runloader);
1359     }
1360   }
1361
1362   return iResult;
1363 }
1364
1365 int AliHLTSystem::BuildTaskListsFromReconstructionChains(AliRawReader* rawReader, AliRunLoader* runloader)
1366 {
1367   // see header file for class documentation
1368   if (CheckStatus(kRunning)) {
1369     HLTError("HLT system in running state, can not configure");
1370     return -EBUSY;
1371   }
1372   if (!CheckStatus(kConfigurationLoaded)) {
1373     HLTWarning("configurations not yet loaded");
1374     return 0;
1375   }
1376
1377   int iResult=0;
1378   int bHaveOutput=0;
1379
1380   // query chains
1381   TString chains;
1382   if (fChains.Length()>0) {
1383     chains=fChains;
1384     HLTImportant("custom reconstruction chain: %s", chains.Data());
1385   } else {
1386     for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
1387          pAgent && iResult>=0;
1388          pAgent=AliHLTModuleAgent::GetNextAgent()) {
1389       const char* agentchains=pAgent->GetReconstructionChains(rawReader, runloader);
1390       if (agentchains) {
1391         if (!chains.IsNull()) chains+=" ";
1392         chains+=agentchains;
1393         HLTInfo("reconstruction chains for agent %s (%p): %s", pAgent->GetName(), pAgent, agentchains);
1394       }
1395     }
1396   }
1397
1398   // build task list for chains
1399   TObjArray* pTokens=chains.Tokenize(" ");
1400   if (pTokens) {
1401     int iEntries=pTokens->GetEntriesFast();
1402     for (int i=0; i<iEntries && iResult>=0; i++) {
1403       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
1404       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
1405       if (pConf) {
1406         iResult=BuildTaskList(pConf);
1407         if (true) { // condition was deprecated but kept for sake of svn diff
1408           // bHaveOutput variable has to be set for both running modes
1409           // AliHLTSimulation and AliHLTReconstruction
1410           assert(fpComponentHandler!=NULL);
1411           TString cid=pConf->GetComponentID();
1412           if (runloader!=NULL && cid.CompareTo("HLTOUT")==0) {
1413             // remove from the input of a global HLTOUT configuration
1414             chains.ReplaceAll(pCID, "");
1415           } else if (bHaveOutput==0) {
1416             // check whether this configuration produces data output
1417             if ((bHaveOutput=fpComponentHandler->HasOutputData(cid.Data()))<0) {
1418               bHaveOutput=0;
1419               chains.ReplaceAll(pCID, "");
1420             }
1421           }
1422         }
1423       } else {
1424         HLTWarning("can not find configuration %s", pCID);
1425       }
1426     }
1427     delete pTokens;
1428   }
1429
1430   // build HLTOUT for simulation
1431   if (iResult>=0 && runloader) {
1432     if (bHaveOutput) {
1433       // there are components in the chain which produce data which need to be
1434       // piped to an HLTOUT
1435
1436       // add the SchemaEvolutionComponent which analyzes the ROOT objects in
1437       // the output stream
1438       if (fpComponentHandler->FindComponentIndex("ROOTSchemaEvolutionComponent")>=0 ||
1439           fpComponentHandler->LoadLibrary("libAliHLTUtil.so")>=0) {
1440         AliHLTConfiguration schemaevo("_schemaevolution_", "ROOTSchemaEvolutionComponent", 
1441                                       chains.Data(), "-file=HLT.StreamerInfo.root");
1442         iResult=BuildTaskList("_schemaevolution_");
1443       } else {
1444         HLTWarning("can not load libAliHLTUtil.so and ROOTSchemaEvolutionComponent");
1445       }
1446
1447       // add the HLTOUT component
1448       if (fpComponentHandler->FindComponentIndex("HLTOUT")>=0 ||
1449           fpComponentHandler->LoadLibrary("libHLTsim.so")>=0) {
1450         // for the default HLTOUTComponent type 'global' the data generation is steered
1451         // by global flags from AliSimulation. This allows for emulation of the old
1452         // AliHLTSimulation behavior where only one chain is run on either digits or
1453         // simulated raw data and the HLT digits and raw files have been generated
1454         // depending on the configuration
1455         const char* HLTOUTComponentId="HLTOUT";
1456         if (!fUseHLTOUTComponentTypeGlobal) {
1457           // choose the type of output depending  on the availability of
1458           // the raw reader
1459           if (rawReader) HLTOUTComponentId="HLTOUTraw";
1460           else HLTOUTComponentId="HLTOUTdigits";
1461         }
1462         AliHLTConfiguration globalout("_globalout_", HLTOUTComponentId, chains.Data(), NULL);
1463         iResult=BuildTaskList("_globalout_");
1464       } else {
1465         HLTError("can not load libHLTsim.so and HLTOUT component");
1466         iResult=-EFAULT;
1467       }
1468     }
1469   }
1470
1471   // build HLTOUT task for reconstruction
1472   // Matthias 08.07.2008 the rawReader is never set when running embedded into
1473   // AliReconstruction. The system is configured during AliHLTReconstructor::Init
1474   // where the RawReader is not available. It is available in the first invocation
1475   // of Reconstruct.
1476   // 
1477   // That means that policy is slightly changed:
1478   // - if the run loader is available -> AliSimulation
1479   // - no run loader available -> AliReconstruction
1480   if (iResult>=0 && !runloader) {
1481     if (bHaveOutput) {
1482       // there are components in the chain which produce data which need to be
1483       // piped to an HLTOUT sub-collection
1484       if (!fpHLTOUTTask) {
1485         iResult=AddHLTOUTTask(chains.Data());
1486       }
1487     }
1488   }
1489
1490   if (iResult>=0) SetStatusFlags(kTaskListCreated);
1491
1492   return iResult;
1493 }
1494
1495 int AliHLTSystem::AddHLTOUTTask(const char* hltoutchains)
1496 {
1497   // see header file for class documentation
1498   int iResult=0;
1499   if (!hltoutchains || hltoutchains[0]==0) return 0;
1500
1501   // check chains for output
1502   TString chains=hltoutchains;
1503   TObjArray* pTokens=chains.Tokenize(" ");
1504   if (pTokens) {
1505     int iEntries=pTokens->GetEntriesFast();
1506     for (int i=0; i<iEntries && iResult>=0; i++) {
1507       const char* token=((TObjString*)pTokens->At(i))->GetString().Data();
1508       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(token);
1509       if (pConf) {
1510         TString cid=pConf->GetComponentID();
1511         if (fpComponentHandler->HasOutputData(cid.Data())) {
1512           continue;
1513         }
1514       } else {
1515         HLTWarning("can not find configuration %s", token);
1516       }
1517       // remove from the list of hltout chains
1518       chains.ReplaceAll(token, "");
1519     }
1520     delete pTokens;
1521   }
1522
1523   // do not create the HLTOUT task if none of the chains have output
1524   if (chains.IsNull()) return 0;
1525
1526   // indicate the task to be available
1527   iResult=1;
1528
1529   if (fpHLTOUTTask) {
1530     if (strcmp(chains.Data(), fpHLTOUTTask->GetSourceChains())==0) {
1531       HLTWarning("HLTOUT task already added for chains \"%s\" %p", chains.Data(), fpHLTOUTTask);
1532     } else {
1533       HLTError("HLTOUT task already added for chains \"%s\" %p, ignoring new chains  \"%s\"",
1534                fpHLTOUTTask->GetSourceChains(), fpHLTOUTTask, chains.Data());
1535     }
1536     return iResult;
1537   }
1538
1539   fpHLTOUTTask=new AliHLTOUTTask(chains);
1540   if (fpHLTOUTTask) {
1541     if (fpHLTOUTTask->GetConf() && 
1542         (fpHLTOUTTask->GetConf()->SourcesResolved()>0 ||
1543          fpHLTOUTTask->GetConf()->ExtractSources()>0)) {
1544       iResult=InsertTask(fpHLTOUTTask);
1545     } else {
1546       HLTError("HLTOUT task (%s) sources not resolved", fpHLTOUTTask->GetName());
1547       iResult=-ENOENT;
1548     }
1549
1550     if (iResult<0) {
1551       delete fpHLTOUTTask;
1552     }
1553
1554   } else {
1555     iResult=-ENOMEM;
1556   }
1557   return iResult;
1558 }
1559
1560 int AliHLTSystem::CheckStatus(int flag)
1561 {
1562   // see header file for class documentation
1563   if (flag==kUninitialized && flag==fState) return 1;
1564   if ((fState&flag)==flag) return 1;
1565   return 0;
1566 }
1567
1568 int AliHLTSystem::GetStatusFlags()
1569 {
1570   // see header file for class documentation
1571   return fState;
1572 }
1573
1574 int AliHLTSystem::SetStatusFlags(int flags)
1575 {
1576   // see header file for class documentation
1577   fState|=flags;
1578   return fState;
1579 }
1580
1581 int AliHLTSystem::ClearStatusFlags(int flags)
1582 {
1583   // see header file for class documentation
1584   fState&=~flags;
1585   return fState;
1586 }
1587
1588 AliHLTfctVoid AliHLTSystem::FindDynamicSymbol(const char* library, const char* symbol)
1589 {
1590   // see header file for class documentation
1591   if (fpComponentHandler==NULL) return NULL;
1592   return fpComponentHandler->FindSymbol(library, symbol);
1593 }
1594
1595 void AliHLTSystem::SetFrameworkLog(AliHLTComponentLogSeverity level) 
1596 {
1597   // see header file for class documentation
1598   SetLocalLoggingLevel(level);
1599   if (fpComponentHandler) fpComponentHandler->SetLocalLoggingLevel(level);
1600   if (fpConfigurationHandler) fpConfigurationHandler->SetLocalLoggingLevel(level);
1601 }
1602
1603 int AliHLTSystem::LoggingVarargs(AliHLTComponentLogSeverity severity, 
1604                                  const char* originClass, const char* originFunc,
1605                                  const char* file, int line, ... ) const
1606 {
1607   // see header file for function documentation
1608   int iResult=0;
1609
1610   va_list args;
1611   va_start(args, line);
1612
1613   if (!fName.IsNull())
1614     AliHLTLogging::SetLogString(this, " (%p)", "%s_pfmt_: ", fName.Data());
1615   iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, !fName.IsNull() /*append if non empty*/));
1616   va_end(args);
1617
1618   return iResult;
1619 }