]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTDataBuffer.cxx
adding class for handling of CTP information
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataBuffer.cxx
index 5825dd55fd46c5b8b28a0ba359559728014fe63a..a057783b841f528ea724c1736063e922906fe45e 100644 (file)
@@ -1,20 +1,20 @@
 // $Id$
 
-/**************************************************************************
- * This file is property of and copyright by the ALICE HLT Project        * 
- * ALICE Experiment at CERN, All rights reserved.                         *
- *                                                                        *
- * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
- *                  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.                  *
- **************************************************************************/
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+//*                  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   AliHLTDataBuffer.cxx
     @author Matthias Richter
     @brief  Handling of Data Buffers for HLT components.
 */
 
-// 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 __GNUC__>= 3
 using namespace std;
 #endif
@@ -77,6 +71,7 @@ AliHLTUInt32_t AliHLTDataBuffer::fgMargin=1024;
 AliHLTLogging AliHLTDataBuffer::fgLogging;
 const Int_t AliHLTDataBuffer::fgkSafetyPatternSize=16;
 const char AliHLTDataBuffer::fgkSafetyPattern[]={0x28, 0x63, 0x29, 0x4d, 0x52, 0x49, 0x43, 0x48, 0x54, 0x45, 0x52, 0x20, 0x32, 0x30, 0x30, 0x37};
+AliHLTUInt32_t AliHLTDataBuffer::fgEventCount=0;
 
 AliHLTDataBuffer::~AliHLTDataBuffer()
 {
@@ -154,8 +149,7 @@ int AliHLTDataBuffer::FindMatchingDataSegments(const AliHLTComponent* pConsumer,
     while (segment!=fSegments.end()) {
       AliHLTComponentDataTypeList::iterator type=dtlist.begin();
       while (type!=dtlist.end()) {
-       if ((*segment).fDataType==(*type) ||
-           (*type)==kAliHLTAnyDataType) {
+       if ((*segment).fDataType==(*type)) {
          tgtList.push_back(*segment);
          iResult++;
          break;
@@ -227,7 +221,11 @@ int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponen
          iResult=-EBADF;
        }
       } else {
-       HLTError("component %p is not a data consumer of data buffer %s", pConsumer, this);
+       if (!FindConsumer(pConsumer)) {
+         HLTError("component %p is not a data consumer of data buffer %p", pConsumer, this);
+       } else {
+         HLTError("component %p is a valid data consumer of data buffer %p, but did not release it's buffer subscription", pConsumer, this);
+       }
        iResult=-ENOENT;
       }
     } else {
@@ -254,7 +252,7 @@ int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc,
     AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers);
     if (pDesc) {
       if ((iResult=pDesc->CheckActiveDataSegment(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize)))!=1) {
-       HLTWarning("data segment missmatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
+       HLTWarning("data segment mismatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
        // TODO: appropriate error handling, but so far optional
        iResult=0;
       } else {
@@ -262,6 +260,39 @@ int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc,
       }
       if (GetNofPendingConsumers()==0 && fForwardedSegments.size()>0) {
        // last consumer, release forwarded segments
+       ReleaseForwardedBlock(pBlockDesc, pOwnerTask);
+      }
+      pBlockDesc->fOffset=0;
+      pBlockDesc->fPtr=NULL;
+      pBlockDesc->fSize=0;
+      if (pDesc->GetNofActiveSegments()==0) {
+       if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
+         if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) {
+           // this is the last consumer, reset the consumer list and release the raw buffer
+           ResetDataBuffer();
+         }
+       } else {
+         HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
+         iResult=-EACCES;
+       }
+      }
+    } else {
+      HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this);
+      iResult=-ENOENT;
+    }
+  } else {
+    HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
+    iResult=-EINVAL;
+  }
+  return iResult;
+}
+
+int AliHLTDataBuffer::ReleaseForwardedBlock(AliHLTComponentBlockData* pBlockDesc,
+                                           const AliHLTTask* pOwnerTask)
+{
+  // see header file for function documentation
+  int iResult=0;
+  if (pBlockDesc && pOwnerTask) {
        assert(fForwardedSegments.size()==fForwardedSegmentSources.size());
        AliHLTDataSegmentList::iterator segment=fForwardedSegments.begin();
        AliHLTTaskPList::iterator src=fForwardedSegmentSources.begin();
@@ -288,27 +319,8 @@ int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc,
            break;
          }
        }
-      }
-      pBlockDesc->fOffset=0;
-      pBlockDesc->fPtr=NULL;
-      pBlockDesc->fSize=0;
-      if (pDesc->GetNofActiveSegments()==0) {
-       if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
-         if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) {
-           // this is the last consumer, reset the consumer list and release the raw buffer
-           ResetDataBuffer();
-         }
-       } else {
-         HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
-         iResult=-EACCES;
-       }
-      }
-    } else {
-      HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this);
-      iResult=-ENOENT;
-    }
   } else {
-    HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
+    HLTError("inavalid parameter: pBlockDesc=%p pOwnerTask=%p", pBlockDesc, pOwnerTask);
     iResult=-EINVAL;
   }
   return iResult;
@@ -358,7 +370,8 @@ int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData*
          if (arrayBlockData[i].fPtr==NULL ||
              arrayBlockData[i].fPtr==*fpBuffer) {
            arrayBlockData[i].fPtr=*fpBuffer;
-           if (arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->GetUsedSize()) {
+           if ((arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->GetUsedSize()) ||
+               ((arrayBlockData[i].fOffset==~(AliHLTUInt32_t)0) && arrayBlockData[i].fSize==0)) {
              segment.fSegmentOffset=arrayBlockData[i].fOffset;
              segment.fPtr=(AliHLTUInt8_t*)arrayBlockData[i].fPtr;
              segment.fSegmentSize=arrayBlockData[i].fSize;
@@ -383,7 +396,7 @@ int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData*
        iResult=-EINVAL;
       }
     } else {
-      HLTFatal("internal data structur missmatch");
+      HLTFatal("internal data structur mismatch");
       iResult=-EFAULT;
     }
   } else {
@@ -396,14 +409,14 @@ int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData*
 int AliHLTDataBuffer::IsEmpty()
 {
   // see header file for function documentation
-  int iResult=fpBuffer==NULL || GetNofSegments()==0;
+  int iResult=(fpBuffer==NULL && fForwardedSegments.size()==0) || GetNofSegments()==0;
   return iResult;
 }
 
 int AliHLTDataBuffer::GetNofSegments()
 {
   // see header file for function documentation
-  int iResult=fSegments.size();
+  int iResult=fSegments.size() + fForwardedSegments.size();
   return iResult;
 }
 
@@ -505,21 +518,46 @@ int AliHLTDataBuffer::DeleteRawBuffers()
 {
   // see header file for function documentation
   int iResult=0;
-//   int iTotalSize=0;
-//   int iCount=fgFreeBuffers.size()+fgActiveBuffers.size();
+#ifdef ALIHLTSYSTEM_PROFILING
+  int iTotalSize=0;
+  int iCount=fgFreeBuffers.size()+fgActiveBuffers.size();
+#endif //ALIHLTSYSTEM_PROFILING
   AliHLTRawBufferPList::iterator buffer;;
   while ((buffer=fgFreeBuffers.begin())!=fgFreeBuffers.end()) {
-//     iTotalSize+=(*buffer)->GetTotalSize();
+#ifdef ALIHLTSYSTEM_PROFILING
+    iTotalSize+=(*buffer)->GetTotalSize();
+#endif //ALIHLTSYSTEM_PROFILING
     delete *buffer;
     fgFreeBuffers.erase(buffer);
   }
   while ((buffer=fgActiveBuffers.begin())!=fgActiveBuffers.end()) {
-//     iTotalSize+=(*buffer)->GetTotalSize();
+#ifdef ALIHLTSYSTEM_PROFILING
+    iTotalSize+=(*buffer)->GetTotalSize();
+#endif //ALIHLTSYSTEM_PROFILING
     fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "request to delete active raw buffer container (raw buffer %p, size %d)", (*buffer)->GetPointer(), (*buffer)->GetTotalSize());
     delete *buffer;
     fgActiveBuffers.erase(buffer);
   }
-//   fgLogging.Logging(kHLTLogInfo, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "Total memory allocation: %d byte in %d buffers", iTotalSize, iCount);
+#ifdef ALIHLTSYSTEM_PROFILING
+  fgLogging.Logging(kHLTLogImportant, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "Total memory allocation: %d byte in %d buffers", iTotalSize, iCount);
+#endif //ALIHLTSYSTEM_PROFILING
+  return iResult;
+}
+
+int AliHLTDataBuffer::PrintStatistics() 
+{
+  // see header file for function documentation
+  int iResult=0;
+  int iFree=0;
+  int iActive=0;
+  AliHLTRawBufferPList::iterator buffer;;
+  for (buffer=fgFreeBuffers.begin(); buffer!=fgFreeBuffers.end(); buffer++) {
+    iFree+=(*buffer)->GetTotalSize();
+  }
+  for (buffer=fgActiveBuffers.begin(); buffer!=fgActiveBuffers.end(); buffer++) {
+    iActive+=(*buffer)->GetTotalSize();
+  }
+  fgLogging.Logging(kHLTLogInfo, "AliHLTDataBuffer::PrintStatistics", "data buffer handling", "Total memory allocation: %d byte; %d free buffers (%d byte) - %d active buffers (%d byte) ", iFree+iActive, fgFreeBuffers.size(), iFree, fgActiveBuffers.size(), iActive);
   return iResult;
 }
 
@@ -569,7 +607,7 @@ int AliHLTDataBuffer::ResetDataBuffer()
   desc=fActiveConsumers.begin();
   while (desc!=fActiveConsumers.end()) {
     AliHLTConsumerDescriptor* pDesc=*desc;
-    HLTWarning("consumer %p was not released", pDesc);
+    HLTWarning("consumer %p (%s) was not released", pDesc, pDesc->GetComponent()?pDesc->GetComponent()->GetComponentID():"### invalid component ###");
     fActiveConsumers.erase(desc);
     desc=fActiveConsumers.begin();
     fConsumers.push_back(pDesc);
@@ -659,7 +697,7 @@ int AliHLTDataBuffer::CleanupConsumerList()
   return iResult;
 }
 
-int AliHLTDataBuffer::FindConsumer(AliHLTComponent* pConsumer, int bAllLists)
+int AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, int bAllLists)
 {
   // see header file for function documentation
   AliHLTConsumerDescriptorPList::iterator desc=fConsumers.begin();
@@ -689,7 +727,8 @@ AliHLTDataBuffer::AliHLTRawBuffer::AliHLTRawBuffer(AliHLTUInt32_t size)
   :
   fSize(0),
   fTotalSize(size),
-  fPtr(static_cast<AliHLTUInt8_t*>(malloc(size)))
+  fPtr(static_cast<AliHLTUInt8_t*>(malloc(size))),
+  fLastEventCount(0)
 {
   // see header file for class documentation
   // or
@@ -745,6 +784,7 @@ AliHLTUInt8_t* AliHLTDataBuffer::AliHLTRawBuffer::UseBuffer(AliHLTUInt32_t size)
   // see header file for function documentation
   if (size>0 && fTotalSize>=size) {
     fSize=size;
+    fLastEventCount=AliHLTDataBuffer::fgEventCount;
     return fPtr;
   }
   return NULL;
@@ -753,7 +793,12 @@ AliHLTUInt8_t* AliHLTDataBuffer::AliHLTRawBuffer::UseBuffer(AliHLTUInt32_t size)
 int AliHLTDataBuffer::AliHLTRawBuffer::CheckSize(AliHLTUInt32_t size) const
 {
   // see header file for function documentation
-  return fTotalSize>=size && ((fTotalSize-size)<fgMargin);
+  if (fTotalSize<size) return 0;
+  unsigned adjust=0;
+  if (fLastEventCount+1<AliHLTDataBuffer::fgEventCount) {
+    adjust=AliHLTDataBuffer::fgEventCount-fLastEventCount;
+  }
+  return (adjust>2) || ((fTotalSize-size)<(fgMargin<<adjust));
 }
 
 int AliHLTDataBuffer::AliHLTRawBuffer::Reset()