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 "AliHLTOfflineInterface.h"
37 #include <TObjArray.h>
38 #include <TObjString.h>
41 /** ROOT macro for the implementation of ROOT specific class methods */
42 ClassImp(AliHLTSystem)
44 AliHLTSystem::AliHLTSystem()
46 fpComponentHandler(new AliHLTComponentHandler()),
47 fpConfigurationHandler(new AliHLTConfigurationHandler()),
51 // see header file for class documentation
53 // refer to README to build package
55 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
57 if (fgNofInstances++>0)
58 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
60 SetGlobalLoggingLevel(kHLTLogDefault);
61 if (fpComponentHandler) {
62 AliHLTComponentEnvironment env;
63 memset(&env, 0, sizeof(AliHLTComponentEnvironment));
64 env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
65 env.fLoggingFunc=NULL;
66 fpComponentHandler->SetEnvironment(&env);
68 HLTFatal("can not create Component Handler");
70 if (fpConfigurationHandler) {
71 AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
73 HLTFatal("can not create Configuration Handler");
77 AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
80 fpComponentHandler(NULL),
81 fpConfigurationHandler(NULL),
85 // see header file for class documentation
86 if (fgNofInstances++>0)
87 HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
89 HLTFatal("copy constructor untested");
92 AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
94 // see header file for class documentation
95 HLTFatal("assignment operator untested");
99 AliHLTSystem::~AliHLTSystem()
101 // see header file for class documentation
104 AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
105 if (fpConfigurationHandler) {
106 delete fpConfigurationHandler;
108 fpConfigurationHandler=NULL;
110 if (fpComponentHandler) {
111 delete fpComponentHandler;
113 fpComponentHandler=NULL;
116 int AliHLTSystem::fgNofInstances=0;
118 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
120 // see header file for class documentation
129 int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
131 // see header file for class documentation
143 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
145 // see header file for class documentation
154 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
156 // see header file for class documentation
159 AliHLTTask* pTask=NULL;
160 if ((pTask=FindTask(pConf->GetName()))!=NULL) {
161 if (pTask->GetConf()!=pConf) {
162 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);
166 } else if (pConf->SourcesResolved(1)!=1) {
167 HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
170 pTask=new AliHLTTask(pConf);
176 // check for circular dependencies
177 if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
178 HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
179 pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
180 HLTError("aborted ...");
184 // check whether all dependencies are already in the task list
185 // create the missing ones
186 // this step is an iterative process which calls this function again for the missing
187 // configurations, in order to avoid the currently processed task to be created
188 // again it is added to the list temporarily and removed afterwards
189 // This is of high importance to preserve the order of the tasks. Furthermore, the
190 // InsertTask method has to be used in order to set all the cross links right
191 fTaskList.Add(pTask);
192 AliHLTConfiguration* pDep=pConf->GetFirstSource();
193 while (pDep!=NULL && iResult>=0) {
194 if (FindTask(pDep->GetName())==NULL) {
195 iResult=BuildTaskList(pDep);
197 pDep=pConf->GetNextSource();
199 // remove the temporarily added task
200 fTaskList.Remove(pTask);
202 // insert the task and set the cross-links
204 iResult=InsertTask(pTask);
217 int AliHLTSystem::CleanTaskList()
219 // see header file for class documentation
222 while ((lnk=fTaskList.FirstLink())!=NULL) {
223 fTaskList.Remove(lnk);
224 delete (lnk->GetObject());
229 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
231 // see header file for class documentation
233 TObjLink *lnk = NULL;
234 if ((iResult=pTask->CheckDependencies())>0)
235 lnk=fTaskList.FirstLink();
236 while (lnk && iResult>0) {
237 AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
238 //HLTDebug("checking \"%s\"", pCurr->GetName());
239 iResult=pTask->Depends(pCurr);
241 iResult=pTask->SetDependency(pCurr);
242 pCurr->SetTarget(pTask);
243 HLTDebug("set dependency \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
245 if (pCurr->Depends(pTask)) {
246 // circular dependency
247 HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
249 } else if ((iResult=pTask->CheckDependencies())>0) {
255 fTaskList.AddAfter(lnk, pTask);
257 fTaskList.AddFirst(pTask);
259 HLTDebug("task \"%s\" inserted", pTask->GetName());
260 } else if (iResult>0) {
261 HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
267 AliHLTTask* AliHLTSystem::FindTask(const char* id)
269 // see header file for class documentation
270 AliHLTTask* pTask=NULL;
272 pTask=(AliHLTTask*)fTaskList.FindObject(id);
277 void AliHLTSystem::PrintTaskList()
279 // see header file for class documentation
280 HLTLogKeyword("task list");
281 TObjLink *lnk = NULL;
282 HLTMessage("Task List");
283 lnk=fTaskList.FirstLink();
285 TObject* obj=lnk->GetObject();
287 HLTMessage(" %s - status:", obj->GetName());
288 AliHLTTask* pTask=(AliHLTTask*)obj;
289 pTask->PrintStatus();
296 int AliHLTSystem::Run(Int_t iNofEvents)
298 // see header file for class documentation
301 SetStatusFlags(kRunning);
302 if ((iResult=InitTasks())>=0) {
303 if ((iResult=StartTasks())>=0) {
304 for (int i=0; i<iNofEvents && iResult>=0; i++) {
305 iResult=ProcessTasks(i);
307 HLTInfo("Event %d successfully finished (%d)", i, iResult);
311 HLTError("Processing of event %d failed (%d)", i, iResult);
312 // TODO: define different running modes to either ignore errors in
313 // event processing or not
320 HLTError("can not start task list");
323 } else if (iResult!=-ENOENT) {
324 HLTError("can not initialize task list");
326 if (iResult>=0) iResult=iCount;
327 ClearStatusFlags(kRunning);
331 int AliHLTSystem::InitTasks()
333 // see header file for class documentation
335 TObjLink *lnk=fTaskList.FirstLink();
337 HLTWarning("Task list is empty, aborting ...");
340 while (lnk && iResult>=0) {
341 TObject* obj=lnk->GetObject();
343 AliHLTTask* pTask=(AliHLTTask*)obj;
344 iResult=pTask->Init(NULL, fpComponentHandler);
354 int AliHLTSystem::StartTasks()
356 // see header file for class documentation
358 TObjLink *lnk=fTaskList.FirstLink();
359 while (lnk && iResult>=0) {
360 TObject* obj=lnk->GetObject();
362 AliHLTTask* pTask=(AliHLTTask*)obj;
363 iResult=pTask->StartRun();
373 int AliHLTSystem::ProcessTasks(Int_t eventNo)
375 // see header file for class documentation
377 HLTDebug("processing event no %d", eventNo);
378 TObjLink *lnk=fTaskList.FirstLink();
379 while (lnk && iResult>=0) {
380 TObject* obj=lnk->GetObject();
382 AliHLTTask* pTask=(AliHLTTask*)obj;
383 iResult=pTask->ProcessTask(eventNo);
384 HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
392 int AliHLTSystem::StopTasks()
394 // see header file for class documentation
396 TObjLink *lnk=fTaskList.FirstLink();
397 while (lnk && iResult>=0) {
398 TObject* obj=lnk->GetObject();
400 AliHLTTask* pTask=(AliHLTTask*)obj;
401 iResult=pTask->EndRun();
409 int AliHLTSystem::DeinitTasks()
411 // see header file for class documentation
413 TObjLink *lnk=fTaskList.FirstLink();
414 while (lnk && iResult>=0) {
415 TObject* obj=lnk->GetObject();
417 AliHLTTask* pTask=(AliHLTTask*)obj;
418 iResult=pTask->Deinit();
426 void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
428 // see header file for class documentation
430 // get rid of 'unused parameter' warning
432 return (void*)new char[size];
435 int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader,
436 AliRawReader* rawReader)
438 // see header file for class documentation
441 HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
442 if (CheckStatus(kReady)) {
443 if ((iResult=AliHLTOfflineInterface::SetParamsToComponents(runLoader, rawReader))>=0) {
444 iResult=Run(nofEvents);
447 HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
450 HLTError("missing run loader instance");
456 int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
458 // see header file for class documentation
461 HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
462 iResult=AliHLTOfflineInterface::FillComponentESDs(eventNo, runLoader, esd);
464 HLTError("missing run loader/ESD instance(s)");
470 int AliHLTSystem::LoadComponentLibraries(const char* libraries)
472 // see header file for class documentation
475 if (fpComponentHandler) {
476 TString libs(libraries);
477 TObjArray* pTokens=libs.Tokenize(" ");
479 int iEntries=pTokens->GetEntries();
480 for (int i=0; i<iEntries && iResult>=0; i++) {
481 iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
486 SetStatusFlags(kLibrariesLoaded);
488 // lets see if we need this, probably not
489 //fpComponentHandler->UnloadLibraries();
490 ClearStatusFlags(kLibrariesLoaded);
494 HLTFatal("no component handler available");
502 int AliHLTSystem::Configure(AliRunLoader* runloader)
504 // see header file for class documentation
506 if (CheckStatus(kRunning)) {
507 HLTError("HLT system in running state, can not configure");
510 if (CheckFilter(kHLTLogDebug))
511 AliHLTModuleAgent::PrintStatus();
512 ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
513 iResult=LoadConfigurations(runloader);
515 SetStatusFlags(kConfigurationLoaded);
516 iResult=BuildTaskListsFromTopConfigurations(runloader);
518 SetStatusFlags(kTaskListCreated);
521 if (iResult<0) SetStatusFlags(kError);
526 int AliHLTSystem::Reset(int bForce)
528 // see header file for class documentation
530 if (!bForce && CheckStatus(kRunning)) {
531 HLTError("HLT system in running state, can not configure");
535 ClearStatusFlags(~kUninitialized);
539 int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
541 // see header file for class documentation
542 if (CheckStatus(kRunning)) {
543 HLTError("HLT system in running state, can not configure");
547 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
548 while (pAgent && iResult>=0) {
549 const char* deplibs=pAgent->GetRequiredComponentLibraries();
551 HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
552 iResult=LoadComponentLibraries(deplibs);
555 HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
556 pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
557 pAgent=AliHLTModuleAgent::GetNextAgent();
563 int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
565 // see header file for class documentation
566 if (CheckStatus(kRunning)) {
567 HLTError("HLT system in running state, can not configure");
570 if (!CheckStatus(kConfigurationLoaded)) {
571 HLTWarning("configurations not yet loaded");
576 AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
577 while (pAgent && iResult>=0) {
578 TString tops=pAgent->GetTopConfigurations(runloader);
579 HLTDebug("top configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
580 TObjArray* pTokens=tops.Tokenize(" ");
582 int iEntries=pTokens->GetEntries();
583 for (int i=0; i<iEntries && iResult>=0; i++) {
584 const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
585 AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
587 iResult=BuildTaskList(pConf);
589 HLTWarning("can not find top configuration %s", pCID);
595 pAgent=AliHLTModuleAgent::GetNextAgent();
597 if (iResult>=0) SetStatusFlags(kTaskListCreated);
602 int AliHLTSystem::CheckStatus(int flag)
604 // see header file for class documentation
605 if (flag==kUninitialized && flag==fState) return 1;
606 if ((fState&flag)==flag) return 1;
610 int AliHLTSystem::GetStatusFlags()
612 // see header file for class documentation
616 int AliHLTSystem::SetStatusFlags(int flags)
618 // see header file for class documentation
623 int AliHLTSystem::ClearStatusFlags(int flags)
625 // see header file for class documentation