]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTSystem.cxx
component librarary unloading and handling of multiple loads fixed; documentation...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          for The ALICE Off-line 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 "AliHLTStdIncludes.h"
29 #include "AliHLTSystem.h"
30 #include "AliHLTComponentHandler.h"
31 #include "AliHLTComponent.h"
32 #include "AliHLTConfiguration.h"
33 #include "AliHLTConfigurationHandler.h"
34 #include "AliHLTTask.h"
35 #include "AliHLTModuleAgent.h"
36 #include <TObjArray.h>
37 #include <TObjString.h>
38 #include <TString.h>
39
40 /** ROOT macro for the implementation of ROOT specific class methods */
41 ClassImp(AliHLTSystem)
42
43 AliHLTSystem::AliHLTSystem()
44   :
45   fpComponentHandler(new AliHLTComponentHandler()),
46   fpConfigurationHandler(new AliHLTConfigurationHandler()),
47   fTaskList(),
48   fState(0)
49 {
50   // see header file for class documentation
51   // or
52   // refer to README to build package
53   // or
54   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
55
56   if (fgNofInstances++>0)
57     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
58
59   SetGlobalLoggingLevel(kHLTLogDefault);
60   if (fpComponentHandler) {
61     AliHLTComponentEnvironment env;
62     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
63     env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
64     env.fLoggingFunc=NULL;
65     fpComponentHandler->SetEnvironment(&env);
66   } else {
67     HLTFatal("can not create Component Handler");
68   }
69   if (fpConfigurationHandler) {
70     AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
71   } else {
72     HLTFatal("can not create Configuration Handler");
73   }
74 }
75
76 AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
77   :
78   AliHLTLogging(),
79   fpComponentHandler(NULL),
80   fpConfigurationHandler(NULL),
81   fTaskList(),
82   fState(0)
83 {
84   // see header file for class documentation
85   if (fgNofInstances++>0)
86     HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
87
88   HLTFatal("copy constructor untested");
89 }
90
91 AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
92
93   // see header file for class documentation
94   HLTFatal("assignment operator untested");
95   return *this;
96 }
97
98 AliHLTSystem::~AliHLTSystem()
99 {
100   // see header file for class documentation
101   fgNofInstances--;
102   CleanTaskList();
103   AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
104   if (fpConfigurationHandler) {
105     delete fpConfigurationHandler;
106   }
107   fpConfigurationHandler=NULL;
108   
109   if (fpComponentHandler) {
110     delete fpComponentHandler;
111   }
112   fpComponentHandler=NULL;
113 }
114
115 int AliHLTSystem::fgNofInstances=0;
116
117 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
118 {
119   // see header file for class documentation
120   int iResult=0;
121   if (pConf) {
122   } else {
123     iResult=-EINVAL;
124   }
125   return iResult;
126 }
127
128 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
129 {
130   // see header file for class documentation
131   int iResult=0;
132   if (pConf) {
133     if (pPrec) {
134       // find the position
135     }
136   } else {
137     iResult=-EINVAL;
138   }
139   return iResult;
140 }
141
142 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
143 {
144   // see header file for class documentation
145   int iResult=0;
146   if (pConf) {
147   } else {
148     iResult=-EINVAL;
149   }
150   return iResult;
151 }
152
153 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
154 {
155   // see header file for class documentation
156   int iResult=0;
157   if (pConf) {
158     AliHLTTask* pTask=NULL;
159     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
160       if (pTask->GetConf()!=pConf) {
161         HLTError("configuration missmatch, there is already a task with configuration name \"%s\", but it is different. Most likely configuration %p is not registered properly", pConf->GetName(), pConf);
162         iResult=-EEXIST;
163         pTask=NULL;
164       }
165     } else if (pConf->SourcesResolved(1)!=1) {
166         HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
167         iResult=-ENOLINK;
168     } else {
169       pTask=new AliHLTTask(pConf);
170       if (pTask==NULL) {
171         iResult=-ENOMEM;
172       }
173     }
174     if (pTask) {
175       // check for circular dependencies
176       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
177         HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
178         pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
179         HLTError("aborted ...");
180         iResult=-ELOOP;
181       }
182       if (iResult>=0) {
183         // check whether all dependencies are already in the task list
184         // create the missing ones
185         // this step is an iterative process which calls this function again for the missing
186         // configurations, in order to avoid the currently processed task to be created
187         // again it is added to the list temporarily and removed afterwards
188         // This is of high importance to preserve the order of the tasks. Furthermore, the
189         // InsertTask method has to be used in order to set all the cross links right 
190         fTaskList.Add(pTask);
191         AliHLTConfiguration* pDep=pConf->GetFirstSource();
192         while (pDep!=NULL && iResult>=0) {
193           if (FindTask(pDep->GetName())==NULL) {
194             iResult=BuildTaskList(pDep);
195           }
196           pDep=pConf->GetNextSource();
197         }
198         // remove the temporarily added task
199         fTaskList.Remove(pTask);
200
201         // insert the task and set the cross-links
202         if (iResult>=0) {
203           iResult=InsertTask(pTask);
204         }
205       } else {
206         delete pTask;
207         pTask=NULL;
208       }
209     }
210   } else {
211     iResult=-EINVAL;
212   }
213   return iResult;
214 }
215
216 int AliHLTSystem::CleanTaskList()
217 {
218   // see header file for class documentation
219   int iResult=0;
220   TObjLink* lnk=NULL;
221   while ((lnk=fTaskList.FirstLink())!=NULL) {
222     fTaskList.Remove(lnk);
223     delete (lnk->GetObject());
224   }
225   return iResult;
226 }
227
228 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
229 {
230   // see header file for class documentation
231   int iResult=0;
232   TObjLink *lnk = NULL;
233   if ((iResult=pTask->CheckDependencies())>0)
234     lnk=fTaskList.FirstLink();
235   while (lnk && iResult>0) {
236     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
237     //HLTDebug("checking  \"%s\"", pCurr->GetName());
238     iResult=pTask->Depends(pCurr);
239     if (iResult>0) {
240       iResult=pTask->SetDependency(pCurr);
241       pCurr->SetTarget(pTask);
242       HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
243     }
244     if (pCurr->Depends(pTask)) {
245       // circular dependency
246       HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
247       iResult=-ELOOP;
248     } else if ((iResult=pTask->CheckDependencies())>0) {
249       lnk = lnk->Next();
250     }
251   }
252   if (iResult==0) {
253       if (lnk) {
254         fTaskList.AddAfter(lnk, pTask);
255       } else {
256         fTaskList.AddFirst(pTask);
257       }
258       HLTDebug("task \"%s\" inserted", pTask->GetName());
259   } else if (iResult>0) {
260     HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
261     iResult=-ENOLINK;
262   }
263   return iResult;
264 }
265
266 AliHLTTask* AliHLTSystem::FindTask(const char* id)
267 {
268   // see header file for class documentation
269   AliHLTTask* pTask=NULL;
270   if (id) {
271     pTask=(AliHLTTask*)fTaskList.FindObject(id); 
272   }
273   return pTask;
274 }
275
276 void AliHLTSystem::PrintTaskList()
277 {
278   // see header file for class documentation
279   HLTLogKeyword("task list");
280   TObjLink *lnk = NULL;
281   HLTMessage("Task List");
282   lnk=fTaskList.FirstLink();
283   while (lnk) {
284     TObject* obj=lnk->GetObject();
285     if (obj) {
286       HLTMessage("  %s - status:", obj->GetName());
287       AliHLTTask* pTask=(AliHLTTask*)obj;
288       pTask->PrintStatus();
289     } else {
290     }
291     lnk = lnk->Next();
292   }
293 }
294
295 int AliHLTSystem::Run(Int_t iNofEvents) 
296 {
297   // see header file for class documentation
298   int iResult=0;
299   int iCount=0;
300   SetStatusFlags(kRunning);
301   if ((iResult=InitTasks())>=0) {
302     if ((iResult=StartTasks())>=0) {
303       for (int i=0; i<iNofEvents && iResult>=0; i++) {
304         iResult=ProcessTasks(i);
305         if (iResult>=0) {
306           HLTInfo("Event %d successfully finished (%d)", i, iResult);
307           iResult=0;
308           iCount++;
309         } else {
310           HLTError("Processing of event %d failed (%d)", i, iResult);
311           // TODO: define different running modes to either ignore errors in
312           // event processing or not
313           // currently ignored 
314           //iResult=0;
315         }
316       }
317       StopTasks();
318     } else {
319       HLTError("can not start task list");
320     }
321     DeinitTasks();
322   } else if (iResult!=-ENOENT) {
323     HLTError("can not initialize task list");
324   }
325   if (iResult>=0) iResult=iCount;
326   ClearStatusFlags(kRunning);
327   return iResult;
328 }
329
330 int AliHLTSystem::InitTasks()
331 {
332   // see header file for class documentation
333   int iResult=0;
334   TObjLink *lnk=fTaskList.FirstLink();
335   if (lnk==NULL) {
336     HLTWarning("Task list is empty, aborting ...");
337     return -ENOENT;
338   }
339   while (lnk && iResult>=0) {
340     TObject* obj=lnk->GetObject();
341     if (obj) {
342       AliHLTTask* pTask=(AliHLTTask*)obj;
343       iResult=pTask->Init(NULL, fpComponentHandler);
344     } else {
345     }
346     lnk = lnk->Next();
347   }
348   if (iResult<0) {
349   }
350   return iResult;
351 }
352
353 int AliHLTSystem::StartTasks()
354 {
355   // see header file for class documentation
356   int iResult=0;
357   TObjLink *lnk=fTaskList.FirstLink();
358   while (lnk && iResult>=0) {
359     TObject* obj=lnk->GetObject();
360     if (obj) {
361       AliHLTTask* pTask=(AliHLTTask*)obj;
362       iResult=pTask->StartRun();
363     } else {
364     }
365     lnk = lnk->Next();
366   }
367   if (iResult<0) {
368   }
369   return iResult;
370 }
371
372 int AliHLTSystem::ProcessTasks(Int_t eventNo)
373 {
374   // see header file for class documentation
375   int iResult=0;
376   HLTDebug("processing event no %d", eventNo);
377   TObjLink *lnk=fTaskList.FirstLink();
378   while (lnk && iResult>=0) {
379     TObject* obj=lnk->GetObject();
380     if (obj) {
381       AliHLTTask* pTask=(AliHLTTask*)obj;
382       iResult=pTask->ProcessTask(eventNo);
383       HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
384     } else {
385     }
386     lnk = lnk->Next();
387   }
388   return iResult;
389 }
390
391 int AliHLTSystem::StopTasks()
392 {
393   // see header file for class documentation
394   int iResult=0;
395   TObjLink *lnk=fTaskList.FirstLink();
396   while (lnk && iResult>=0) {
397     TObject* obj=lnk->GetObject();
398     if (obj) {
399       AliHLTTask* pTask=(AliHLTTask*)obj;
400       iResult=pTask->EndRun();
401     } else {
402     }
403     lnk = lnk->Next();
404   }
405   return iResult;
406 }
407
408 int AliHLTSystem::DeinitTasks()
409 {
410   // see header file for class documentation
411   int iResult=0;
412   TObjLink *lnk=fTaskList.FirstLink();
413   while (lnk && iResult>=0) {
414     TObject* obj=lnk->GetObject();
415     if (obj) {
416       AliHLTTask* pTask=(AliHLTTask*)obj;
417       iResult=pTask->Deinit();
418     } else {
419     }
420     lnk = lnk->Next();
421   }
422   return iResult;
423 }
424
425 void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
426 {
427   // see header file for class documentation
428   if (param==NULL) {
429     // get rid of 'unused parameter' warning
430   }
431   return (void*)new char[size];
432 }
433
434 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
435                               AliRawReader* rawReader)
436 {
437   // see header file for class documentation
438   int iResult=0;
439   if (runLoader) {
440     HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
441     if (CheckStatus(kReady)) {
442       iResult=Run(nofEvents);
443     } else {
444       HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
445     }
446   } else {
447     HLTError("missing run loader instance");
448     iResult=-EINVAL;
449   }
450   return iResult;
451 }
452
453 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
454 {
455   // see header file for class documentation
456   int iResult=0;
457   if (runLoader) {
458     HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
459   } else {
460     HLTError("missing run loader/ESD instance(s)");
461     iResult=-EINVAL;
462   }
463   return iResult;
464 }
465
466 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
467 {
468   // see header file for class documentation
469   int iResult=0;
470   if (libraries) {
471     if (fpComponentHandler) {
472       TString libs(libraries);
473       TObjArray* pTokens=libs.Tokenize(" ");
474       if (pTokens) {
475         int iEntries=pTokens->GetEntries();
476         for (int i=0; i<iEntries && iResult>=0; i++) {
477           iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
478         }
479         delete pTokens;
480       }
481       if (iResult>=0) {
482         SetStatusFlags(kLibrariesLoaded);
483       } else {
484         // lets see if we need this, probably not
485         //fpComponentHandler->UnloadLibraries();
486         ClearStatusFlags(kLibrariesLoaded);
487       }
488     } else {
489       iResult=-EFAULT;
490       HLTFatal("no component handler available");
491     }
492   } else {
493     iResult=-EINVAL;
494   }
495   return iResult;
496 }
497
498 int AliHLTSystem::Configure(AliRunLoader* runloader)
499 {
500   // see header file for class documentation
501   int iResult=0;
502   if (CheckStatus(kRunning)) {
503     HLTError("HLT system in running state, can not configure");
504     return -EBUSY;
505   }
506   if (CheckFilter(kHLTLogDebug))
507     AliHLTModuleAgent::PrintStatus();
508   ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
509   iResult=LoadConfigurations(runloader);
510   if (iResult>=0) {
511     SetStatusFlags(kConfigurationLoaded);
512     iResult=BuildTaskListsFromTopConfigurations(runloader);
513     if (iResult>=0) {
514       SetStatusFlags(kTaskListCreated);
515     }
516   }
517   if (iResult<0) SetStatusFlags(kError);
518   
519   return iResult;
520 }
521
522 int AliHLTSystem::Reset(int bForce)
523 {
524   // see header file for class documentation
525   int iResult=0;
526   if (!bForce && CheckStatus(kRunning)) {
527     HLTError("HLT system in running state, can not configure");
528     return -EBUSY;
529   }
530   CleanTaskList();
531   ClearStatusFlags(~kUninitialized);
532   return iResult;
533 }
534
535 int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
536 {
537   // see header file for class documentation
538   if (CheckStatus(kRunning)) {
539     HLTError("HLT system in running state, can not configure");
540     return -EBUSY;
541   }
542   int iResult=0;
543   AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
544   while (pAgent && iResult>=0) {
545     const char* deplibs=pAgent->GetRequiredComponentLibraries();
546     if (deplibs) {
547       HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
548       iResult=LoadComponentLibraries(deplibs);
549     }
550     if (iResult>=0) {
551       HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
552       pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
553       pAgent=AliHLTModuleAgent::GetNextAgent();
554     }
555   }
556   return iResult;
557 }
558
559 int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
560 {
561   // see header file for class documentation
562   if (CheckStatus(kRunning)) {
563     HLTError("HLT system in running state, can not configure");
564     return -EBUSY;
565   }
566   if (!CheckStatus(kConfigurationLoaded)) {
567     HLTWarning("configurations not yet loaded");
568     return 0;
569   }
570
571   int iResult=0;
572   AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
573   while (pAgent && iResult>=0) {
574     TString tops=pAgent->GetTopConfigurations(runloader);
575     HLTDebug("top configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
576     TObjArray* pTokens=tops.Tokenize(" ");
577     if (pTokens) {
578       int iEntries=pTokens->GetEntries();
579       for (int i=0; i<iEntries && iResult>=0; i++) {
580         const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
581         AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
582         if (pConf) {
583           iResult=BuildTaskList(pConf);
584         } else {
585           HLTWarning("can not find top configuration %s", pCID);
586         }
587       }
588       delete pTokens;
589     }
590     
591     pAgent=AliHLTModuleAgent::GetNextAgent();
592   }
593   if (iResult>=0) SetStatusFlags(kTaskListCreated);
594
595   return iResult;
596 }
597
598 int AliHLTSystem::CheckStatus(int flag)
599 {
600   // see header file for class documentation
601   if (flag==kUninitialized && flag==fState) return 1;
602   if ((fState&flag)==flag) return 1;
603   return 0;
604 }
605
606 int AliHLTSystem::GetStatusFlags()
607 {
608   // see header file for class documentation
609   return fState;
610 }
611
612 int AliHLTSystem::SetStatusFlags(int flags)
613 {
614   // see header file for class documentation
615   fState|=flags;
616   return fState;
617 }
618
619 int AliHLTSystem::ClearStatusFlags(int flags)
620 {
621   // see header file for class documentation
622   fState&=~flags;
623   return fState;
624 }