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