X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=HLT%2FBASE%2FAliHLTComponent.cxx;h=1fc871814b67f045199dddb4547fc755a9d14b8a;hb=552165965afa36010a518aa1f08f4f5508264af3;hp=fe4ce04d436adc0c8b972c3bb3f4bfea6879de94;hpb=7a5ccd96a42770d6852f425b753ed1d9ec23bbd8;p=u%2Fmrichter%2FAliRoot.git diff --git a/HLT/BASE/AliHLTComponent.cxx b/HLT/BASE/AliHLTComponent.cxx index fe4ce04d436..1fc871814b6 100644 --- a/HLT/BASE/AliHLTComponent.cxx +++ b/HLT/BASE/AliHLTComponent.cxx @@ -1,20 +1,21 @@ // $Id$ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Authors: Matthias Richter * - * Timm Steinbeck * - * for The ALICE Off-line Project. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ +//************************************************************************** +//* This file is property of and copyright by the ALICE HLT Project * +//* ALICE Experiment at CERN, All rights reserved. * +//* * +//* Primary Authors: Matthias Richter * +//* Timm Steinbeck * +//* for The ALICE HLT Project. * +//* * +//* Permission to use, copy, modify and distribute this software and its * +//* documentation strictly for non-commercial purposes is hereby granted * +//* without fee, provided that the above copyright notice appears in all * +//* copies and that both the copyright notice and this permission notice * +//* appear in the supporting documentation. The authors make no claims * +//* about the suitability of this software for any purpose. It is * +//* provided "as is" without express or implied warranty. * +//************************************************************************** /** @file AliHLTComponent.cxx @author Matthias Richter, Timm Steinbeck @@ -25,14 +26,26 @@ using namespace std; #endif -#include "AliHLTStdIncludes.h" +//#include "AliHLTStdIncludes.h" #include "AliHLTComponent.h" #include "AliHLTComponentHandler.h" #include "AliHLTMessage.h" #include "TString.h" +#include "TMath.h" #include "TObjArray.h" +#include "TObjectTable.h" #include "TClass.h" #include "TStopwatch.h" +#include "AliHLTMemoryFile.h" +#include "AliHLTMisc.h" +#include +#include + +/** + * default compression level for ROOT objects + */ +#define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5 +#define ALIHLTCOMPONENT_STATTIME_SCALER 1000000 /** ROOT macro for the implementation of ROOT specific class methods */ ClassImp(AliHLTComponent); @@ -62,53 +75,61 @@ AliHLTComponent::AliHLTComponent() fOutputBufferSize(0), fOutputBufferFilled(0), fOutputBlocks(), - fpStopwatches(new TObjArray(kSWTypeCount)) + fpStopwatches(new TObjArray(kSWTypeCount)), + fMemFiles(), + fpRunDesc(NULL), + fpDDLList(NULL), + fCDBSetRunNoFunc(false), + fChainId(), + fChainIdCrc(0), + fpBenchmark(NULL), + fRequireSteeringBlocks(false), + fEventType(gkAliEventTypeUnknown), + fComponentArgs(), + fEventDoneData(NULL), + fEventDoneDataSize(0), + fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION) + , fLastObjectSize(0) { // see header file for class documentation // or // refer to README to build package // or // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt - memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment)); + memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment)); if (fgpComponentHandler) fgpComponentHandler->ScheduleRegister(this); - SetLocalLoggingLevel(kHLTLogDefault); -} - -AliHLTComponent::AliHLTComponent(const AliHLTComponent&) - : - AliHLTLogging(), - fEnvironment(), - fCurrentEvent(0), - fEventCount(-1), - fFailedEvents(0), - fCurrentEventData(), - fpInputBlocks(NULL), - fCurrentInputBlock(-1), - fSearchDataType(kAliHLTVoidDataType), - fClassName(), - fpInputObjects(NULL), - fpOutputBuffer(NULL), - fOutputBufferSize(0), - fOutputBufferFilled(0), - fOutputBlocks(), - fpStopwatches(NULL) -{ - // see header file for class documentation - HLTFatal("copy constructor untested"); -} - -AliHLTComponent& AliHLTComponent::operator=(const AliHLTComponent&) -{ - // see header file for class documentation - HLTFatal("assignment operator untested"); - return *this; + //SetLocalLoggingLevel(kHLTLogDefault); } AliHLTComponent::~AliHLTComponent() { // see header file for function documentation + if (fpBenchmark) delete fpBenchmark; + fpBenchmark=NULL; + CleanupInputObjects(); + if (fpStopwatches!=NULL) delete fpStopwatches; + fpStopwatches=NULL; + AliHLTMemoryFilePList::iterator element=fMemFiles.begin(); + while (element!=fMemFiles.end()) { + if (*element) { + if ((*element)->IsClosed()==0) { + HLTWarning("memory file has not been closed, possible data loss or incomplete buffer"); + // close but do not flush as we dont know whether the buffer is still valid + (*element)->CloseMemoryFile(0); + } + delete *element; + *element=NULL; + } + element++; + } + if (fpRunDesc) { + delete fpRunDesc; + fpRunDesc=NULL; + } + if (fEventDoneData) + delete [] reinterpret_cast( fEventDoneData ); } AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL; @@ -130,14 +151,29 @@ int AliHLTComponent::UnsetGlobalComponentHandler() return SetGlobalComponentHandler(NULL,1); } -int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv ) +int AliHLTComponent::SetComponentEnvironment(const AliHLTAnalysisEnvironment* comenv, void* environParam) { // see header file for function documentation + HLTLogKeyword(fChainId.c_str()); int iResult=0; - if (environ) { - memcpy(&fEnvironment, environ, sizeof(AliHLTComponentEnvironment)); + if (comenv) { + memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment)); + memcpy(&fEnvironment, comenv, comenv->fStructSizefStructSize:sizeof(AliHLTAnalysisEnvironment)); + fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment); fEnvironment.fParam=environParam; } + return iResult; +} + +int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv ) +{ + // see header file for function documentation + HLTLogKeyword(fChainId.c_str()); + int iResult=0; + if (comenv) { + SetComponentEnvironment(comenv, environParam); + } + fComponentArgs=""; const char** pArguments=NULL; int iNofChildArgs=0; TString argument=""; @@ -146,26 +182,39 @@ int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environPar pArguments=new const char*[argc]; if (pArguments) { for (int i=0; i=0; i++) { + if (fComponentArgs.size()>0) fComponentArgs+=" "; + fComponentArgs+=argv[i]; argument=argv[i]; if (argument.IsNull()) continue; // benchmark - if (argument.CompareTo("benchmark")==0) { + if (argument.CompareTo("-benchmark")==0) { - // loglevel - } else if (argument.CompareTo("loglevel")==0) { - if ((bMissingParam=(++i>=argc))) break; - TString parameter(argv[i]); + // -loglevel= + } else if (argument.BeginsWith("-loglevel=")) { + TString parameter=argument.ReplaceAll("-loglevel=", ""); parameter.Remove(TString::kLeading, ' '); // remove all blanks if (parameter.BeginsWith("0x") && parameter.Replace(0,2,"",0).IsHex()) { - AliHLTComponentLogSeverity loglevel=kHLTLogNone; - sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel); - SetLocalLoggingLevel(loglevel); + unsigned int loglevel=kHLTLogNone; + sscanf(parameter.Data(),"%x", &loglevel); + SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel); } else { HLTError("wrong parameter for argument %s, hex number expected", argument.Data()); iResult=-EINVAL; } + // -object-compression= + } else if (argument.BeginsWith("-object-compression=")) { + argument.ReplaceAll("-object-compression=", ""); + if (argument.IsDigit()) { + fCompressionLevel=argument.Atoi(); + if (fCompressionLevel<0 || fCompressionLevel>9) { + HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION); + fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION; + } + } else { + HLTError("wrong parameter for argument -object-compression, number expected"); + } } else { pArguments[iNofChildArgs++]=argv[i]; } @@ -181,31 +230,200 @@ int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environPar if (iResult>=0) { iResult=DoInit(iNofChildArgs, pArguments); } - if (iResult>=0) fEventCount=0; + if (iResult>=0) { + fEventCount=0; + + // find out if the component wants to get the steering events + // explicitly + AliHLTComponentDataTypeList inputDt; + GetInputDataTypes(inputDt); + for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin(); + dt!=inputDt.end() && !fRequireSteeringBlocks; + dt++) { + fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR); + fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType); + fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR); + fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL); + fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics); + } + } if (pArguments) delete [] pArguments; + +#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS) + // benchmarking stopwatch for the component statistics + fpBenchmark=new TStopwatch; +#endif + return iResult; } int AliHLTComponent::Deinit() { // see header file for function documentation + HLTLogKeyword(fChainId.c_str()); int iResult=0; iResult=DoDeinit(); + if (fpRunDesc) { + HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo); + AliHLTRunDesc* pRunDesc=fpRunDesc; + fpRunDesc=NULL; + delete pRunDesc; + } + fEventCount=0; return iResult; } -int AliHLTComponent::DoInit( int argc, const char** argv ) +int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler) { // see header file for function documentation - if (argc==0 && argv==NULL) { - // this is currently just to get rid of the warning "unused parameter" + int iResult=0; + HLTInfo("Using CDB: %s", cdbPath); + if (pHandler) { + // I have to think about separating the library handling from the + // component handler. Requiring the component handler here is not + // the cleanest solution. + // We presume the library already to be loaded, which is the case + // because it is loaded in the initialization of the logging functionality + // + // find the symbol + AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB); + if (pFunc) { + TString path; + if (cdbPath && cdbPath[0]!=0) { + path=cdbPath; + // very temporary fix, have to check for other formats + if (!path.BeginsWith("local://")) { + path="local://"; + path+=cdbPath; + } + } + if ((iResult=(*pFunc)(path.Data()))>=0) { + if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) { + Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB", + "can not find function to set CDB run no"); + } + } + } else { + Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB", + "can not find initialization function"); + iResult=-ENOSYS; } + } else { + iResult=-EINVAL; + } + return iResult; +} + +int AliHLTComponent::SetCDBRunNo(int runNo) +{ + // see header file for function documentation + if (!fCDBSetRunNoFunc) return 0; + return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo); +} + +int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/) +{ + // see header file for function documentation + if (!desc) return -EINVAL; + if (desc->fStructSize!=sizeof(AliHLTRunDesc)) { + HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize); + return -EINVAL; + } + + if (!fpRunDesc) { + fpRunDesc=new AliHLTRunDesc; + if (!fpRunDesc) return -ENOMEM; + *fpRunDesc=kAliHLTVoidRunDesc; + } + + if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) { + HLTWarning("Run description has already been set"); + } + *fpRunDesc=*desc; + SetCDBRunNo(fpRunDesc->fRunNo); + // TODO: we have to decide about the runType return 0; } -int AliHLTComponent::DoDeinit() +int AliHLTComponent::SetComponentDescription(const char* desc) { // see header file for function documentation + int iResult=0; + if (!desc) return 0; + + TString descriptor=desc; + TObjArray* pTokens=descriptor.Tokenize(" "); + if (pTokens) { + for (int i=0; iGetEntries() && iResult>=0; i++) { + TString argument=((TObjString*)pTokens->At(i++))->GetString(); + if (!argument || argument.IsNull()) continue; + + // chainid + if (argument.BeginsWith("chainid")) { + argument.ReplaceAll("chainid", ""); + if (argument.BeginsWith("=")) { + fChainId=argument.Replace(0,1,""); + fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length()); + HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc); + } else { + fChainId=""; + } + } else { + HLTWarning("unknown component description %s", argument.Data()); + } + } + } + + return iResult; +} + +int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/) +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); + return 0; +} + +int AliHLTComponent::DoDeinit() +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); + return 0; +} + +int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); + return 0; +} + +int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/) +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); + return 0; +} + +int AliHLTComponent::StartOfRun() +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); + return 0; +} + +int AliHLTComponent::EndOfRun() +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); + return 0; +} + + +int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/) +{ + // default implementation, childs can overload + HLTLogKeyword("dummy"); return 0; } @@ -218,11 +436,49 @@ void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char o strncat( output, type.fID, kAliHLTComponentDataTypefIDsize ); } -string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type ) +string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode) { // see header file for function documentation string out(""); - + + if (mode==2) { + int i=0; + char tmp[8]; + for (i=0; i& blocks, AliHLTUInt32_t* blockCount, +int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount, AliHLTComponentBlockData** outputBlocks ) { // see header file for function documentation @@ -269,7 +525,7 @@ int AliHLTComponent::MakeOutputDataBlockList( const vector* tgtList) +int AliHLTComponent::ReserveEventDoneData( unsigned long size ) +{ + // see header file for function documentation + int iResult=0; + + + if (size>fEventDoneDataSize) { + AliHLTComponentEventDoneData* newEDD = reinterpret_cast( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+size ] ); + if (!newEDD) + return -ENOMEM; + newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData); + newEDD->fDataSize = 0; + newEDD->fData = reinterpret_cast(newEDD)+newEDD->fStructSize; + if (fEventDoneData) { + memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize ); + newEDD->fDataSize = fEventDoneData->fDataSize; + delete [] reinterpret_cast( fEventDoneData ); + } + fEventDoneData = newEDD; + fEventDoneDataSize = size; + } + return iResult; + +} + +int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord ) +{ + if (!fEventDoneData) + return -ENOMEM; + if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize) + return -ENOSPC; + *reinterpret_cast((reinterpret_cast(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord; + fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t); + return 0; +} + +void AliHLTComponent::ReleaseEventDoneData() +{ + if (fEventDoneData) + delete [] reinterpret_cast( fEventDoneData ); + fEventDoneData = NULL; + fEventDoneDataSize = 0; +} + + +int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList) { // see header file for function documentation int iResult=0; if (pConsumer) { - vector ctlist; - ((AliHLTComponent*)pConsumer)->GetInputDataTypes(ctlist); - vector::iterator type=ctlist.begin(); - //AliHLTComponentDataType ouptdt=GetOutputDataType(); - //PrintDataTypeContent(ouptdt, "publisher \'%s\'"); - while (type!=ctlist.end() && iResult==0) { - //PrintDataTypeContent((*type), "consumer \'%s\'"); - if ((*type)==GetOutputDataType() || - (*type)==kAliHLTAnyDataType) { - if (tgtList) tgtList->push_back(*type); + AliHLTComponentDataTypeList itypes; + AliHLTComponentDataTypeList otypes; + otypes.push_back(GetOutputDataType()); + if (MatchExactly(otypes[0],kAliHLTMultipleDataType)) { + otypes.clear(); + int count=0; + if ((count=GetOutputDataTypes(otypes))>0) { + } else if (GetComponentType()!=kSink) { + HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count); + } + } + ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes); + AliHLTComponentDataTypeList::iterator otype=otypes.begin(); + for (;otype!=otypes.end();otype++) { + //PrintDataTypeContent((*otype), "publisher \'%s\'"); + if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) { + if (tgtList) tgtList->push_back(*otype); + iResult++; + continue; + } + + AliHLTComponentDataTypeList::iterator itype=itypes.begin(); + for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */}; + //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'"); + if (itype!=itypes.end()) { + if (tgtList) tgtList->push_back(*otype); iResult++; - // this loop has to be changed in case of multiple output types - break; } - type++; } } else { iResult=-EINVAL; @@ -320,27 +634,29 @@ int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, vectorkAliHLTComponentDataTypefIDsize) { - HLTWarning("data type id %s is too long, truncated to %d", id, kAliHLTComponentDataTypefIDsize); + tgtdt.fStructSize=sizeof(AliHLTComponentDataType); + if (id) { + memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize); + strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize); } - strncpy(&tgtdt.fID[0], id, kAliHLTComponentDataTypefIDsize); - - if ((int)strlen(origin)>kAliHLTComponentDataTypefOriginSize) { - HLTWarning("data type origin %s is too long, truncated to %d", origin, kAliHLTComponentDataTypefOriginSize); + if (origin) { + memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize); + strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize); } - strncpy(&tgtdt.fOrigin[0], origin, kAliHLTComponentDataTypefOriginSize); +} + +void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin) +{ + // see header file for function documentation + dt.fStructSize=sizeof(AliHLTComponentDataType); + assert(kAliHLTComponentDataTypefIDsize==sizeof(id)); + assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin)); + memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize); + memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize); } void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData) @@ -396,6 +718,7 @@ void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData) // see header file for function documentation memset(&evtData, 0, sizeof(AliHLTComponentEventData)); evtData.fStructSize=sizeof(AliHLTComponentEventData); + evtData.fEventID=kAliHLTVoidEventID; } void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt) @@ -429,7 +752,7 @@ int AliHLTComponent::IncrementEventCounter() return fEventCount; } -int AliHLTComponent::GetNumberOfInputBlocks() +int AliHLTComponent::GetNumberOfInputBlocks() const { // see header file for function documentation if (fpInputBlocks!=NULL) { @@ -438,6 +761,15 @@ int AliHLTComponent::GetNumberOfInputBlocks() return 0; } +AliHLTEventID_t AliHLTComponent::GetEventId() const +{ + // see header file for function documentation + if (fpInputBlocks!=NULL) { + return fCurrentEventData.fEventID; + } + return 0; +} + const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt, const char* classname, int bForce) @@ -447,10 +779,10 @@ const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataTyp fSearchDataType=dt; if (classname) fClassName=classname; else fClassName.clear(); - int idx=FindInputBlock(fSearchDataType, 0); - HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str()); + int idx=FindInputBlock(fSearchDataType, 0, 1); TObject* pObj=NULL; if (idx>=0) { + HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str()); if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) { fCurrentInputBlock=idx; } else { @@ -475,7 +807,7 @@ const TObject* AliHLTComponent::GetNextInputObject(int bForce) { // see header file for function documentation ALIHLTCOMPONENT_BASE_STOPWATCH(); - int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1); + int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1); //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str()); TObject* pObj=NULL; if (idx>=0) { @@ -486,16 +818,21 @@ const TObject* AliHLTComponent::GetNextInputObject(int bForce) return pObj; } -int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx) +int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const { // see header file for function documentation int iResult=-ENOENT; if (fpInputBlocks!=NULL) { int idx=startIdx<0?0:startIdx; for ( ; (UInt_t)idxGetName()); + TClass* objclass=msg.GetClass(); + pObj=msg.ReadObject(objclass); + if (pObj && objclass) { + HLTDebug("object %p type %s created", pObj, objclass->GetName()); } else { } - } else { - // } else if (bForce!=0) { - HLTError("size missmatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t)); + //} else { + } else if (bForce!=0) { + HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t)); } } else { HLTFatal("block descriptor empty"); @@ -534,7 +872,7 @@ TObject* AliHLTComponent::CreateInputObject(int idx, int bForce) return pObj; } -TObject* AliHLTComponent::GetInputObject(int idx, const char* classname, int bForce) +TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce) { // see header file for function documentation if (fpInputObjects==NULL) { @@ -557,12 +895,27 @@ TObject* AliHLTComponent::GetInputObject(int idx, const char* classname, int bFo int AliHLTComponent::CleanupInputObjects() { + // see header file for function documentation if (!fpInputObjects) return 0; TObjArray* array=fpInputObjects; fpInputObjects=NULL; for (int i=0; iGetEntries(); i++) { TObject* pObj=array->At(i); - if (pObj) delete pObj; + // grrr, garbage collection strikes back: When read via AliHLTMessage + // (CreateInputObject), and written to a TFile afterwards, the + // TFile::Close calls ROOOT's garbage collection. No clue why the + // object ended up in the key list and needs to be deleted + // + // Matthias 09.11.2008 follow up + // This approach doesn't actually work in all cases: the object table + // can be switched off globally, the flag needs to be checked here as + // well in order to avoid memory leaks. + // This means we have to find another solution for the problem if it + // pops up again. + if (pObj && + (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) { + delete pObj; + } } delete array; return 0; @@ -612,6 +965,43 @@ AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject) return iSpec; } +int AliHLTComponent::Forward(const TObject* pObject) +{ + // see header file for function documentation + int iResult=0; + int idx=fCurrentInputBlock; + if (pObject) { + if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) { + } else { + HLTError("unknown object %p", pObject); + iResult=-ENOENT; + } + } + if (idx>=0) { + fOutputBlocks.push_back(fpInputBlocks[idx]); + } + return iResult; +} + +int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock) +{ + // see header file for function documentation + int iResult=0; + int idx=fCurrentInputBlock; + if (pBlock) { + if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) { + } else { + HLTError("unknown Block %p", pBlock); + iResult=-ENOENT; + } + } + if (idx>=0) { + // check for fpInputBlocks pointer done in FindInputBlock + fOutputBlocks.push_back(fpInputBlocks[idx]); + } + return iResult; +} + const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt) { // see header file for function documentation @@ -623,6 +1013,7 @@ const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLT if (idx>=0) { // check for fpInputBlocks pointer done in FindInputBlock pBlock=&fpInputBlocks[idx]; + fCurrentInputBlock=idx; } return pBlock; } @@ -637,6 +1028,14 @@ const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* return GetFirstInputBlock(dt); } +const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const +{ + // see header file for function documentation + ALIHLTCOMPONENT_BASE_STOPWATCH(); + assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt ); + return &fpInputBlocks[index]; +} + const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock() { // see header file for function documentation @@ -646,11 +1045,12 @@ const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock() if (idx>=0) { // check for fpInputBlocks pointer done in FindInputBlock pBlock=&fpInputBlocks[idx]; + fCurrentInputBlock=idx; } return pBlock; } -int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) +int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const { // see header file for function documentation int iResult=-ENOENT; @@ -685,21 +1085,43 @@ AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* return iSpec; } -int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec) +int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, + void* pHeader, int headerSize) { // see header file for function documentation ALIHLTCOMPONENT_BASE_STOPWATCH(); int iResult=0; + fLastObjectSize=0; if (pObject) { AliHLTMessage msg(kMESS_OBJECT); + msg.SetCompressionLevel(fCompressionLevel); msg.WriteObject(pObject); Int_t iMsgLength=msg.Length(); if (iMsgLength>0) { + // Matthias Sep 2008 + // NOTE: AliHLTMessage does implement it's own SetLength method + // which is not architecture independent. The original SetLength + // stores the size always in network byte order. + // I'm trying to remember the rational for that, might be that + // it was just some lack of knowledge. Want to change this, but + // has to be done carefullt to be backward compatible. msg.SetLength(); // sets the length to the first (reserved) word - iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec); + + // does nothing if the level is 0 + msg.Compress(); + + char *mbuf = msg.Buffer(); + if (msg.CompBuffer()) { + msg.SetLength(); // set once more to have to byte order + mbuf = msg.CompBuffer(); + iMsgLength = msg.CompLength(); + } + assert(mbuf!=NULL); + iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize); if (iResult>=0) { - HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength); + HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel()); } + fLastObjectSize=iMsgLength; } else { HLTError("object serialization failed for object %p", pObject); iResult=-ENOMSG; @@ -710,81 +1132,260 @@ int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& d return iResult; } -int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec) +int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec, + void* pHeader, int headerSize) { // see header file for function documentation ALIHLTCOMPONENT_BASE_STOPWATCH(); AliHLTComponentDataType dt; SetDataType(dt, dtID, dtOrigin); - return PushBack(pObject, dt, spec); + return PushBack(pObject, dt, spec, pHeader, headerSize); } -int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec) +int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, + const void* pHeader, int headerSize) { // see header file for function documentation ALIHLTCOMPONENT_BASE_STOPWATCH(); - return InsertOutputBlock(pBuffer, iSize, dt, spec); + return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize); } -int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec) +int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec, + const void* pHeader, int headerSize) { // see header file for function documentation ALIHLTCOMPONENT_BASE_STOPWATCH(); AliHLTComponentDataType dt; SetDataType(dt, dtID, dtOrigin); - return PushBack(pBuffer, iSize, dt, spec); + return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize); } -int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec) +int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, + const void* pHeader, int iHeaderSize) { // see header file for function documentation int iResult=0; - if (pBuffer) { - if (fpOutputBuffer && iSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) { + int iBlkSize = iBufferSize + iHeaderSize; + + if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) { + if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) { AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled; - AliHLTComponentBlockData bd; - FillBlockData( bd ); - bd.fOffset = fOutputBufferFilled; - bd.fPtr = pTgt; - bd.fSize = iSize; - bd.fDataType = dt; - bd.fSpecification = spec; + + // copy header if provided but skip if the header is the target location + // in that case it has already been copied + if (pHeader!=NULL && pHeader!=pTgt) { + memcpy(pTgt, pHeader, iHeaderSize); + } + + pTgt += (AliHLTUInt8_t) iHeaderSize; + + // copy buffer if provided but skip if buffer is the target location + // in that case it has already been copied if (pBuffer!=NULL && pBuffer!=pTgt) { - memcpy(pTgt, pBuffer, iSize); + memcpy(pTgt, pBuffer, iBufferSize); + //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); - //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iSize, pBuffer, pTgt, firstWord); + //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord); } - fOutputBufferFilled+=bd.fSize; - fOutputBlocks.push_back( bd ); - //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iSize, DataType2Text(dt).c_str(), spec); + //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec); } else { if (fpOutputBuffer) { - HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iSize); + HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize); } else { HLTError("output buffer not available"); } iResult=-ENOSPC; } - } else { - iResult=-EINVAL; } + if (iResult>=0) { + AliHLTComponentBlockData bd; + FillBlockData( bd ); + bd.fOffset = fOutputBufferFilled; + bd.fSize = iBlkSize; + bd.fDataType = dt; + bd.fSpecification = spec; + fOutputBlocks.push_back( bd ); + fOutputBufferFilled+=bd.fSize; + } + return iResult; } int AliHLTComponent::EstimateObjectSize(TObject* pObject) const { + // see header file for function documentation if (!pObject) return -EINVAL; AliHLTMessage msg(kMESS_OBJECT); msg.WriteObject(pObject); return msg.Length(); } +AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID, + const char* dtOrigin, + AliHLTUInt32_t spec) +{ + // see header file for function documentation + ALIHLTCOMPONENT_BASE_STOPWATCH(); + AliHLTComponentDataType dt; + SetDataType(dt, dtID, dtOrigin); + return CreateMemoryFile(capacity, dt, spec); +} + +AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, + const AliHLTComponentDataType& dt, + AliHLTUInt32_t spec) +{ + // see header file for function documentation + ALIHLTCOMPONENT_BASE_STOPWATCH(); + AliHLTMemoryFile* pFile=NULL; + if (capacity>=0 && static_cast(capacity)<=fOutputBufferSize-fOutputBufferFilled){ + AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled; + pFile=new AliHLTMemoryFile((char*)pTgt, capacity); + if (pFile) { + unsigned int nofBlocks=fOutputBlocks.size(); + if (nofBlocks+1>fMemFiles.size()) { + fMemFiles.resize(nofBlocks+1, NULL); + } + if (nofBlocksCloseMemoryFile(0); + delete pFile; + pFile=NULL; + } + } + } else { + HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled); + } + return pFile; +} + +AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID, + const char* dtOrigin, + AliHLTUInt32_t spec, + float capacity) +{ + // see header file for function documentation + ALIHLTCOMPONENT_BASE_STOPWATCH(); + AliHLTComponentDataType dt; + SetDataType(dt, dtID, dtOrigin); + int size=fOutputBufferSize-fOutputBufferFilled; + if (capacity<0 || capacity>1.0) { + HLTError("invalid parameter: capacity %f", capacity); + return NULL; + } + size=(int)(size*capacity); + return CreateMemoryFile(size, dt, spec); +} + +AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt, + AliHLTUInt32_t spec, + float capacity) +{ + // see header file for function documentation + ALIHLTCOMPONENT_BASE_STOPWATCH(); + int size=fOutputBufferSize-fOutputBufferFilled; + if (capacity<0 || capacity>1.0) { + HLTError("invalid parameter: capacity %f", capacity); + return NULL; + } + size=(int)(size*capacity); + return CreateMemoryFile(size, dt, spec); +} + +int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject, + const char* key, int option) +{ + // see header file for function documentation + int iResult=0; + if (pFile && pObject) { + pFile->cd(); + iResult=pObject->Write(key, option); + if (iResult>0) { + // success + } else { + iResult=-pFile->GetErrno(); + if (iResult==-ENOSPC) { + HLTError("error writing memory file, buffer too small"); + } + } + } else { + iResult=-EINVAL; + } + return iResult; +} + +int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile) +{ + // see header file for function documentation + int iResult=0; + if (pFile) { + AliHLTMemoryFilePList::iterator element=fMemFiles.begin(); + int i=0; + while (element!=fMemFiles.end() && iResult>=0) { + if (*element && *element==pFile) { + iResult=pFile->CloseMemoryFile(); + + // sync memory files and descriptors + if (iResult>=0) { + fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize(); + } + delete *element; + *element=NULL; + return iResult; + } + element++; i++; + } + HLTError("can not find memory file %p", pFile); + iResult=-ENOENT; + } else { + iResult=-EINVAL; + } + return iResult; +} + int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd) { // see header file for function documentation - int iResult=-ENOSYS; - //#warning function not yet implemented - HLTWarning("function not yet implemented"); + int iResult=0; + + AliHLTComponentEventDoneData* newEDD = NULL; + + unsigned long newSize=edd.fDataSize; + if (fEventDoneData) + newSize += fEventDoneData->fDataSize; + + if (newSize>fEventDoneDataSize) { + newEDD = reinterpret_cast( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] ); + if (!newEDD) + return -ENOMEM; + newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData); + newEDD->fDataSize = newSize; + newEDD->fData = reinterpret_cast(newEDD)+newEDD->fStructSize; + unsigned long long offset = 0; + if (fEventDoneData) { + memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize ); + offset += fEventDoneData->fDataSize; + } + memcpy( reinterpret_cast(newEDD->fData)+offset, edd.fData, edd.fDataSize ); + if (fEventDoneData) + delete [] reinterpret_cast( fEventDoneData ); + fEventDoneData = newEDD; + fEventDoneDataSize = newSize; + } + else { + memcpy( reinterpret_cast(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize ); + fEventDoneData->fDataSize += edd.fDataSize; + } return iResult; } @@ -798,6 +1399,7 @@ int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData, AliHLTComponentEventDoneData*& edd ) { // see header file for function documentation + HLTLogKeyword(fChainId.c_str()); ALIHLTCOMPONENT_BASE_STOPWATCH(); int iResult=0; fCurrentEvent=evtData.fEventID; @@ -809,35 +1411,414 @@ int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData, fOutputBufferSize=size; fOutputBufferFilled=0; fOutputBlocks.clear(); - - vector blockData; + outputBlockCnt=0; + outputBlocks=NULL; + + AliHLTComponentBlockDataList forwardedBlocks; + + // optional component statistics + AliHLTComponentStatisticsList compStats; + bool bAddComponentTableEntry=false; + vector parentComponentTables; +#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS) + AliHLTComponentStatistics outputStat; + memset(&outputStat, 0, sizeof(AliHLTComponentStatistics)); + outputStat.fStructSize=sizeof(AliHLTComponentStatistics); + outputStat.fId=fChainIdCrc; + if (fpBenchmark) { + fpBenchmark->Stop(); + outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER); + fpBenchmark->Reset(); + fpBenchmark->Start(); + } + compStats.push_back(outputStat); +#endif + + // data processing is skipped + // - if there are only steering events in the block list. + // For the sake of data source components data processing + // is not skipped if there is no block list at all or if it + // just contains the eventType block + // - always skipped if the event is of type + // - gkAliEventTypeConfiguration + // - gkAliEventTypeReadPreprocessor + const unsigned int skipModeDefault=0x1; + const unsigned int skipModeForce=0x2; + unsigned int bSkipDataProcessing=skipModeDefault; + + // find special events + if (fpInputBlocks && evtData.fBlockCnt>0) { + // first look for all special events and execute in the appropriate + // sequence afterwords + int indexComConfEvent=-1; + int indexUpdtDCSEvent=-1; + int indexSOREvent=-1; + int indexEOREvent=-1; + for (unsigned int i=0; i=0; i++) { + if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) { + indexSOREvent=i; + // the AliHLTCalibrationProcessor relies on the SOR and EOR events + bSkipDataProcessing&=~skipModeDefault; + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) { + // run type string + // handling is not clear yet + if (fpInputBlocks[i].fPtr) { + HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr); + } + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) { + indexEOREvent=i; + // the calibration processor relies on the SOR and EOR events + bSkipDataProcessing&=~skipModeDefault; + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) { + // DDL list + // this event is most likely deprecated + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) { + indexComConfEvent=i; + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) { + indexUpdtDCSEvent=i; + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) { + fEventType=fpInputBlocks[i].fSpecification; + + // skip always in case of gkAliEventTypeConfiguration + if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce; + + // skip always in case of gkAliEventTypeReadPreprocessor + if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce; + + // never skip if the event type block is the only block + if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault; + + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) { + if (compStats.size()>0) { + AliHLTUInt8_t* pData=reinterpret_cast(fpInputBlocks[i].fPtr); + for (AliHLTUInt32_t offset=0; + offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize; + offset+=sizeof(AliHLTComponentStatistics)) { + AliHLTComponentStatistics* pStat=reinterpret_cast(pData+offset); + if (pStat && compStats[0].fLevel<=pStat->fLevel) { + compStats[0].fLevel=pStat->fLevel+1; + } + compStats.push_back(*pStat); + } + } + } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) { + forwardedBlocks.push_back(fpInputBlocks[i]); + parentComponentTables.push_back(fpInputBlocks[i].fSpecification); + } else { + // the processing function is called if there is at least one + // non-steering data block. Steering blocks are not filtered out + // for sake of performance + bSkipDataProcessing&=~skipModeDefault; + if (compStats.size()>0) { + compStats[0].fInputBlockCount++; + compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize; + } + } + } + + if (indexSOREvent>=0) { + // start of run + bAddComponentTableEntry=true; + if (fpRunDesc==NULL) { + fpRunDesc=new AliHLTRunDesc; + if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc; + } + if (fpRunDesc) { + AliHLTRunDesc rundesc; + if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) { + if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) { + *fpRunDesc=rundesc; + HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo); + SetCDBRunNo(fpRunDesc->fRunNo); + } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) { + HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo); + } + } + } else { + iResult=-ENOMEM; + } + } + if (indexEOREvent>=0) { + bAddComponentTableEntry=true; + if (fpRunDesc!=NULL) { + if (fpRunDesc) { + AliHLTRunDesc rundesc; + if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) { + if (fpRunDesc->fRunNo!=rundesc.fRunNo) { + HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo); + } else { + HLTDebug("EOR run no %d", fpRunDesc->fRunNo); + } + } + AliHLTRunDesc* pRunDesc=fpRunDesc; + fpRunDesc=NULL; + delete pRunDesc; + } + } else { + HLTWarning("did not receive SOR, ignoring EOR"); + } + } + if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) { + TString cdbEntry; + if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) { + cdbEntry.Append(reinterpret_cast(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize); + } + HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data()); + int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str()); + if (tmpResult<0) { + HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult); + } + } + if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) { + TString modules; + if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) { + modules.Append(reinterpret_cast(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize); + } + HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data()); + int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data()); + if (tmpResult<0) { + HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult); + } + } + } else { + // processing function needs to be called if there are no input data + // blocks in order to make data source components working. + bSkipDataProcessing&=~skipModeDefault; + } + + // data processing is not skipped if the component explicitly asks + // for the private blocks + if (fRequireSteeringBlocks) bSkipDataProcessing=0; + + AliHLTComponentBlockDataList blockData; + if (iResult>=0 && !bSkipDataProcessing) { // dont delete, sets the scope for the stopwatch guard - ALIHLTCOMPONENT_DA_STOPWATCH(); + // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro + // in order to avoid 'shadowed variable' warning + AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast(fpStopwatches->At((int)kSWDA)):NULL); iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd); } // end of the scope of the stopwatch guard - if (iResult>=0) { + if (iResult>=0 && !bSkipDataProcessing) { if (fOutputBlocks.size()>0) { - //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size()); - if (blockData.size()>0) { - HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks"); - iResult=-EFAULT; - } else { - iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks); - size=fOutputBufferFilled; + // High Level interface + + //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size()); + // sync memory files and descriptors + AliHLTMemoryFilePList::iterator element=fMemFiles.begin(); + int i=0; + while (element!=fMemFiles.end() && iResult>=0) { + if (*element) { + if ((*element)->IsClosed()==0) { + HLTWarning("memory file has not been closed, force flush"); + iResult=CloseMemoryFile(*element); + } + } + element++; i++; + } + + if (iResult>=0) { + // create the descriptor list + if (blockData.size()>0) { + HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks"); + iResult=-EFAULT; + } else { + if (compStats.size()>0 && IsDataEvent()) { + int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats); + if (offset>0) fOutputBufferFilled+=offset; + } + if (bAddComponentTableEntry) { + int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables); + if (offset>0) size+=offset; + } + if (forwardedBlocks.size()>0) { + fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end()); + } + iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks); + size=fOutputBufferFilled; + } } } else { + // Low Level interface + if (compStats.size()>0) { + int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats); + if (offset>0) size+=offset; + } + if (bAddComponentTableEntry) { + int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables); + if (offset>0) size+=offset; + } + if (forwardedBlocks.size()>0) { + blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end()); + } iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks); } if (iResult<0) { HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this); } } - if (iResult<0) { + if (iResult<0 || bSkipDataProcessing) { outputBlockCnt=0; outputBlocks=NULL; } CleanupInputObjects(); - IncrementEventCounter(); + if (iResult>=0 && IsDataEvent()) { + IncrementEventCounter(); + } + if (outputBlockCnt==0) { + // no output blocks, set size to 0 + size=0; + } + FillEventData(fCurrentEventData); + return iResult; +} + +int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks, + AliHLTUInt8_t* buffer, + AliHLTUInt32_t bufferSize, + AliHLTUInt32_t offset, + AliHLTComponentStatisticsList& stats) const +{ + // see header file for function documentation + int iResult=0; +#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS) + if (stats.size()==0) return -ENOENT; + // check if there is space for at least one entry + if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0; + stats[0].fTotalOutputSize=offset; + stats[0].fOutputBlockCount=blocks.size(); + if (fpBenchmark) { + fpBenchmark->Stop(); + stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER); + stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER); + fpBenchmark->Continue(); + } + if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) { + AliHLTUInt32_t removedLevel=0; + do { + // remove all entries of the level of the last entry + removedLevel=stats.back().fLevel; + AliHLTComponentStatisticsList::iterator element=stats.begin(); + element++; + while (element!=stats.end()) { + if (element->fLevel<=removedLevel) { + element=stats.erase(element); + } else { + element++; + } + } + } while (stats.size()>1 && + (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize)); + } + assert(stats.size()>0); + if (stats.size()==0) return 0; + + if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) { + AliHLTComponentBlockData bd; + FillBlockData( bd ); + bd.fOffset = offset; + bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics); + bd.fDataType = kAliHLTDataTypeComponentStatistics; + bd.fSpecification = kAliHLTVoidDataSpec; + unsigned int master=0; + for (unsigned int i=1; iblocks[master].fSize && + !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) + master=i; + } + if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) { + // take the data origin of the biggest block as specification + // this is similar to the treatment in the HOMER interface. For traditional + // reasons, the bytes are swapped there on a little endian architecture, so + // we do it as well. + memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification)); +#ifdef R__BYTESWAP // set on little endian architectures + bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) | + ((bd.fSpecification & 0xFF00ULL) << 8) | + ((bd.fSpecification & 0xFF0000ULL) >> 8) | + ((bd.fSpecification & 0xFF000000ULL) >> 24); +#endif + } + memcpy(buffer+offset, &(stats[0]), bd.fSize); + blocks.push_back(bd); + iResult=bd.fSize; + } +#else + if (blocks.size() && buffer && bufferSize && offset && stats.size()) { + // get rid of warning + } +#endif + return iResult; +} + +int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks, + AliHLTUInt8_t* buffer, + AliHLTUInt32_t bufferSize, + AliHLTUInt32_t offset, + const vector& parents) const +{ + // see header file for function documentation + int iResult=0; +#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS) + // the payload consists of the AliHLTComponentTableEntry struct, + // followed by a an array of 32bit crc chain ids and the component + // description string + unsigned int payloadSize=sizeof(AliHLTComponentTableEntry); + payloadSize+=parents.size()*sizeof(AliHLTUInt32_t); + + // the component description has the following format: + // chain-id{component-id:arguments} + const char* componentId=const_cast(this)->GetComponentID(); + unsigned int descriptionSize=fChainId.size()+1; + descriptionSize+=2; // the '{}' around the component id + descriptionSize+=strlen(componentId); + descriptionSize+=1; // the ':' between component id and arguments + descriptionSize+=fComponentArgs.size(); + + payloadSize+=descriptionSize; + if (buffer && (offset+payloadSize<=bufferSize)) { + AliHLTUInt8_t* pTgt=buffer+offset; + memset(pTgt, 0, payloadSize); + + // write entry + AliHLTComponentTableEntry* pEntry=reinterpret_cast(pTgt); + pEntry->fStructSize=sizeof(AliHLTComponentTableEntry); + pEntry->fNofParents=parents.size(); + pEntry->fSizeDescription=descriptionSize; + pTgt=pEntry->fBuffer; + + // write array of parents + if (parents.size()>0) { + unsigned int copy=parents.size()*sizeof(vector::value_type); + memcpy(pTgt, &parents[0], parents.size()*sizeof(vector::value_type)); + pTgt+=copy; + } + + // write component description + memcpy(pTgt, fChainId.c_str(), fChainId.size()); + pTgt+=fChainId.size(); + *pTgt++='{'; + memcpy(pTgt, componentId, strlen(componentId)); + pTgt+=strlen(componentId); + *pTgt++=':'; + memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size()); + pTgt+=fComponentArgs.size(); + *pTgt++='}'; + *pTgt++=0; + + AliHLTComponentBlockData bd; + FillBlockData( bd ); + bd.fOffset = offset; + bd.fSize = payloadSize; + bd.fDataType = kAliHLTDataTypeComponentTable; + bd.fSpecification = fChainIdCrc; + blocks.push_back(bd); + iResult=bd.fSize; + } +#else + if (blocks.size() && buffer && bufferSize && offset && parents.size()) { + // get rid of warning + } + #endif return iResult; } @@ -868,12 +1849,24 @@ AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwat if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE); } -AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(AliHLTStopwatchGuard&) +AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&) : fpStopwatch(NULL), fpPrec(NULL) { - // copy constructor (not for use) + // + // copy constructor not for use + // +} + +AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&) +{ + // + // assignment operator not for use + // + fpStopwatch=NULL; + fpPrec=NULL; + return *this; } AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL; @@ -938,3 +1931,264 @@ int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches) SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i); return iResult; } + +AliHLTUInt32_t AliHLTComponent::GetRunNo() const +{ + // see header file for function documentation + if (fpRunDesc==NULL) return kAliHLTVoidRunNo; + return fpRunDesc->fRunNo; +} + +AliHLTUInt32_t AliHLTComponent::GetRunType() const +{ + // see header file for function documentation + if (fpRunDesc==NULL) return kAliHLTVoidRunType; + return fpRunDesc->fRunType; +} + +bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) +{ + // see header file for function documentation + if (pTgt) *pTgt=fEventType; + return (fEventType==gkAliEventTypeData || + fEventType==gkAliEventTypeDataReplay || + fEventType==gkAliEventTypeCalibration); +} + +int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo, + const char* structname, const char* eventname) +{ + // see header file for function documentation + int iResult=0; + if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) { + if (fpInputBlocks!=NULL && iBlockNofpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize; + } + if (copy!=iStructSize) { + HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION); + if (copy>iStructSize) { + copy=iStructSize; + } else { + memset(pTgt, 0, iStructSize); + } + } + memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy); + *pTgt=iStructSize; + iResult=copy; + } else { + HLTWarning("%s event: missing data block", eventname); + } + } else { + iResult=-ENODATA; + } + } else { + HLTError("invalid struct"); + iResult=-EINVAL; + } + return iResult; +} + +void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const +{ + // see header file for function documentation + + // -- Detector offset + Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 ); + + // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 ) + Int_t wordBase = 0; + + if ( ddlIdBase <= 3 ) + wordBase = ddlIdBase; + else if ( ddlIdBase > 3 && ddlIdBase < 5 ) + wordBase = ddlIdBase + 7; + else + wordBase = ddlIdBase + 9; + + // -- Bit index in Word + Int_t bitIdx = ddlId % 32; + + // -- Index of word + Int_t wordIdx = wordBase; + + // -- if TPC (3) or TOD (5) add word idx + if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) { + wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 ); + } + + // -- Set -- 'OR' word with bit mask; + if ( state ) + list.fList[wordIdx] |= ( 0x00000001 << bitIdx ); + // -- Unset -- 'AND' word with bit mask; + else + list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) ); +} + +Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const +{ + // see header file for function documentation + + Int_t iResult = -1; + + for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) { + + if ( list.fList[wordNdx] != 0 && iResult == -1 ) { + // check for special cases TPC and TOF + if ( wordNdx > 3 && wordNdx <= 10 ) { + wordNdx = 10; + iResult = 3; + } + else if ( wordNdx > 12 && wordNdx <= 14 ) { + wordNdx = 14; + iResult = 12; + } + else + iResult = wordNdx; + } + else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) { + HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx ); + iResult = -1; + break; + } + } + + return iResult; +} + +AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size) +{ + // see header file for function documentation + AliHLTUInt32_t remainder = 0; + const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t)); + const AliHLTUInt32_t topbit=1 << (crcwidth-1); + const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */ + + // code from + // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code + + /* + * Perform modulo-2 division, a byte at a time. + */ + for (int byte = 0; byte < size; ++byte) + { + /* + * Bring the next byte into the remainder. + */ + remainder ^= (buffer[byte] << (crcwidth - 8)); + + /* + * Perform modulo-2 division, a bit at a time. + */ + for (uint8_t bit = 8; bit > 0; --bit) + { + /* + * Try to divide the current data bit. + */ + if (remainder & topbit) + { + remainder = (remainder << 1) ^ polynomial; + } + else + { + remainder = (remainder << 1); + } + } + } + + /* + * The final remainder is the CRC result. + */ + return (remainder); +} + +int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, + string& retChainId, string& retCompId, string& retCompArgs, + vector& parents) +{ + // see header file for function documentation + retChainId.clear(); + retCompId.clear(); + retCompArgs.clear(); + parents.clear(); + if (!pBuffer || size==0) return 0; + + const AliHLTComponentTableEntry* pEntry=reinterpret_cast(pBuffer); + if (size<8/* the initial size of the structure*/ || + pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG; + const AliHLTUInt32_t* pParents=reinterpret_cast(pEntry->fBuffer); + const AliHLTUInt8_t* pEnd=pBuffer+size; + + if (pParents+pEntry->fNofParents>=reinterpret_cast(pEnd)) return -ENODEV; + for (unsigned int i=0; ifNofParents; i++, pParents++) { + parents.push_back(*pParents); + } + + const char* pDescription=reinterpret_cast(pParents); + if (pDescription+pEntry->fSizeDescription>=reinterpret_cast(pEnd) || + *(pDescription+pEntry->fSizeDescription)!=0) { + return -EBADF; + } + + TString descriptor=reinterpret_cast(pDescription); + TString chainId; + TString compId; + TString compArgs; + TObjArray* pTokens=descriptor.Tokenize("{"); + if (pTokens) { + int n=0; + if (pTokens->GetEntries()>n) { + retChainId=((TObjString*)pTokens->At(n++))->GetString(); + } + if (pTokens->GetEntries()>n) { + compId=((TObjString*)pTokens->At(n++))->GetString(); + } + delete pTokens; + } + if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) { + int n=0; + if (pTokens->GetEntries()>n) { + compId=((TObjString*)pTokens->At(n++))->GetString(); + } + if (pTokens->GetEntries()>n) { + compArgs=((TObjString*)pTokens->At(n++))->GetString(); + } + delete pTokens; + } + compId.ReplaceAll("}", ""); + compArgs.ReplaceAll("}", ""); + + retCompId=compId; + retCompArgs=compArgs; + + if (retChainId.size()==0) return -ENODATA; + + return 1; +} + +int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity, + const char* originClass, const char* originFunc, + const char* file, int line, ... ) const +{ + // see header file for function documentation + int iResult=0; + + va_list args; + va_start(args, line); + + // logging function needs to be const in order to be called from const member functions + // without problems. But at this point we face the problem with virtual members which + // are not necessarily const. + AliHLTComponent* nonconst=const_cast(this); + AliHLTLogging::SetLogString("%s (%s, %p): ", + fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(), + nonconst->GetComponentID(), this); + iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/)); + va_end(args); + + return iResult; +}