]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTSystem.cxx
Modified initialisation
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTSystem.cxx
index 45851efbcea49f266d19644dd179b4da1c9eface..178e00e26fe3a14e93c8b803d1696ab0fa1377a2 100644 (file)
@@ -4,8 +4,6 @@
  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
  *                                                                        *
  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
- *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
- *          Artur Szostak <artursz@iafrica.com>                           *
  *          for The ALICE Off-line Project.                               *
  *                                                                        *
  * Permission to use, copy, modify and distribute this software and its   *
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-///////////////////////////////////////////////////////////////////////////////
-//                                                                           //
-// global HLT module management                                              //
-//                                                                           //
-///////////////////////////////////////////////////////////////////////////////
+/** @file   AliHLTSystem.cxx
+    @author Matthias Richter
+    @date   
+    @brief  Implementation of HLT module management.
+*/
 
-#if __GNUC__== 3
+#if __GNUC__>= 3
 using namespace std;
 #endif
 
-#include <errno.h>
-#include <string.h>
-#include "AliL3StandardIncludes.h"
+#include "AliHLTStdIncludes.h"
 #include "AliHLTSystem.h"
 #include "AliHLTComponentHandler.h"
 #include "AliHLTComponent.h"
 #include "AliHLTConfiguration.h"
+#include "AliHLTConfigurationHandler.h"
+#include "AliHLTTask.h"
+#include "AliHLTModuleAgent.h"
+#include <TObjArray.h>
+#include <TObjString.h>
+#include <TString.h>
 
+/** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTSystem)
 
 AliHLTSystem::AliHLTSystem()
+  :
+  fpComponentHandler(new AliHLTComponentHandler()),
+  fpConfigurationHandler(new AliHLTConfigurationHandler()),
+  fTaskList(),
+  fState(0)
 {
-  fpComponentHandler=new AliHLTComponentHandler();
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+  if (fgNofInstances++>0)
+    HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
+
+  SetGlobalLoggingLevel(kHLTLogDefault);
   if (fpComponentHandler) {
     AliHLTComponentEnvironment env;
     memset(&env, 0, sizeof(AliHLTComponentEnvironment));
-    env.fLoggingFunc=AliHLTLogging::Message;
+    env.fAllocMemoryFunc=AliHLTSystem::AllocMemory;
+    env.fLoggingFunc=NULL;
     fpComponentHandler->SetEnvironment(&env);
-
-    // init logging function in AliHLTLogging
-    Init(AliHLTLogging::Message);
+  } else {
+    HLTFatal("can not create Component Handler");
+  }
+  if (fpConfigurationHandler) {
+    AliHLTConfiguration::GlobalInit(fpConfigurationHandler);
+  } else {
+    HLTFatal("can not create Configuration Handler");
   }
-  DebugMsg("create hlt object %s %p", "AliHLTSystem", this);
-  DebugMsg("done");
 }
 
+AliHLTSystem::AliHLTSystem(const AliHLTSystem&)
+  :
+  AliHLTLogging(),
+  fpComponentHandler(NULL),
+  fpConfigurationHandler(NULL),
+  fTaskList(),
+  fState(0)
+{
+  // see header file for class documentation
+  if (fgNofInstances++>0)
+    HLTWarning("multiple instances of AliHLTSystem, you should not use more than one at a time");
+
+  HLTFatal("copy constructor untested");
+}
+
+AliHLTSystem& AliHLTSystem::operator=(const AliHLTSystem&)
+{ 
+  // see header file for class documentation
+  HLTFatal("assignment operator untested");
+  return *this;
+}
 
 AliHLTSystem::~AliHLTSystem()
 {
+  // see header file for class documentation
+  fgNofInstances--;
+  CleanTaskList();
+  AliHLTConfiguration::GlobalDeinit(fpConfigurationHandler);
+  if (fpConfigurationHandler) {
+    delete fpConfigurationHandler;
+  }
+  fpConfigurationHandler=NULL;
+  
+  if (fpComponentHandler) {
+    delete fpComponentHandler;
+  }
+  fpComponentHandler=NULL;
 }
 
+int AliHLTSystem::fgNofInstances=0;
+
 int AliHLTSystem::AddConfiguration(AliHLTConfiguration* pConf)
 {
+  // see header file for class documentation
   int iResult=0;
+  if (pConf) {
+  } else {
+    iResult=-EINVAL;
+  }
   return iResult;
 }
 
-// int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
-// {
-//   int iResult=0;
-//   return iResult;
-// }
+int AliHLTSystem::InsertConfiguration(AliHLTConfiguration* pConf, AliHLTConfiguration* pPrec)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (pConf) {
+    if (pPrec) {
+      // find the position
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
 
 int AliHLTSystem::DeleteConfiguration(AliHLTConfiguration* pConf)
 {
+  // see header file for class documentation
   int iResult=0;
+  if (pConf) {
+  } else {
+    iResult=-EINVAL;
+  }
   return iResult;
 }
 
 int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
 {
+  // see header file for class documentation
   int iResult=0;
   if (pConf) {
     AliHLTTask* pTask=NULL;
     if ((pTask=FindTask(pConf->GetName()))!=NULL) {
       if (pTask->GetConf()!=pConf) {
-       Logging(kHLTLogError, "BASE", "AliHLTSystem", "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);
+       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);
        iResult=-EEXIST;
        pTask=NULL;
       }
     } else if (pConf->SourcesResolved(1)!=1) {
-       Logging(kHLTLogError, "BASE", "AliHLTSystem", "configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
+       HLTError("configuration \"%s\" has unresolved sources, aborting ...", pConf->GetName());
        iResult=-ENOLINK;
     } else {
-      pTask=new AliHLTTask(pConf, NULL);
+      pTask=new AliHLTTask(pConf);
       if (pTask==NULL) {
        iResult=-ENOMEM;
       }
     }
     if (pTask) {
-      // check for ring dependencies
+      // check for circular dependencies
       if ((iResult=pConf->FollowDependency(pConf->GetName()))>0) {
-       Logging(kHLTLogError, "BASE", "AliHLTSystem", "detected ring dependency for configuration \"%s\"", pTask->GetName());
+       HLTError("detected circular dependency for configuration \"%s\"", pTask->GetName());
        pTask->PrintDependencyTree(pTask->GetName(), 1/*use the configuration list*/);
-       Logging(kHLTLogError, "BASE", "AliHLTSystem", "aborted ...");
+       HLTError("aborted ...");
        iResult=-ELOOP;
       }
       if (iResult>=0) {
        // check whether all dependencies are already in the task list
        // create the missing ones
+       // this step is an iterative process which calls this function again for the missing
+       // configurations, in order to avoid the currently processed task to be created
+       // again it is added to the list temporarily and removed afterwards
+       // This is of high importance to preserve the order of the tasks. Furthermore, the
+       // InsertTask method has to be used in order to set all the cross links right 
        fTaskList.Add(pTask);
        AliHLTConfiguration* pDep=pConf->GetFirstSource();
        while (pDep!=NULL && iResult>=0) {
@@ -115,6 +195,7 @@ int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
          }
          pDep=pConf->GetNextSource();
        }
+       // remove the temporarily added task
        fTaskList.Remove(pTask);
 
        // insert the task and set the cross-links
@@ -134,6 +215,7 @@ int AliHLTSystem::BuildTaskList(AliHLTConfiguration* pConf)
 
 int AliHLTSystem::CleanTaskList()
 {
+  // see header file for class documentation
   int iResult=0;
   TObjLink* lnk=NULL;
   while ((lnk=fTaskList.FirstLink())!=NULL) {
@@ -145,22 +227,23 @@ int AliHLTSystem::CleanTaskList()
 
 int AliHLTSystem::InsertTask(AliHLTTask* pTask)
 {
+  // see header file for class documentation
   int iResult=0;
   TObjLink *lnk = NULL;
   if ((iResult=pTask->CheckDependencies())>0)
     lnk=fTaskList.FirstLink();
   while (lnk && iResult>0) {
     AliHLTTask* pCurr = (AliHLTTask*)lnk->GetObject();
-    //Logging(kHLTLogDebug, "BASE", "AliHLTSystem", "checking  \"%s\"", pCurr->GetName());
+    //HLTDebug("checking  \"%s\"", pCurr->GetName());
     iResult=pTask->Depends(pCurr);
     if (iResult>0) {
       iResult=pTask->SetDependency(pCurr);
       pCurr->SetTarget(pTask);
-      Logging(kHLTLogDebug, "BASE", "AliHLTSystem", "set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
+      HLTDebug("set dependency  \"%s\" for configuration \"%s\"", pCurr->GetName(), pTask->GetName());
     }
     if (pCurr->Depends(pTask)) {
-      // ring dependency
-      Logging(kHLTLogError, "BASE", "AliHLTSystem", "ring dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
+      // circular dependency
+      HLTError("circular dependency: can not resolve dependencies for configuration \"%s\"", pTask->GetName());
       iResult=-ELOOP;
     } else if ((iResult=pTask->CheckDependencies())>0) {
       lnk = lnk->Next();
@@ -172,9 +255,9 @@ int AliHLTSystem::InsertTask(AliHLTTask* pTask)
       } else {
        fTaskList.AddFirst(pTask);
       }
-      Logging(kHLTLogDebug, "BASE", "AliHLTSystem", "task \"%s\" inserted", pTask->GetName());
+      HLTDebug("task \"%s\" inserted", pTask->GetName());
   } else if (iResult>0) {
-    Logging(kHLTLogError, "BASE", "AliHLTSystem", "can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
+    HLTError("can not resolve dependencies for configuration \"%s\" (%d unresolved)", pTask->GetName(), iResult);
     iResult=-ENOLINK;
   }
   return iResult;
@@ -182,6 +265,7 @@ int AliHLTSystem::InsertTask(AliHLTTask* pTask)
 
 AliHLTTask* AliHLTSystem::FindTask(const char* id)
 {
+  // see header file for class documentation
   AliHLTTask* pTask=NULL;
   if (id) {
     pTask=(AliHLTTask*)fTaskList.FindObject(id); 
@@ -191,13 +275,15 @@ AliHLTTask* AliHLTSystem::FindTask(const char* id)
 
 void AliHLTSystem::PrintTaskList()
 {
+  // see header file for class documentation
+  HLTLogKeyword("task list");
   TObjLink *lnk = NULL;
-  Logging(kHLTLogInfo, "BASE", "AliHLTSystem", "Task List");
+  HLTMessage("Task List");
   lnk=fTaskList.FirstLink();
   while (lnk) {
     TObject* obj=lnk->GetObject();
     if (obj) {
-      Logging(kHLTLogInfo, "BASE", "AliHLTSystem", "  %s - status:", obj->GetName());
+      HLTMessage("  %s - status:", obj->GetName());
       AliHLTTask* pTask=(AliHLTTask*)obj;
       pTask->PrintStatus();
     } else {
@@ -205,3 +291,325 @@ void AliHLTSystem::PrintTaskList()
     lnk = lnk->Next();
   }
 }
+
+int AliHLTSystem::Run(Int_t iNofEvents) 
+{
+  // see header file for class documentation
+  int iResult=0;
+  int iCount=0;
+  SetStatusFlags(kRunning);
+  if ((iResult=InitTasks())>=0) {
+    if ((iResult=StartTasks())>=0) {
+      for (int i=0; i<iNofEvents && iResult>=0; i++) {
+       iResult=ProcessTasks(i);
+       if (iResult>=0) {
+         HLTInfo("Event %d successfully finished (%d)", i, iResult);
+         iResult=0;
+         iCount++;
+       } else {
+         HLTError("Processing of event %d failed (%d)", i, iResult);
+         // TODO: define different running modes to either ignore errors in
+         // event processing or not
+         // currently ignored 
+         //iResult=0;
+       }
+      }
+      StopTasks();
+    } else {
+      HLTError("can not start task list");
+    }
+    DeinitTasks();
+  } else if (iResult!=-ENOENT) {
+    HLTError("can not initialize task list");
+  }
+  if (iResult>=0) iResult=iCount;
+  ClearStatusFlags(kRunning);
+  return iResult;
+}
+
+int AliHLTSystem::InitTasks()
+{
+  // see header file for class documentation
+  int iResult=0;
+  TObjLink *lnk=fTaskList.FirstLink();
+  if (lnk==NULL) {
+    HLTWarning("Task list is empty, aborting ...");
+    return -ENOENT;
+  }
+  while (lnk && iResult>=0) {
+    TObject* obj=lnk->GetObject();
+    if (obj) {
+      AliHLTTask* pTask=(AliHLTTask*)obj;
+      iResult=pTask->Init(NULL, fpComponentHandler);
+    } else {
+    }
+    lnk = lnk->Next();
+  }
+  if (iResult<0) {
+  }
+  return iResult;
+}
+
+int AliHLTSystem::StartTasks()
+{
+  // see header file for class documentation
+  int iResult=0;
+  TObjLink *lnk=fTaskList.FirstLink();
+  while (lnk && iResult>=0) {
+    TObject* obj=lnk->GetObject();
+    if (obj) {
+      AliHLTTask* pTask=(AliHLTTask*)obj;
+      iResult=pTask->StartRun();
+    } else {
+    }
+    lnk = lnk->Next();
+  }
+  if (iResult<0) {
+  }
+  return iResult;
+}
+
+int AliHLTSystem::ProcessTasks(Int_t eventNo)
+{
+  // see header file for class documentation
+  int iResult=0;
+  HLTDebug("processing event no %d", eventNo);
+  TObjLink *lnk=fTaskList.FirstLink();
+  while (lnk && iResult>=0) {
+    TObject* obj=lnk->GetObject();
+    if (obj) {
+      AliHLTTask* pTask=(AliHLTTask*)obj;
+      iResult=pTask->ProcessTask(eventNo);
+      HLTDebug("task %s finnished (%d)", pTask->GetName(), iResult);
+    } else {
+    }
+    lnk = lnk->Next();
+  }
+  return iResult;
+}
+
+int AliHLTSystem::StopTasks()
+{
+  // see header file for class documentation
+  int iResult=0;
+  TObjLink *lnk=fTaskList.FirstLink();
+  while (lnk && iResult>=0) {
+    TObject* obj=lnk->GetObject();
+    if (obj) {
+      AliHLTTask* pTask=(AliHLTTask*)obj;
+      iResult=pTask->EndRun();
+    } else {
+    }
+    lnk = lnk->Next();
+  }
+  return iResult;
+}
+
+int AliHLTSystem::DeinitTasks()
+{
+  // see header file for class documentation
+  int iResult=0;
+  TObjLink *lnk=fTaskList.FirstLink();
+  while (lnk && iResult>=0) {
+    TObject* obj=lnk->GetObject();
+    if (obj) {
+      AliHLTTask* pTask=(AliHLTTask*)obj;
+      iResult=pTask->Deinit();
+    } else {
+    }
+    lnk = lnk->Next();
+  }
+  return iResult;
+}
+
+void* AliHLTSystem::AllocMemory( void* param, unsigned long size )
+{
+  // see header file for class documentation
+  if (param==NULL) {
+    // get rid of 'unused parameter' warning
+  }
+  return (void*)new char[size];
+}
+
+int AliHLTSystem::Reconstruct(int nofEvents, AliRunLoader* runLoader, 
+                             AliRawReader* rawReader)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (runLoader) {
+    HLTInfo("Run Loader %p, Raw Reader %p , %d events", runLoader, rawReader, nofEvents);
+    if (CheckStatus(kReady)) {
+      iResult=Run(nofEvents);
+    } else {
+      HLTError("wrong state %#x, required flags %#x", GetStatusFlags(), kReady);
+    }
+  } else {
+    HLTError("missing run loader instance");
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTSystem::FillESD(int eventNo, AliRunLoader* runLoader, AliESD* esd)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (runLoader) {
+    HLTInfo("Event %d: Run Loader %p, ESD %p", eventNo, runLoader, esd);
+  } else {
+    HLTError("missing run loader/ESD instance(s)");
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTSystem::LoadComponentLibraries(const char* libraries)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (libraries) {
+    if (fpComponentHandler) {
+      TString libs(libraries);
+      TObjArray* pTokens=libs.Tokenize(" ");
+      if (pTokens) {
+       int iEntries=pTokens->GetEntries();
+       for (int i=0; i<iEntries && iResult>=0; i++) {
+         iResult=fpComponentHandler->LoadLibrary((((TObjString*)pTokens->At(i))->GetString()).Data());
+       }
+       delete pTokens;
+      }
+      if (iResult>=0) {
+       SetStatusFlags(kLibrariesLoaded);
+      } else {
+       // lets see if we need this, probably not
+       //fpComponentHandler->UnloadLibraries();
+       ClearStatusFlags(kLibrariesLoaded);
+      }
+    } else {
+      iResult=-EFAULT;
+      HLTFatal("no component handler available");
+    }
+  } else {
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTSystem::Configure(AliRunLoader* runloader)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (CheckStatus(kRunning)) {
+    HLTError("HLT system in running state, can not configure");
+    return -EBUSY;
+  }
+  ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
+  iResult=LoadConfigurations(runloader);
+  if (iResult>=0) {
+    SetStatusFlags(kConfigurationLoaded);
+    iResult=BuildTaskListsFromTopConfigurations(runloader);
+    if (iResult>=0) {
+      SetStatusFlags(kTaskListCreated);
+    }
+  }
+  if (iResult<0) SetStatusFlags(kError);
+  
+  return iResult;
+}
+
+int AliHLTSystem::Reset(int bForce)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (!bForce && CheckStatus(kRunning)) {
+    HLTError("HLT system in running state, can not configure");
+    return -EBUSY;
+  }
+  CleanTaskList();
+  ClearStatusFlags(~kUninitialized);
+  return iResult;
+}
+
+int AliHLTSystem::LoadConfigurations(AliRunLoader* runloader)
+{
+  // see header file for class documentation
+  if (CheckStatus(kRunning)) {
+    HLTError("HLT system in running state, can not configure");
+    return -EBUSY;
+  }
+  int iResult=0;
+  AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
+  while (pAgent) {
+    HLTDebug("load configurations for agent %s (%p)", pAgent->GetName(), pAgent);
+    pAgent->CreateConfigurations(fpConfigurationHandler, runloader);
+    pAgent=AliHLTModuleAgent::GetNextAgent();
+  }
+  return iResult;
+}
+
+int AliHLTSystem::BuildTaskListsFromTopConfigurations(AliRunLoader* runloader)
+{
+  // see header file for class documentation
+  if (CheckStatus(kRunning)) {
+    HLTError("HLT system in running state, can not configure");
+    return -EBUSY;
+  }
+  if (!CheckStatus(kConfigurationLoaded)) {
+    HLTWarning("configurations not yet loaded");
+    return 0;
+  }
+
+  int iResult=0;
+  AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent();
+  while (pAgent && iResult>=0) {
+    TString tops=pAgent->GetTopConfigurations(runloader);
+    HLTDebug("top configurations for agent %s (%p): %s", pAgent->GetName(), pAgent, tops.Data());
+    TObjArray* pTokens=tops.Tokenize(" ");
+    if (pTokens) {
+      int iEntries=pTokens->GetEntries();
+      for (int i=0; i<iEntries && iResult>=0; i++) {
+       const char* pCID=((TObjString*)pTokens->At(i))->GetString().Data();
+       AliHLTConfiguration* pConf=fpConfigurationHandler->FindConfiguration(pCID);
+       if (pConf) {
+         iResult=BuildTaskList(pConf);
+       } else {
+         HLTWarning("can not find top configuration %s", pCID);
+       }
+      }
+      delete pTokens;
+    }
+    
+    pAgent=AliHLTModuleAgent::GetNextAgent();
+  }
+  if (iResult>=0) SetStatusFlags(kTaskListCreated);
+
+  return iResult;
+}
+
+int AliHLTSystem::CheckStatus(int flag)
+{
+  // see header file for class documentation
+  if (flag==kUninitialized && flag==fState) return 1;
+  if ((fState&flag)==flag) return 1;
+  return 0;
+}
+
+int AliHLTSystem::GetStatusFlags()
+{
+  // see header file for class documentation
+  return fState;
+}
+
+int AliHLTSystem::SetStatusFlags(int flags)
+{
+  // see header file for class documentation
+  fState|=flags;
+  return fState;
+}
+
+int AliHLTSystem::ClearStatusFlags(int flags)
+{
+  // see header file for class documentation
+  fState&=~flags;
+  return fState;
+}