3 /**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * for The ALICE Off-line Project. *
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 **************************************************************************/
18 /** @file AliHLTSystem.cxx
19 @author Matthias Richter
21 @brief Implementation of HLT module management.
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>
40 /** ROOT macro for the implementation of ROOT specific class methods */
41 ClassImp(AliHLTSystem)
43 AliHLTSystem::AliHLTSystem()
45 fpComponentHandler(new AliHLTComponentHandler()),
46 fpConfigurationHandler(new AliHLTConfigurationHandler()),
50 // see header file for class documentation
52 // refer to README to build package
54 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
56 if (fgNofInstances++>0)
57 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
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);
67 HLTFatal("can not create Component Handler");
69 if (fpConfigurationHandler) {
70 AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
72 HLTFatal("can not create Configuration Handler");
76 AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
79 fpComponentHandler(NULL),
80 fpConfigurationHandler(NULL),
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");
88 HLTFatal("copy constructor untested");
91 AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
93 // see header file for class documentation
94 HLTFatal("assignment operator untested");
98 AliHLTSystem::~AliHLTSystem()
100 // see header file for class documentation
103 AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
104 if (fpConfigurationHandler) {
105 delete fpConfigurationHandler;
107 fpConfigurationHandler=NULL;
109 if (fpComponentHandler) {
110 delete fpComponentHandler;
112 fpComponentHandler=NULL;
115 int AliHLTSystem::fgNofInstances=0;
117 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
119 // see header file for class documentation
128 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
130 // see header file for class documentation
142 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
144 // see header file for class documentation
153 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
155 // see header file for class documentation
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);
165 } else if (pConf->SourcesResolved(1)!=1) {
166 HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
169 pTask=new AliHLTTask(pConf);
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 ...");
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);
196 pDep=pConf->GetNextSource();
198 // remove the temporarily added task
199 fTaskList.Remove(pTask);
201 // insert the task and set the cross-links
203 iResult=InsertTask(pTask);
216 int AliHLTSystem::CleanTaskList()
218 // see header file for class documentation
221 while ((lnk=fTaskList.FirstLink())!=NULL) {
222 fTaskList.Remove(lnk);
223 delete (lnk->GetObject());
228 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
230 // see header file for class documentation
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);
240 iResult=pTask->SetDependency(pCurr);
241 pCurr->SetTarget(pTask);
242 HLTDebug("set dependency \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
244 if (pCurr->Depends(pTask)) {
245 // circular dependency
246 HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
248 } else if ((iResult=pTask->CheckDependencies())>0) {
254 fTaskList.AddAfter(lnk, pTask);
256 fTaskList.AddFirst(pTask);
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);
266 AliHLTTask* AliHLTSystem::FindTask(const char* id)
268 // see header file for class documentation
269 AliHLTTask* pTask=NULL;
271 pTask=(AliHLTTask*)fTaskList.FindObject(id);
276 void AliHLTSystem::PrintTaskList()
278 // see header file for class documentation
279 HLTLogKeyword("task list");
280 TObjLink *lnk = NULL;
281 HLTMessage("Task List");
282 lnk=fTaskList.FirstLink();
284 TObject* obj=lnk->GetObject();
286 HLTMessage(" %s - status:", obj->GetName());
287 AliHLTTask* pTask=(AliHLTTask*)obj;
288 pTask->PrintStatus();
295 int AliHLTSystem::Run(Int_t iNofEvents)
297 // see header file for class documentation
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);
306 HLTInfo("Event %d successfully finished (%d)", i, iResult);
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
319 HLTError("can not start task list");
322 } else if (iResult!=-ENOENT) {
323 HLTError("can not initialize task list");
325 if (iResult>=0) iResult=iCount;
326 ClearStatusFlags(kRunning);
330 int AliHLTSystem::InitTasks()
332 // see header file for class documentation
334 TObjLink *lnk=fTaskList.FirstLink();
336 HLTWarning("Task list is empty, aborting ...");
339 while (lnk && iResult>=0) {
340 TObject* obj=lnk->GetObject();
342 AliHLTTask* pTask=(AliHLTTask*)obj;
343 iResult=pTask->Init(NULL, fpComponentHandler);
353 int AliHLTSystem::StartTasks()
355 // see header file for class documentation
357 TObjLink *lnk=fTaskList.FirstLink();
358 while (lnk && iResult>=0) {
359 TObject* obj=lnk->GetObject();
361 AliHLTTask* pTask=(AliHLTTask*)obj;
362 iResult=pTask->StartRun();
372 int AliHLTSystem::ProcessTasks(Int_t eventNo)
374 // see header file for class documentation
376 HLTDebug("processing event no %d", eventNo);
377 TObjLink *lnk=fTaskList.FirstLink();
378 while (lnk && iResult>=0) {
379 TObject* obj=lnk->GetObject();
381 AliHLTTask* pTask=(AliHLTTask*)obj;
382 iResult=pTask->ProcessTask(eventNo);
383 HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
391 int AliHLTSystem::StopTasks()
393 // see header file for class documentation
395 TObjLink *lnk=fTaskList.FirstLink();
396 while (lnk && iResult>=0) {
397 TObject* obj=lnk->GetObject();
399 AliHLTTask* pTask=(AliHLTTask*)obj;
400 iResult=pTask->EndRun();
408 int AliHLTSystem::DeinitTasks()
410 // see header file for class documentation
412 TObjLink *lnk=fTaskList.FirstLink();
413 while (lnk && iResult>=0) {
414 TObject* obj=lnk->GetObject();
416 AliHLTTask* pTask=(AliHLTTask*)obj;
417 iResult=pTask->Deinit();
425 void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
427 // see header file for class documentation
429 // get rid of 'unused parameter' warning
431 return (void*)new char[size];
434 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader,
435 AliRawReader* rawReader)
437 // see header file for class documentation
440 HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
441 if (CheckStatus(kReady)) {
442 iResult=Run(nofEvents);
444 HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
447 HLTError("missing run loader instance");
453 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
455 // see header file for class documentation
458 HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
460 HLTError("missing run loader/ESD instance(s)");
466 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
468 // see header file for class documentation
471 if (fpComponentHandler) {
472 TString libs(libraries);
473 TObjArray* pTokens=libs.Tokenize(" ");
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());
482 SetStatusFlags(kLibrariesLoaded);
484 // lets see if we need this, probably not
485 //fpComponentHandler->UnloadLibraries();
486 ClearStatusFlags(kLibrariesLoaded);
490 HLTFatal("no component handler available");
498 int AliHLTSystem::Configure(AliRunLoader* runloader)
500 // see header file for class documentation
502 if (CheckStatus(kRunning)) {
503 HLTError("HLT system in running state, can not configure");
506 if (CheckFilter(kHLTLogDebug))
507 AliHLTModuleAgent::PrintStatus();
508 ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
509 iResult=LoadConfigurations(runloader);
511 SetStatusFlags(kConfigurationLoaded);
512 iResult=BuildTaskListsFromTopConfigurations(runloader);
514 SetStatusFlags(kTaskListCreated);
517 if (iResult<0) SetStatusFlags(kError);
522 int AliHLTSystem::Reset(int bForce)
524 // see header file for class documentation
526 if (!bForce && CheckStatus(kRunning)) {
527 HLTError("HLT system in running state, can not configure");
531 ClearStatusFlags(~kUninitialized);
535 int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
537 // see header file for class documentation
538 if (CheckStatus(kRunning)) {
539 HLTError("HLT system in running state, can not configure");
543 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
544 while (pAgent && iResult>=0) {
545 const char* deplibs=pAgent->GetRequiredComponentLibraries();
547 HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
548 iResult=LoadComponentLibraries(deplibs);
551 HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
552 pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
553 pAgent=AliHLTModuleAgent::GetNextAgent();
559 int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
561 // see header file for class documentation
562 if (CheckStatus(kRunning)) {
563 HLTError("HLT system in running state, can not configure");
566 if (!CheckStatus(kConfigurationLoaded)) {
567 HLTWarning("configurations not yet loaded");
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(" ");
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);
583 iResult=BuildTaskList(pConf);
585 HLTWarning("can not find top configuration %s", pCID);
591 pAgent=AliHLTModuleAgent::GetNextAgent();
593 if (iResult>=0) SetStatusFlags(kTaskListCreated);
598 int AliHLTSystem::CheckStatus(int flag)
600 // see header file for class documentation
601 if (flag==kUninitialized && flag==fState) return 1;
602 if ((fState&flag)==flag) return 1;
606 int AliHLTSystem::GetStatusFlags()
608 // see header file for class documentation
612 int AliHLTSystem::SetStatusFlags(int flags)
614 // see header file for class documentation
619 int AliHLTSystem::ClearStatusFlags(int flags)
621 // see header file for class documentation