LCOV - code coverage report
Current view: top level - HLT/BASE - AliHLTDataBuffer.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 9 669 1.3 %
Date: 2016-06-14 17:26:59 Functions: 6 79 7.6 %

          Line data    Source code
       1             : // $Id$
       2             : 
       3             : //**************************************************************************
       4             : //* This file is property of and copyright by the                          * 
       5             : //* ALICE Experiment at CERN, All rights reserved.                         *
       6             : //*                                                                        *
       7             : //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
       8             : //*                  for The ALICE HLT Project.                            *
       9             : //*                                                                        *
      10             : //* Permission to use, copy, modify and distribute this software and its   *
      11             : //* documentation strictly for non-commercial purposes is hereby granted   *
      12             : //* without fee, provided that the above copyright notice appears in all   *
      13             : //* copies and that both the copyright notice and this permission notice   *
      14             : //* appear in the supporting documentation. The authors make no claims     *
      15             : //* about the suitability of this software for any purpose. It is          *
      16             : //* provided "as is" without express or implied warranty.                  *
      17             : //**************************************************************************
      18             : 
      19             : //  @file   AliHLTDataBuffer.cxx
      20             : //  @author Matthias Richter
      21             : //  @date   
      22             : //  @brief  Handling of Data Buffers for HLT components.
      23             : //  @note   Only used in the AliRoot framework
      24             : 
      25             : #include "AliHLTDataBuffer.h"
      26             : #include "AliHLTConsumerDescriptor.h"
      27             : #include "AliHLTComponent.h"
      28             : #include "AliHLTTask.h"
      29             : #include <cerrno>
      30             : #include <cassert>
      31             : //#include <string>
      32             : //#include "AliHLTSystem.h"
      33             : 
      34             : using std::cout;
      35             : 
      36             : /** ROOT macro for the implementation of ROOT specific class methods */
      37         126 : ClassImp(AliHLTDataBuffer)
      38             : 
      39           0 : AliHLTDataBuffer::AliHLTDataBuffer()
      40             :   :
      41           0 :   fSegments(),
      42           0 :   fConsumers(),
      43           0 :   fActiveConsumers(),
      44           0 :   fReleasedConsumers(),
      45           0 :   fpBuffer(NULL),
      46           0 :   fFlags(0),
      47           0 :   fForwardedSegmentSources(),
      48           0 :   fForwardedSegments()
      49           0 : {
      50             :   // see header file for class documentation
      51             :   // or
      52             :   // refer to README to build package
      53             :   // or
      54             :   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
      55           0 :   fSegments.empty();
      56           0 :   fConsumers.empty();
      57           0 :   fActiveConsumers.empty();
      58           0 :   fReleasedConsumers.empty();
      59           0 :   fgNofInstances++;
      60           0 : }
      61             : 
      62             : int AliHLTDataBuffer::fgNofInstances=0;
      63         126 : AliHLTDataBuffer::AliHLTRawBufferPList AliHLTDataBuffer::fgFreeBuffers;
      64         126 : AliHLTDataBuffer::AliHLTRawBufferPList AliHLTDataBuffer::fgActiveBuffers;
      65             : AliHLTUInt32_t AliHLTDataBuffer::fgMargin=1024;
      66         126 : AliHLTLogging AliHLTDataBuffer::fgLogging;
      67             : const Int_t AliHLTDataBuffer::fgkSafetyPatternSize=16;
      68             : const char AliHLTDataBuffer::fgkSafetyPattern[]={0x28, 0x63, 0x29, 0x4d, 0x52, 0x49, 0x43, 0x48, 0x54, 0x45, 0x52, 0x20, 0x32, 0x30, 0x30, 0x37};
      69             : AliHLTUInt32_t AliHLTDataBuffer::fgEventCount=0;
      70             : 
      71           0 : AliHLTDataBuffer::~AliHLTDataBuffer()
      72           0 : {
      73             :   // see header file for function documentation
      74           0 :   CleanupConsumerList();
      75             : 
      76           0 :   if (--fgNofInstances<=0) {
      77           0 :     DeleteRawBuffers();
      78             :   }
      79           0 : }
      80             : 
      81             : int AliHLTDataBuffer::SetConsumer(AliHLTComponent* pConsumer)
      82             : {
      83             :   // see header file for function documentation
      84             :   int iResult=0;
      85           0 :   if (pConsumer) {
      86           0 :     if (FindConsumer(pConsumer)) {
      87           0 :       HLTWarning("consumer %s (%p) already set to data buffer %p", pConsumer->GetComponentID(), pConsumer, this);
      88             :     }
      89           0 :     AliHLTConsumerDescriptor* pDesc=new AliHLTConsumerDescriptor(pConsumer);
      90           0 :     if (pDesc) {
      91           0 :       fConsumers.push_back(pDesc);
      92             :       HLTDebug("set consumer %s (%p) to data buffer %p", pConsumer->GetComponentID(), pConsumer, this);
      93           0 :     } else {
      94           0 :       HLTError("memory allocation failed");
      95             :       iResult=-ENOMEM;
      96             :     }
      97           0 :   } else {
      98           0 :     HLTError("invalid parameter: consumer component (nil)");
      99             :     iResult=-EINVAL;
     100             :   }
     101           0 :   return iResult;
     102           0 : }
     103             : 
     104             : int AliHLTDataBuffer::FindMatchingDataBlocks(const AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
     105             : {
     106             :   // see header file for function documentation
     107             :   int iResult=0;
     108           0 :   if (pConsumer) {
     109           0 :     AliHLTDataSegmentList segments;
     110           0 :     if ((iResult=FindMatchingDataSegments(pConsumer, segments))>=0) {
     111           0 :       if (tgtList) {
     112           0 :         AliHLTDataSegmentList::iterator segment=segments.begin();
     113           0 :         while (segment!=segments.end()) {
     114           0 :           tgtList->push_back((*segment).fDataType);
     115           0 :           segment++;
     116             :         }
     117           0 :       }
     118           0 :       iResult=segments.size();
     119           0 :     }
     120           0 :   } else {
     121             :     iResult=-EINVAL;
     122             :   }
     123           0 :   return iResult;
     124           0 : }
     125             : 
     126             : int AliHLTDataBuffer::FindMatchingDataSegments(const AliHLTComponent* /*pConsumer*/,
     127             :                                                AliHLTDataSegmentList& tgtList)
     128             : {
     129             :   // see header file for function documentation
     130             :   int iResult=0;
     131             : 
     132             :   // Matthias 26.09.2007 relax the restriction to matching data blocks
     133             :   // all blocks are passed to the consumer, which is the policy also in
     134             :   // PubSub
     135           0 :   tgtList.assign(fSegments.begin(), fSegments.end());
     136             : 
     137             :   // add all forwarded blocks
     138           0 :   tgtList.insert(tgtList.begin(), fForwardedSegments.begin(), fForwardedSegments.end());
     139           0 :   iResult=tgtList.size();
     140           0 :   return iResult;
     141             : }
     142             : 
     143             : int AliHLTDataBuffer::Subscribe(const AliHLTComponent* pConsumer, AliHLTComponentBlockDataList& blockDescList)
     144             : {
     145             :   // see header file for function documentation
     146             :   int iResult=0;
     147           0 :   if (pConsumer) {
     148             :     if (1/*fpBuffer*/) {
     149           0 :       AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fConsumers);
     150           0 :       if (pDesc) {
     151           0 :         AliHLTDataSegmentList tgtList;
     152             :         // Matthias 26.07.2007 AliHLTSystem should behave the same way as PubSub
     153             :         // so it does not matter if there are matching data types or not, unless
     154             :         // we implement such a check in PubSub
     155           0 :         if ((iResult=FindMatchingDataSegments(pConsumer, tgtList))>=0) {
     156           0 :           AliHLTDataSegmentList::iterator segment=tgtList.begin();
     157           0 :           while (segment!=tgtList.end()) {
     158             :             // fill the block data descriptor
     159           0 :             AliHLTComponentBlockData bd;
     160           0 :             AliHLTComponent::FillBlockData(bd);
     161             :             // This models the behavior of PubSub.
     162             :             // For incoming data blocks, fOffset must be ignored by the
     163             :             // processing component. It is set for bookkeeping in the framework.
     164             :             // fPtr always points to the beginning of the data.
     165           0 :             bd.fOffset=0;
     166           0 :             AliHLTUInt8_t* pTgt=*segment;
     167           0 :             bd.fPtr=reinterpret_cast<void*>(pTgt);
     168           0 :             bd.fSize=(*segment).fSegmentSize;
     169           0 :             bd.fDataType=(*segment).fDataType;
     170           0 :             bd.fSpecification=(*segment).fSpecification;
     171           0 :             blockDescList.push_back(bd);
     172           0 :             pDesc->SetActiveDataSegment(*segment);
     173             :             HLTDebug("component %p (%s) subscribed to segment offset %d size %d data type %s %#x", 
     174             :                      pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), bd.fOffset,
     175             :                      bd.fSize, (AliHLTComponent::DataType2Text(bd.fDataType)).c_str(), 
     176             :                      bd.fSpecification);
     177           0 :             segment++;
     178           0 :           }
     179             :           // move this consumer to the active list
     180           0 :           if (tgtList.size()==0) {
     181           0 :             ChangeConsumerState(pDesc, fConsumers, fReleasedConsumers);
     182             :             HLTDebug("no input data for component %p (%s) available", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID());
     183           0 :           } else if (ChangeConsumerState(pDesc, fConsumers, fActiveConsumers)>=0) {
     184             :             HLTDebug("component %p (%s) subscribed to data buffer %p", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID(), this);
     185             :           } else {
     186             :             // TODO: cleanup the consumer descriptor correctly
     187           0 :             segment=tgtList.begin();
     188           0 :             while (segment!=tgtList.end()) {
     189           0 :               blockDescList.pop_back();
     190           0 :               segment++;
     191             :             }
     192           0 :             HLTError("can not activate consumer %p for data buffer %p", pConsumer, this);
     193             :             iResult=-EACCES;
     194             :           }
     195           0 :         } else {
     196           0 :           HLTError("unresolved data segment(s) for component %p (%s)", pConsumer, ((AliHLTComponent*)pConsumer)->GetComponentID());
     197             :           iResult=-EBADF;
     198             :         }
     199           0 :       } else {
     200           0 :         if (!FindConsumer(pConsumer)) {
     201           0 :           HLTError("component %p is not a data consumer of data buffer %p", pConsumer, this);
     202             :         } else {
     203           0 :           HLTError("component %p is a valid data consumer of data buffer %p, but did not release it's buffer subscription", pConsumer, this);
     204             :         }
     205             :         iResult=-ENOENT;
     206             :       }
     207             :     } else {
     208             :       // Matthias 26.07.2007 until now, data had to be present for successful subscription
     209             :       // in order to be consistent with the PubSub framework, this restiction has been
     210             :       // removed
     211             :       //HLTError("data buffer %p is empty", this);
     212             :       //iResult=-ENODATA;
     213             :     }
     214           0 :   } else {
     215           0 :     HLTError("invalid parameter");
     216             :     iResult=-EINVAL;
     217             :   }
     218           0 :   return iResult;
     219           0 : }
     220             : 
     221             : int AliHLTDataBuffer::Release(AliHLTComponentBlockData* pBlockDesc,
     222             :                               const AliHLTComponent* pConsumer,
     223             :                               const AliHLTTask* pOwnerTask)
     224             : {
     225             :   // see header file for function documentation
     226             :   int iResult=0;
     227           0 :   if (pBlockDesc && pConsumer) {
     228           0 :     AliHLTConsumerDescriptor* pDesc=FindConsumer(pConsumer, fActiveConsumers);
     229           0 :     if (pDesc) {
     230           0 :       if ((iResult=pDesc->CheckActiveDataSegment(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize)))!=1) {
     231           0 :         HLTWarning("data segment mismatch, component %p has not subscribed to a segment with offset %#x and size %d", pConsumer, pBlockDesc->fOffset, pBlockDesc->fSize);
     232             :         // TODO: appropriate error handling, but so far optional
     233             :         iResult=0;
     234           0 :       } else {
     235           0 :         pDesc->ReleaseActiveDataSegment(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize));
     236             :       }
     237           0 :       if (GetNofPendingConsumers()==0 && fForwardedSegments.size()>0) {
     238             :         // last consumer, release forwarded segments
     239           0 :         ReleaseForwardedBlock(pBlockDesc, pOwnerTask);
     240           0 :       }
     241           0 :       pBlockDesc->fOffset=0;
     242           0 :       pBlockDesc->fPtr=NULL;
     243           0 :       pBlockDesc->fSize=0;
     244           0 :       if (pDesc->GetNofActiveSegments()==0) {
     245           0 :         if ((iResult=ChangeConsumerState(pDesc, fActiveConsumers, fReleasedConsumers))>=0) {
     246           0 :           if (GetNofActiveConsumers()==0 && GetNofPendingConsumers()==0) {
     247             :             // this is the last consumer, reset the consumer list and release the raw buffer
     248           0 :             ResetDataBuffer();
     249           0 :           }
     250             :         } else {
     251           0 :           HLTError("can not deactivate consumer %p for data buffer %p", pConsumer, this);
     252             :           iResult=-EACCES;
     253             :         }
     254             :       }
     255             :     } else {
     256           0 :       HLTWarning("component %p has currently not subscribed to the data buffer %p", pConsumer, this);
     257             :       iResult=-ENOENT;
     258             :     }
     259           0 :   } else {
     260           0 :     HLTError("inavalid parameter: pBlockDesc=%p pConsumer=%p", pBlockDesc, pConsumer);
     261             :     iResult=-EINVAL;
     262             :   }
     263           0 :   return iResult;
     264           0 : }
     265             : 
     266             : int AliHLTDataBuffer::ReleaseForwardedBlock(AliHLTComponentBlockData* pBlockDesc,
     267             :                                             const AliHLTTask* pOwnerTask)
     268             : {
     269             :   // see header file for function documentation
     270             :   int iResult=0;
     271           0 :   if (pBlockDesc && pOwnerTask) {
     272           0 :         assert(fForwardedSegments.size()==fForwardedSegmentSources.size());
     273           0 :         AliHLTDataSegmentList::iterator segment=fForwardedSegments.begin();
     274           0 :         AliHLTTaskPList::iterator src=fForwardedSegmentSources.begin();
     275             :         //HLTDebug("%p checking forwarded segments", this);
     276           0 :         for (; segment!=fForwardedSegments.end(); segment++, src++) {
     277             :           //HLTDebug("segment ptr=%p offset=%d size=%d\n"
     278             :           //   "block ptr=%p offset=%d size=%d", (*segment).fPtr, (*segment).fSegmentOffset, (*segment).fSegmentSize, pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize);
     279           0 :           if ((*segment)==AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize)) {
     280             :             //HLTDebug("release segment of task %p", *src);
     281           0 :             assert((*src)!=NULL);
     282           0 :             if ((*src)!=NULL) {
     283           0 :               if ((*src)->Release(pBlockDesc, pOwnerTask)>=0) {
     284             :                 HLTDebug("task %s (%p) released forwarded segment %p size %d of task %s (%p)",
     285             :                          pOwnerTask->GetName(), pOwnerTask, (*segment).GetPtr(), (*segment).GetSize(),
     286             :                          (*src)->GetName(), *src);
     287             :               } else {
     288           0 :                 HLTError("task %s (%p) failed releasing forwarded segment %p size %d of task %s (%p)",
     289             :                          pOwnerTask->GetName(), pOwnerTask, (*segment).GetPtr(), (*segment).GetSize(),
     290             :                          (*src)->GetName(), *src);
     291             :               }
     292             :             }
     293           0 :             fForwardedSegments.erase(segment);
     294           0 :             fForwardedSegmentSources.erase(src);
     295           0 :             break;
     296             :           }
     297             :         }
     298           0 :   } else {
     299           0 :     HLTError("inavalid parameter: pBlockDesc=%p pOwnerTask=%p", pBlockDesc, pOwnerTask);
     300             :     iResult=-EINVAL;
     301             :   }
     302           0 :   return iResult;
     303             : }
     304             : 
     305             : int AliHLTDataBuffer::Forward(AliHLTTask* pSrcTask, AliHLTComponentBlockData* pBlockDesc)
     306             : {
     307             :   // see header file for function documentation
     308           0 :   if (pSrcTask==NULL || pBlockDesc==NULL) return -EINVAL;
     309           0 :   assert(fForwardedSegments.size()==fForwardedSegmentSources.size());
     310           0 :   if (fForwardedSegments.size()!=fForwardedSegmentSources.size()) return -EFAULT;
     311           0 :   fForwardedSegmentSources.push_back(pSrcTask);
     312           0 :   fForwardedSegments.push_back(AliHLTDataSegment(pBlockDesc->fPtr, pBlockDesc->fOffset, pBlockDesc->fSize, pBlockDesc->fDataType, pBlockDesc->fSpecification));
     313           0 :   return 0;
     314           0 : }
     315             : 
     316             : AliHLTUInt8_t* AliHLTDataBuffer::GetTargetBuffer(int iMinSize)
     317             : {
     318             :   // see header file for function documentation
     319             :   AliHLTUInt8_t* pTargetBuffer=NULL;
     320           0 :   if (fpBuffer!=NULL) {
     321           0 :     HLTWarning("data buffer not properly reset, possible memory leak\n");
     322             :   }
     323           0 :   fpBuffer=CreateRawBuffer(iMinSize);
     324           0 :   if (fpBuffer) {
     325           0 :     pTargetBuffer=*fpBuffer;
     326           0 :   } else {
     327           0 :     HLTError("can not create raw buffer");
     328             :   }
     329           0 :   return pTargetBuffer;
     330             : }
     331             : 
     332             : int AliHLTDataBuffer::SetSegments(AliHLTUInt8_t* pTgt, AliHLTComponentBlockData* arrayBlockData, int iSize)
     333             : {
     334             :   // see header file for function documentation
     335             :   int iResult=0;
     336           0 :   if (pTgt && arrayBlockData && iSize>=0) {
     337           0 :     if (fpBuffer) {
     338           0 :       if (*fpBuffer==pTgt) {
     339           0 :         AliHLTDataBuffer::AliHLTDataSegment segment;
     340             :         AliHLTUInt32_t maxSize=0;
     341           0 :         for (int i=0; i<iSize; i++) {
     342             :           // This function has to model the behavior of PubSub
     343             :           // For output blocks only the fOffset value is used, this must be the offset
     344             :           // relative to the output pointer. fPtr must be either NULL or the output
     345             :           // pointer. In either case it is 'ignored' and set to the beginning of the
     346             :           // data buffer
     347           0 :           if (arrayBlockData[i].fPtr==NULL ||
     348           0 :               arrayBlockData[i].fPtr==*fpBuffer) {
     349           0 :             arrayBlockData[i].fPtr=*fpBuffer;
     350           0 :             if ((arrayBlockData[i].fOffset+arrayBlockData[i].fSize<=fpBuffer->GetUsedSize()) ||
     351           0 :                 ((arrayBlockData[i].fOffset==~(AliHLTUInt32_t)0) && arrayBlockData[i].fSize==0)) {
     352           0 :               segment.fSegmentOffset=arrayBlockData[i].fOffset;
     353           0 :               segment.fPtr=(AliHLTUInt8_t*)arrayBlockData[i].fPtr;
     354           0 :               segment.fSegmentSize=arrayBlockData[i].fSize;
     355           0 :               segment.fDataType=arrayBlockData[i].fDataType;
     356           0 :               segment.fSpecification=arrayBlockData[i].fSpecification;
     357           0 :               fSegments.push_back(segment);
     358             :               HLTDebug("set segment %s with size %d at offset %d", AliHLTComponent::DataType2Text(segment.fDataType).data(), segment.fSegmentSize, segment.fSegmentOffset);
     359             : 
     360             :               // find the actual size of the data
     361           0 :               if ((arrayBlockData[i].fOffset!=~(AliHLTUInt32_t)0) &&
     362           0 :                   arrayBlockData[i].fOffset+arrayBlockData[i].fSize>maxSize) {
     363             :                 maxSize=arrayBlockData[i].fOffset+arrayBlockData[i].fSize;
     364           0 :               }
     365             :             } else {
     366           0 :               HLTError("block data specification %#d (%s) exceeds size of data buffer", i, AliHLTComponent::DataType2Text(arrayBlockData[i].fDataType).data());
     367           0 :               HLTError("block offset=%d, block size=%d, buffer size=%d", arrayBlockData[i].fOffset, arrayBlockData[i].fSize, fpBuffer->GetUsedSize());
     368             :               iResult=-E2BIG;
     369             :             }
     370             :           } else {
     371           0 :             HLTError("invalid pointer (%p) in block data specification (buffer %p size %d)."
     372             :                      "please note: for output blocks only the fOffset value is valid and must "
     373             :                      "be relative to the output buffer", arrayBlockData[i].fPtr, fpBuffer->GetPointer(), fpBuffer->GetUsedSize());
     374             :             iResult=-ERANGE;
     375             :           }
     376             :         }
     377             :         // to be enabled if unit test is ready
     378           0 :         iResult=SetRawBufferDataSize(fpBuffer, maxSize);        
     379           0 :       } else {
     380           0 :         HLTError("this data buffer (%p) does not match the internal data buffer %p of raw buffer %p", pTgt, fpBuffer->GetPointer(), fpBuffer);
     381             :         iResult=-EINVAL;
     382             :       }
     383             :     } else {
     384           0 :       HLTFatal("internal data structur mismatch");
     385             :       iResult=-EFAULT;
     386             :     }
     387             :   } else {
     388           0 :     HLTError("invalid parameter: pTgtBuffer=%p arrayBlockData=%p", pTgt, arrayBlockData);
     389             :     iResult=-EINVAL;
     390             :   }
     391           0 :   return iResult;
     392           0 : }
     393             : 
     394             : int AliHLTDataBuffer::IsEmpty()
     395             : {
     396             :   // see header file for function documentation
     397           0 :   int iResult=(fpBuffer==NULL && fForwardedSegments.size()==0) || GetNofSegments()==0;
     398           0 :   return iResult;
     399             : }
     400             : 
     401             : int AliHLTDataBuffer::GetNofSegments() const
     402             : {
     403             :   // see header file for function documentation
     404           0 :   int iResult=fSegments.size() + fForwardedSegments.size();
     405           0 :   return iResult;
     406             : }
     407             : 
     408             : int AliHLTDataBuffer::GetNofConsumers() const
     409             : {
     410             :   // see header file for function documentation
     411           0 :   int iResult=fConsumers.size() + GetNofActiveConsumers() + fReleasedConsumers.size();
     412           0 :   return iResult;
     413             : }
     414             : 
     415             : int AliHLTDataBuffer::GetNofPendingConsumers() const
     416             : {
     417             :   // see header file for function documentation
     418           0 :   int iResult=fConsumers.size();
     419           0 :   return iResult;
     420             : }
     421             : 
     422             : int AliHLTDataBuffer::GetNofActiveConsumers() const
     423             : {
     424             :   // see header file for function documentation
     425           0 :   int iResult=fActiveConsumers.size();
     426           0 :   return iResult;
     427             : }
     428             : 
     429             : AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::CreateRawBuffer(AliHLTUInt32_t size)
     430             : {
     431             :   // see header file for function documentation
     432             :   AliHLTRawBuffer* pRawBuffer=NULL;
     433           0 :   unsigned int reqSize=size+fgkSafetyPatternSize;
     434           0 :   pRawBuffer=AliHLTDataBuffer::AliHLTRawPage::GlobalAlloc(reqSize);
     435           0 :   if (pRawBuffer) {
     436           0 :     pRawBuffer->UseBuffer(size);
     437           0 :   }
     438           0 :   if (pRawBuffer!=NULL && fgkSafetyPatternSize>0) {
     439             :     //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::CreateRawBuffer", "data buffer handling", "writing safety pattern to %p offset %d", (*buffer)->GetPointer(), (*buffer)->GetUsedSize());
     440           0 :     pRawBuffer->WritePattern(fgkSafetyPattern, fgkSafetyPatternSize);
     441           0 :   }
     442           0 :   return pRawBuffer;
     443             : }
     444             : 
     445             : int AliHLTDataBuffer::SetRawBufferDataSize(AliHLTRawBuffer* pBuffer, AliHLTUInt32_t size) const
     446             : {
     447             :   // see header file for function documentation
     448             :   int iResult=0;
     449           0 :   if (!pBuffer) return -EINVAL;
     450           0 :   if (size>pBuffer->GetUsedSize()) {
     451           0 :     HLTError("indicated data size %d exceeds data buffer %p (%d)", size, pBuffer->GetPointer(), pBuffer->GetUsedSize());
     452           0 :     return -ENOSPC;
     453             :   }
     454             :   if (fgkSafetyPatternSize>0) {
     455           0 :     if (pBuffer->CheckPattern(fgkSafetyPattern, fgkSafetyPatternSize)) {
     456           0 :       HLTError("potential memory corruption: component has written beyond end of data buffer %p size %d", pBuffer->GetPointer(), pBuffer->GetUsedSize());
     457             :     }
     458             :   }
     459             :   // shrink the buffer and write new pattern at the end
     460           0 :   AliHLTDataBuffer::AliHLTRawPage* rawpage=AliHLTDataBuffer::AliHLTRawPage::FindPage(pBuffer);
     461           0 :   if (rawpage) {
     462           0 :     pBuffer->UseBuffer(size);
     463           0 :     if (rawpage->SetSize(pBuffer, size+fgkSafetyPatternSize)==0) {
     464             :       // nothing to do
     465             :     } else {
     466           0 :       fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::SetRawBufferDataSize", "data buffer handling", "failed to set size for raw buffer %p", pBuffer);
     467             :       iResult=-EFAULT;
     468             :     }
     469             :   } else {
     470           0 :     fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::SetRawBufferDataSize", "data buffer handling", "can not find raw page for buffer %p", pBuffer);
     471             :     iResult=-ENOENT;
     472             :   }
     473             :   if (fgkSafetyPatternSize>0) {
     474           0 :     pBuffer->WritePattern(fgkSafetyPattern, fgkSafetyPatternSize);
     475             :   }
     476             :   return iResult;
     477           0 : }
     478             : 
     479             : int AliHLTDataBuffer::ReleaseRawBuffer(AliHLTRawBuffer* pBuffer)
     480             : {
     481             :   // see header file for function documentation
     482             :   int iResult=0;
     483           0 :   if (pBuffer) {
     484           0 :     AliHLTDataBuffer::AliHLTRawPage* rawpage=AliHLTDataBuffer::AliHLTRawPage::FindPage(pBuffer);
     485           0 :     if (rawpage)
     486             :     {
     487             :       if (fgkSafetyPatternSize>0) {
     488             :         //fgLogging.Logging(kHLTLogDebug, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "comparing safety pattern at %p offset %d", pBuffer->GetPointer(), reinterpret_cast<AliHLTUInt32_t>(pBuffer));
     489           0 :         if ((pBuffer)->CheckPattern(fgkSafetyPattern, fgkSafetyPatternSize)) {
     490           0 :           fgLogging.Logging(kHLTLogFatal, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "component has written beyond end of data buffer %p size %d", pBuffer->GetPointer(), pBuffer->GetUsedSize());
     491           0 :         }
     492             :       }
     493           0 :       pBuffer->Reset();
     494           0 :       if (rawpage->Free(pBuffer)==0) {
     495             :       } else {
     496           0 :         fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "failed to release raw buffer %p", pBuffer);
     497             :       }
     498             :     } else {
     499           0 :       fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "can not find raw page for buffer %p", pBuffer);
     500             :       iResult=-ENOENT;
     501             :     }
     502           0 :   } else {
     503           0 :     fgLogging.Logging(kHLTLogError, "AliHLTDataBuffer::ReleaseRawBuffer", "data buffer handling", "invalid parameter");
     504             :     iResult=-EINVAL;
     505             :   }
     506           0 :   return iResult;
     507             : }
     508             : 
     509             : 
     510             : int AliHLTDataBuffer::DeleteRawBuffers() 
     511             : {
     512             :   // see header file for function documentation
     513             :   int iResult=0;
     514             : #ifdef ALIHLTSYSTEM_PROFILING
     515             :   int iTotalSize=0;
     516             :   int iCount=fgFreeBuffers.size()+fgActiveBuffers.size();
     517             : #endif //ALIHLTSYSTEM_PROFILING
     518           0 :   AliHLTRawBufferPList::iterator buffer;;
     519           0 :   while ((buffer=fgFreeBuffers.begin())!=fgFreeBuffers.end()) {
     520             : #ifdef ALIHLTSYSTEM_PROFILING
     521             :     iTotalSize+=(*buffer)->GetTotalSize();
     522             : #endif //ALIHLTSYSTEM_PROFILING
     523           0 :     delete *buffer;
     524           0 :     fgFreeBuffers.erase(buffer);
     525             :   }
     526           0 :   while ((buffer=fgActiveBuffers.begin())!=fgActiveBuffers.end()) {
     527             : #ifdef ALIHLTSYSTEM_PROFILING
     528             :     iTotalSize+=(*buffer)->GetTotalSize();
     529             : #endif //ALIHLTSYSTEM_PROFILING
     530           0 :     fgLogging.Logging(kHLTLogWarning, "AliHLTDataBuffer::DeleteRawBuffer", "data buffer handling", "request to delete active raw buffer container (raw buffer %p, size %d)", (*buffer)->GetPointer(), (*buffer)->GetTotalSize());
     531           0 :     delete *buffer;
     532           0 :     fgActiveBuffers.erase(buffer);
     533             :   }
     534             : #ifdef ALIHLTSYSTEM_PROFILING
     535             :   fgLogging.Logging(kHLTLogImportant, "AliHLTDataBuffer::DeleteRawBuffer", "data buffer handling", "Total memory allocation: %d byte in %d buffers", iTotalSize, iCount);
     536             : #endif //ALIHLTSYSTEM_PROFILING
     537           0 :   return iResult;
     538           0 : }
     539             : 
     540             : int AliHLTDataBuffer::PrintStatistics() 
     541             : {
     542             :   // see header file for function documentation
     543             :   int iResult=0;
     544             :   int nofPages=0;
     545             :   AliHLTUInt32_t totalSize=0;
     546           0 :   for (AliHLTDataBuffer::AliHLTRawPage* rawpage=AliHLTDataBuffer::AliHLTRawPage::NextPage(NULL);
     547           0 :        rawpage!=NULL; 
     548           0 :        rawpage=AliHLTDataBuffer::AliHLTRawPage::NextPage(rawpage)) {
     549           0 :     nofPages++;
     550           0 :     totalSize+=rawpage->Size();
     551           0 :     if (fgLogging.CheckFilter(kHLTLogDebug)) rawpage->Print("");
     552             :   }
     553             :   //if (rawpage) rawpage->Print("global");
     554           0 :   fgLogging.Logging(kHLTLogInfo, "AliHLTDataBuffer::PrintStatistics", "data buffer handling", "total number of memory pages: %d   total size %d", nofPages, totalSize);
     555             : 
     556           0 :   return iResult;
     557             : }
     558             : 
     559             : AliHLTConsumerDescriptor* AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, AliHLTConsumerDescriptorPList &list) const
     560             : {
     561             :   // see header file for function documentation
     562             :   AliHLTConsumerDescriptor* pDesc=NULL;
     563           0 :   AliHLTConsumerDescriptorPList::iterator desc=list.begin();
     564           0 :   while (desc!=list.end() && pDesc==NULL) {
     565           0 :     if ((pConsumer==NULL || (*desc)->GetComponent()==pConsumer)) {
     566           0 :       pDesc=*desc;
     567           0 :     }
     568           0 :     desc++;
     569             :   }
     570           0 :   return pDesc;
     571           0 : }
     572             : 
     573             : int AliHLTDataBuffer::ResetDataBuffer() 
     574             : {
     575             :   // see header file for function documentation
     576             :   int iResult=0;
     577           0 :   AliHLTRawBuffer* pBuffer=fpBuffer;
     578           0 :   fpBuffer=NULL;
     579             : 
     580             :   // cleanup forwarded segment lists
     581           0 :   assert(fForwardedSegments.size()==0);
     582           0 :   fForwardedSegments.clear();
     583           0 :   fForwardedSegmentSources.clear();
     584             : 
     585             :   // cleanup consumer states
     586           0 :   AliHLTConsumerDescriptorPList::iterator desc;
     587             : //   if (GetNofPendingConsumers()>0) {
     588             : //     desc=fConsumers.begin();
     589             : //     while (desc!=fConsumers.end()) {
     590             : //       AliHLTComponent* pComp=(*desc)->GetComponent();
     591             : //       HLTError("internal error: consumer %p (%s %p) did not get data from data buffer %p", *desc, pComp?pComp->GetComponentID():"", pComp, this);
     592             : //       desc++;
     593             : //     }
     594             : //   }
     595           0 :   desc=fReleasedConsumers.begin();
     596           0 :   while (desc!=fReleasedConsumers.end()) {
     597           0 :     AliHLTConsumerDescriptor* pDesc=*desc;
     598           0 :     fReleasedConsumers.erase(desc);
     599           0 :     desc=fReleasedConsumers.begin();
     600           0 :     fConsumers.push_back(pDesc);
     601           0 :   }
     602           0 :   desc=fActiveConsumers.begin();
     603           0 :   while (desc!=fActiveConsumers.end()) {
     604           0 :     AliHLTConsumerDescriptor* pDesc=*desc;
     605           0 :     HLTWarning("consumer %p (%s) was not released", pDesc, pDesc->GetComponent()?pDesc->GetComponent()->GetComponentID():"### invalid component ###");
     606           0 :     fActiveConsumers.erase(desc);
     607           0 :     desc=fActiveConsumers.begin();
     608           0 :     fConsumers.push_back(pDesc);
     609           0 :   }
     610             : 
     611             :   // cleanup segments
     612           0 :   AliHLTDataSegmentList::iterator segment=fSegments.begin();
     613           0 :   while (segment!=fSegments.end()) {
     614           0 :     fSegments.erase(segment);
     615           0 :     segment=fSegments.begin();
     616             :   }
     617             : 
     618             :   // cleanup raw buffer
     619           0 :   if (pBuffer) {
     620           0 :     ReleaseRawBuffer(pBuffer);
     621           0 :   }
     622           0 :   return iResult;
     623           0 : }
     624             : 
     625             : int AliHLTDataBuffer::Reset()
     626             : {
     627             :   // see header file for function documentation
     628           0 :   return ResetDataBuffer();
     629             : }
     630             : 
     631             : // this is the version which works on lists of components instead of consumer descriptors
     632             : // int AliHLTDataBuffer::ChangeConsumerState(AliHLTComponent* pConsumer, AliHLTComponentPList &srcList, AliHLTComponentPList &tgtList)
     633             : // {
     634             : //   int iResult=0;
     635             : //   if (pDesc) {
     636             : //     AliHLTComponentPList::iterator desc=srcList.begin();
     637             : //     while (desc!=srcList.end()) {
     638             : //       if ((*desc)==pConsumer) {
     639             : //      srcList.erase(desc);
     640             : //      tgtList.push_back(pConsumer);
     641             : //      break;
     642             : //       }
     643             : //      desc++;
     644             : //     }
     645             : //     if (desc==srcList.end()) {
     646             : //       HLTError("can not find consumer component %p in list", pConsumer);
     647             : //       iResult=-ENOENT;
     648             : //     }
     649             : //   } else {
     650             : //     HLTError("invalid parameter");
     651             : //     iResult=-EINVAL;
     652             : //   }
     653             : //   return iResult;
     654             : // }
     655             : 
     656             : int AliHLTDataBuffer::ChangeConsumerState(AliHLTConsumerDescriptor* pDesc, AliHLTConsumerDescriptorPList &srcList, AliHLTConsumerDescriptorPList &tgtList)
     657             : {
     658             :   // see header file for function documentation
     659             :   int iResult=-ENOENT;
     660           0 :   if (pDesc) {
     661           0 :     AliHLTConsumerDescriptorPList::iterator desc=srcList.begin();
     662           0 :     while (desc!=srcList.end()) {
     663           0 :       if ((*desc)==pDesc) {
     664           0 :         srcList.erase(desc);
     665           0 :         tgtList.push_back(pDesc);
     666             :         iResult=0;
     667           0 :         break;
     668             :       }
     669           0 :       desc++;
     670             :     }
     671           0 :     if (iResult<0) {
     672           0 :       HLTError("can not find consumer descriptor %p in list", pDesc);
     673             :     }
     674           0 :   } else {
     675           0 :     HLTError("invalid parameter");
     676             :     iResult=-EINVAL;
     677             :   }
     678           0 :   return iResult;
     679             : }
     680             : 
     681             : int AliHLTDataBuffer::CleanupConsumerList() 
     682             : {
     683             :   // see header file for function documentation
     684             :   int iResult=0;
     685           0 :   ResetDataBuffer();
     686           0 :   AliHLTConsumerDescriptorPList::iterator desc=fConsumers.begin();
     687           0 :   while (desc!=fConsumers.end()) {
     688           0 :     delete *desc;
     689           0 :     fConsumers.erase(desc);
     690           0 :     desc=fConsumers.begin();
     691             :   }
     692           0 :   return iResult;
     693           0 : }
     694             : 
     695             : int AliHLTDataBuffer::FindConsumer(const AliHLTComponent* pConsumer, int bAllLists)
     696             : {
     697             :   // see header file for function documentation
     698           0 :   AliHLTConsumerDescriptorPList::iterator desc=fConsumers.begin();
     699           0 :   while (desc!=fConsumers.end()) {
     700           0 :     if ((*desc)->GetComponent()==pConsumer)
     701           0 :       return 1;
     702           0 :     desc++;
     703             :   }
     704           0 :   if (bAllLists==0) return 0;
     705             : 
     706           0 :   desc=fActiveConsumers.begin();
     707           0 :   while (desc!=fActiveConsumers.end()) {
     708           0 :     if ((*desc)->GetComponent()==pConsumer)
     709           0 :       return 1;
     710           0 :     desc++;
     711             :   }
     712           0 :   desc=fReleasedConsumers.begin();
     713           0 :   while (desc!=fReleasedConsumers.end()) {
     714           0 :     if ((*desc)->GetComponent()==pConsumer)
     715           0 :       return 1;
     716           0 :     desc++;
     717             :   }
     718           0 :   return 0;
     719           0 : }
     720             : 
     721             : AliHLTDataBuffer::AliHLTRawBuffer::AliHLTRawBuffer(AliHLTUInt32_t size)
     722           0 :   : fSize(0)
     723           0 :   , fTotalSize(size)
     724           0 :   , fExternalPtr(NULL)
     725           0 :   , fPtr(static_cast<AliHLTUInt8_t*>(malloc(size)))
     726           0 :   , fLastEventCount(0)
     727           0 : {
     728             :   // see header file for class documentation
     729             :   // or
     730             :   // refer to README to build package
     731             :   // or
     732             :   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
     733           0 :   if (fPtr==NULL) {
     734           0 :     fSize=0;
     735           0 :     fTotalSize=0;
     736           0 :   }
     737           0 : }
     738             : 
     739             : AliHLTDataBuffer::AliHLTRawBuffer::AliHLTRawBuffer(AliHLTUInt32_t size, AliHLTUInt8_t* buffer)
     740           0 :   : fSize(0)
     741           0 :   , fTotalSize(size)
     742           0 :   , fExternalPtr(buffer)
     743           0 :   , fPtr(fExternalPtr)
     744           0 :   , fLastEventCount(0)
     745           0 : {
     746             :   // see header file for class documentation
     747           0 : }
     748             : 
     749             : AliHLTDataBuffer::AliHLTRawBuffer::~AliHLTRawBuffer()
     750           0 : {
     751             :   // see header file for class documentation
     752           0 :   if (fExternalPtr==NULL && fPtr) {
     753           0 :     free(fPtr);
     754             :   }
     755           0 :   fPtr=NULL;
     756           0 :   fSize=0;
     757           0 :   fTotalSize=0;
     758           0 : }
     759             : 
     760             : int AliHLTDataBuffer::AliHLTRawBuffer::operator==(void* ptr) const
     761             : {
     762             :   // see header file for function documentation
     763           0 :   return fPtr == static_cast<AliHLTUInt8_t*>(ptr);
     764             : }
     765             : 
     766             : int AliHLTDataBuffer::AliHLTRawBuffer::operator<(void* ptr) const
     767             : {
     768             :   // see header file for function documentation
     769           0 :   int iResult=fPtr < static_cast<AliHLTUInt8_t*>(ptr);
     770             :   //printf("%p: %p <= %p (%d)\n", this, fPtr, ptr, iResult);
     771           0 :   return iResult;
     772             : }
     773             : 
     774             : int AliHLTDataBuffer::AliHLTRawBuffer::operator<=(void* ptr) const
     775             : {
     776             :   // see header file for function documentation
     777           0 :   int iResult=fPtr <= static_cast<AliHLTUInt8_t*>(ptr);
     778             :   //printf("%p: %p <= %p (%d)\n", this, fPtr, ptr, iResult);
     779           0 :   return iResult;
     780             : }
     781             : 
     782             : int AliHLTDataBuffer::AliHLTRawBuffer::operator>(void* ptr) const
     783             : {
     784             :   // see header file for function documentation
     785           0 :   int iResult=fPtr+fSize > static_cast<AliHLTUInt8_t*>(ptr);
     786             :   //printf("%p: %p + %d > %p (%d)\n", this, fPtr, fSize, ptr, iResult);
     787           0 :   return iResult;
     788             : }
     789             : 
     790             : int AliHLTDataBuffer::AliHLTRawBuffer::operator-(void* ptr) const
     791             : {
     792             :   // see header file for function documentation
     793           0 :   return static_cast<int>(static_cast<AliHLTUInt8_t*>(ptr)-fPtr);
     794             : }
     795             : 
     796             : int AliHLTDataBuffer::AliHLTRawBuffer::operator<(const AliHLTRawBuffer& op) const
     797             : {
     798             :   // see header file for function documentation
     799           0 :   return (fPtr+fSize < op.fPtr);
     800             : }
     801             : 
     802             : int AliHLTDataBuffer::AliHLTRawBuffer::operator<=(const AliHLTRawBuffer& op) const
     803             : {
     804             :   // see header file for function documentation
     805           0 :   return (fPtr+fSize <= op.fPtr);
     806             : }
     807             : 
     808             : int AliHLTDataBuffer::AliHLTRawBuffer::operator>(const AliHLTRawBuffer& op) const
     809             : {
     810             :   // see header file for function documentation
     811           0 :   return (fPtr >= op.fPtr+op.fSize);
     812             : }
     813             : 
     814             : AliHLTUInt8_t* AliHLTDataBuffer::AliHLTRawBuffer::UseBuffer(AliHLTUInt32_t size)
     815             : {
     816             :   // mark a portion of the buffer as used
     817           0 :   if (fTotalSize>=size) {
     818           0 :     fSize=size;
     819           0 :     fLastEventCount=AliHLTDataBuffer::fgEventCount;
     820             :     // only return pointer if there is a portion of the buffer used
     821           0 :     if (size>0) return fPtr;
     822             :   }
     823           0 :   return NULL;
     824           0 : }
     825             : 
     826             : AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::AliHLTRawBuffer::Split(AliHLTUInt32_t size)
     827             : {
     828             :   // split a buffer at specified size
     829             :   // only possible for buffers with external memory
     830           0 :   if (fTotalSize>size && 
     831           0 :       (fSize==0 || fSize<=size) && // used size must fit into the first part
     832           0 :       fExternalPtr!=NULL) {
     833           0 :     AliHLTRawBuffer* part2=new AliHLTRawBuffer(fTotalSize-size, fPtr+size);
     834           0 :     if (part2) {
     835           0 :       fTotalSize=size;
     836           0 :     }
     837             :     return part2;
     838             :   }
     839           0 :   return NULL;
     840           0 : }
     841             : 
     842             : int AliHLTDataBuffer::AliHLTRawBuffer::CheckSize(AliHLTUInt32_t size) const
     843             : {
     844             :   // see header file for function documentation
     845           0 :   if (fTotalSize<size) return 0;
     846             :   unsigned adjust=0;
     847           0 :   if (fLastEventCount+1<AliHLTDataBuffer::fgEventCount) {
     848           0 :     adjust=AliHLTDataBuffer::fgEventCount-fLastEventCount;
     849           0 :   }
     850           0 :   return (adjust>2) || ((fTotalSize-size)<(fgMargin<<adjust));
     851           0 : }
     852             : 
     853             : int AliHLTDataBuffer::AliHLTRawBuffer::Reset()
     854             : {
     855             :   // see header file for function documentation
     856           0 :   fSize=0;
     857           0 :   return 0;
     858             : }
     859             : 
     860             : int AliHLTDataBuffer::AliHLTRawBuffer::WritePattern(const char* pattern, int size)
     861             : {
     862             :   // see header file for function documentation
     863             :   int iResult=0;
     864           0 :   if (pattern!=NULL && size>0) {
     865           0 :     if (fSize+size<=fTotalSize) {
     866           0 :       memcpy(((char*)fPtr)+fSize, pattern, size);
     867             :       iResult=size;
     868           0 :     } else {
     869             :       iResult=-ENOSPC;
     870             :     }
     871             :   }
     872           0 :   return iResult;
     873             : }
     874             : 
     875             : int AliHLTDataBuffer::AliHLTRawBuffer::CheckPattern(const char* pattern, int size) const
     876             : {
     877             :   // see header file for function documentation
     878             :   int iResult=0;
     879           0 :   if (pattern!=NULL && size>0) {
     880           0 :     if (fSize+size<=fTotalSize) {
     881           0 :       iResult=memcmp(((char*)fPtr)+fSize, pattern, size)!=0;
     882           0 :     } else {
     883             :       iResult=-ENOSPC;
     884             :     }
     885             :   }
     886           0 :   return iResult;
     887             : }
     888             : 
     889             : int AliHLTDataBuffer::AliHLTRawBuffer::Merge(const AliHLTDataBuffer::AliHLTRawBuffer& neighbor)
     890             : {
     891             :   // Merge buffer with neighboring buffer.
     892             :   // Only possible if the buffers are consecutive with out any gap.
     893             : 
     894           0 :   if (!fExternalPtr || !neighbor.fExternalPtr) return -EPERM;
     895             : 
     896           0 :   if (neighbor.fTotalSize==0 &&
     897           0 :       fPtr < neighbor.fPtr &&
     898           0 :       fPtr+fTotalSize > neighbor.fPtr) {
     899             :     // special case for a buffer of zero size embedded into this buffer
     900             :     // nothing to do
     901           0 :     return 0;
     902             :   }
     903           0 :   if (fTotalSize==0 &&
     904           0 :       neighbor.fPtr < fPtr &&
     905           0 :       neighbor.fPtr+neighbor.fTotalSize > fPtr) {
     906             :     // special case for this buffer of size zero embedded into another buffer
     907           0 :     fPtr=neighbor.fPtr;
     908           0 :     fExternalPtr=fPtr;
     909           0 :     fTotalSize+=neighbor.fTotalSize;
     910           0 :     fSize=0;
     911           0 :     return 0;
     912             :   }
     913           0 :   if (fPtr+fTotalSize == neighbor.fPtr) {
     914           0 :     fTotalSize+=neighbor.fTotalSize;
     915           0 :     fSize=0;
     916           0 :     return 0;
     917             :   }
     918           0 :   if (fPtr == neighbor.fPtr+neighbor.fTotalSize) {
     919           0 :     fPtr=neighbor.fPtr;
     920           0 :     fExternalPtr=fPtr;
     921           0 :     fTotalSize+=neighbor.fTotalSize;
     922           0 :     fSize=0;
     923           0 :     return 0;
     924             :   }
     925           0 :   return -EINVAL;
     926           0 : }
     927             : 
     928             : void AliHLTDataBuffer::AliHLTRawBuffer::Print(const char* option) const
     929             : {
     930             :   /// print buffer information
     931           0 :   if (strcmp(option, "min")!=0) {
     932           0 :     cout << "************* AliHLTRawBuffer status ***********" << endl;
     933           0 :   }
     934           0 :   printf("  %p: buffer %p%s size %d used %d\n", this, fPtr, fExternalPtr?" (external)":"", fTotalSize, fSize); fflush(stdout);
     935           0 : }
     936             : 
     937           0 : AliHLTDataBuffer::AliHLTRawPage::AliHLTRawPage(AliHLTUInt32_t pagesize)
     938           0 :   : fSize(pagesize)
     939           0 :   , fPtr(static_cast<AliHLTUInt8_t*>(malloc(pagesize)))
     940           0 :   , fFreeBuffers()
     941           0 :   , fUsedBuffers()
     942           0 : {
     943             :   // constructor
     944           0 :   if (fPtr) {
     945           0 :     fFreeBuffers.push_back(new AliHLTRawBuffer(fSize, fPtr));
     946             :   } else {
     947           0 :     fSize=0;
     948             :   }
     949           0 : }
     950             : 
     951             : AliHLTDataBuffer::AliHLTRawPage::~AliHLTRawPage()
     952           0 : {
     953             :   // destructor
     954           0 :   if (IsUsed()) {
     955             :     // do not free if the resources have not been completely freed
     956           0 :     HLTError("memory mismatch: not all allocated intances have been released");
     957             :   } else {
     958           0 :     if (IsFragmented()) {
     959           0 :       HLTWarning("page still fragmented");
     960             :     }
     961           0 :     AliHLTRawBufferPList::iterator element=fFreeBuffers.begin();
     962           0 :     while (element!=fFreeBuffers.end()) {
     963           0 :       if (*element) delete *element;
     964           0 :       element=fFreeBuffers.erase(element);
     965             :     }
     966           0 :     if (fPtr) {
     967           0 :       free(fPtr);
     968             :     }
     969           0 :     fPtr=NULL;
     970           0 :     fSize=0;
     971           0 :   }
     972           0 : }
     973             : 
     974             : AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::AliHLTRawPage::Alloc(AliHLTUInt32_t size)
     975             : {
     976             :   /// alloc a buffer of specified size
     977           0 :   if (fFreeBuffers.size()==0) return NULL;
     978             :   
     979           0 :   for (AliHLTRawBufferPList::iterator iter=fFreeBuffers.begin();
     980           0 :        iter!=fFreeBuffers.end();
     981           0 :        iter++) {
     982           0 :     if ((*iter)->GetTotalSize()==size) {
     983           0 :       AliHLTRawBuffer* thisbuffer=*iter;
     984           0 :       fFreeBuffers.erase(iter);
     985           0 :       fUsedBuffers.push_back(thisbuffer);
     986           0 :       return thisbuffer;
     987           0 :     } else if ((*iter)->GetTotalSize()>size) {
     988           0 :       AliHLTRawBuffer* thisbuffer=*iter;
     989           0 :       AliHLTRawBuffer* newbuffer=thisbuffer->Split(size);
     990           0 :       if (newbuffer) {
     991           0 :         *iter=newbuffer;
     992           0 :         fUsedBuffers.push_back(thisbuffer);
     993           0 :         return thisbuffer;
     994             :       } else {
     995           0 :         HLTWarning("failed to alloc raw buffer: cannot split raw buffer %p of size %d (used %d) at size %d", *iter, (*iter)->GetTotalSize(), (*iter)->GetUsedSize(), size);
     996             :       }
     997           0 :     }
     998             :   }
     999           0 :   return NULL;
    1000           0 : }
    1001             : 
    1002             : int AliHLTDataBuffer::AliHLTRawPage::Free(AliHLTRawBuffer* pBuffer)
    1003             : {
    1004             :   /// free a buffer and merge consecutive free buffers
    1005             :   int iResult=0;
    1006           0 :   for (AliHLTRawBufferPList::iterator iter=fUsedBuffers.begin();
    1007           0 :        iter!=fUsedBuffers.end() && iResult>=0;
    1008           0 :        iter++) {
    1009           0 :     if ((*iter)==pBuffer) {
    1010           0 :       fUsedBuffers.erase(iter);
    1011           0 :       AliHLTRawBufferPList::iterator prev=fFreeBuffers.begin();
    1012           0 :       for (; prev!=fFreeBuffers.end() && iResult>=0; prev++) {
    1013           0 :         if ((*pBuffer)<(*(*prev)) ||
    1014           0 :             ((*prev)->GetTotalSize()==0 && pBuffer->GetPointer()<=(*prev)->GetPointer() && (*prev)->GetPointer()<=pBuffer->GetPointer()+pBuffer->GetTotalSize())) {
    1015             :           // check consecutive buffers
    1016           0 :           if ((*(*prev)) == (pBuffer->GetPointer()+pBuffer->GetTotalSize()) ||
    1017           0 :               ((*prev)->GetTotalSize()==0 && pBuffer->GetPointer()<=(*prev)->GetPointer() && (*prev)->GetPointer()<=pBuffer->GetPointer()+pBuffer->GetTotalSize())) {
    1018             :             // the buffer to be released has a consecutive free buffer -> merge them
    1019           0 :             if ((iResult=pBuffer->Merge(*(*prev)))>=0) {
    1020           0 :               delete *prev;
    1021           0 :               *prev=pBuffer;
    1022           0 :             } else {
    1023           0 :               HLTError("failed to merge consecutive/overlapping buffers %p and %p", pBuffer, (*prev));
    1024           0 :               pBuffer->Print("");
    1025           0 :               (*prev)->Print("");
    1026             :             }
    1027             :             break;
    1028             :           }
    1029           0 :           fFreeBuffers.insert(prev, pBuffer);
    1030           0 :           break;
    1031             :         }
    1032           0 :         if ((*pBuffer)>(*(*prev)) ||
    1033           0 :             (pBuffer->GetTotalSize()==0 && (*prev)->GetPointer()<=pBuffer->GetPointer() && pBuffer->GetPointer()<=(*prev)->GetPointer()+(*prev)->GetTotalSize())) {
    1034             :           // check consecutive buffers
    1035           0 :           if ((*pBuffer) == ((*prev)->GetPointer()+(*prev)->GetTotalSize())||
    1036           0 :               (pBuffer->GetTotalSize()==0 && (*prev)->GetPointer()<=pBuffer->GetPointer() && pBuffer->GetPointer()<=(*prev)->GetPointer()+(*prev)->GetTotalSize())) {
    1037             :             // the buffer to be released is consecutive to a free buffer -> merge them
    1038           0 :             if ((iResult=pBuffer->Merge(*(*prev)))>=0) {
    1039           0 :               AliHLTRawBufferPList::iterator succ=prev+1;
    1040           0 :               delete *prev;
    1041           0 :               *prev=pBuffer;
    1042             :               // check if the buffer and the following one are consecutive
    1043           0 :               if (succ!=fFreeBuffers.end() &&
    1044           0 :                   (*(*succ)) == (pBuffer->GetPointer()+pBuffer->GetTotalSize())) {
    1045           0 :                 if ((iResult=pBuffer->Merge(*(*succ)))>=0) {
    1046           0 :                   delete *succ;
    1047           0 :                   fFreeBuffers.erase(succ);
    1048           0 :                 }
    1049             :               }
    1050           0 :             }
    1051             :             break;
    1052             :           }
    1053             :         }
    1054             :       }
    1055           0 :       if (prev==fFreeBuffers.end()) {
    1056           0 :         fFreeBuffers.push_back(pBuffer);
    1057           0 :       }
    1058             : 
    1059             :       // merge consecutive free buffers
    1060           0 :       prev=fFreeBuffers.begin();
    1061           0 :       for (AliHLTRawBufferPList::iterator current=prev+1; current!=fFreeBuffers.end() && iResult>=0; ) {
    1062             :         // check if the buffer is embedded into the previous one
    1063           0 :         if ((*current)->GetTotalSize()==0 && (*prev)->GetPointer()<=(*current)->GetPointer() && (*current)->GetPointer()<(*prev)->GetPointer()+(*prev)->GetTotalSize())  {
    1064           0 :           if ((iResult=(*prev)->Merge(*(*current)))>=0) {
    1065           0 :             current=fFreeBuffers.erase(current);
    1066           0 :             continue;
    1067             :           } else {
    1068           0 :             HLTError("failed to merge embedded zero length buffer into preceeding buffer");
    1069           0 :             Print("");
    1070             :           }
    1071           0 :         }
    1072             :         // check if the buffer is consecutive to the previous one
    1073           0 :         if ((*(*current)) == ((*prev)->GetPointer()+(*prev)->GetTotalSize())) {
    1074           0 :           if ((iResult=(*prev)->Merge(*(*current)))>=0) {
    1075           0 :             current=fFreeBuffers.erase(current);
    1076           0 :             continue;
    1077             :           } else {
    1078           0 :             HLTError("failed to merge consecutive free buffers");
    1079           0 :             Print("");
    1080             :           }
    1081           0 :         }
    1082           0 :         prev=current++;
    1083             :       }
    1084             : 
    1085             :       // buffer was part of this page
    1086             :       return 0;
    1087           0 :     }
    1088             :   }
    1089             :   // buffer not found in this page
    1090           0 :   return 1;
    1091           0 : }
    1092             : 
    1093             : int AliHLTDataBuffer::AliHLTRawPage::SetSize(const AliHLTDataBuffer::AliHLTRawBuffer* pBuffer, AliHLTUInt32_t size)
    1094             : {
    1095             :   /// set the size of a raw buffer and release the remaining part
    1096             :   int iResult=0;
    1097           0 :   for (AliHLTRawBufferPList::iterator iter=fUsedBuffers.begin();
    1098           0 :        iter!=fUsedBuffers.end() && iResult>=0;
    1099           0 :        iter++) {
    1100           0 :     if ((*iter)==pBuffer) {      // buffer was part of this page
    1101           0 :       if ((*iter)->GetTotalSize()==size) return 0;
    1102           0 :       if ((*iter)->GetTotalSize()<size) {
    1103           0 :         HLTError("%d exceeds total size of buffer %p (%d used %d)\n", size, *iter, (*iter)->GetTotalSize(), (*iter)->GetUsedSize());
    1104           0 :         return -ENOSPC;
    1105             :       }
    1106           0 :       AliHLTDataBuffer::AliHLTRawBuffer* freespace=(*iter)->Split(size);
    1107           0 :       if (freespace) {
    1108           0 :         fUsedBuffers.push_back(freespace);
    1109           0 :         Free(freespace);
    1110           0 :       } else {
    1111           0 :         HLTWarning("failed to relase unused memory: cannot split raw buffer %p of size %d (used %d) at size %d", *iter, (*iter)->GetTotalSize(), (*iter)->GetUsedSize(), size);
    1112             :       }
    1113             :       return 0;
    1114           0 :     }
    1115             :   }
    1116             :   // buffer not found in this page
    1117           0 :   return 1;
    1118           0 : }
    1119             : 
    1120             : bool AliHLTDataBuffer::AliHLTRawPage::HasBuffer(const AliHLTDataBuffer::AliHLTRawBuffer* pBuffer)
    1121             : {
    1122             :   /// check if the buffer is in this page
    1123           0 :   for (AliHLTRawBufferPList::iterator iter=fUsedBuffers.begin();
    1124           0 :        iter!=fUsedBuffers.end();
    1125           0 :        iter++) {
    1126           0 :     if ((*iter)==pBuffer) {      // buffer was part of this page
    1127           0 :       return true;
    1128             :     }
    1129             :   }
    1130             :   // buffer not found in this page
    1131           0 :   return false;
    1132           0 : }
    1133             : 
    1134             : AliHLTUInt32_t AliHLTDataBuffer::AliHLTRawPage::Capacity() const 
    1135             : {
    1136             :   /// get max available contiguous buffer
    1137             :   AliHLTUInt32_t capacity=0;
    1138           0 :   for (unsigned i=0; i<fFreeBuffers.size(); i++) {
    1139           0 :     if (fFreeBuffers[i]->GetTotalSize()>capacity) 
    1140           0 :       capacity=fFreeBuffers[i]->GetTotalSize();
    1141             :   }
    1142           0 :   return capacity;
    1143             : }
    1144             : 
    1145             : void AliHLTDataBuffer::AliHLTRawPage::Print(const char* option)
    1146             : {
    1147             :   /// print page information
    1148           0 :   if (strcmp(option, "global")==0) {
    1149           0 :     cout << "number of global pages: " << fgGlobalPages.size() << endl;
    1150           0 :     for (AliHLTRawPage* rawpage=NextPage(NULL);
    1151           0 :          rawpage!=NULL; 
    1152           0 :          rawpage=NextPage(rawpage)) {
    1153           0 :       rawpage->Print("");
    1154             :     }
    1155           0 :     return;
    1156             :   }
    1157           0 :   cout << "************* AliHLTRawPage status ***********" << endl;
    1158           0 :   cout << "  instance " << this << endl;
    1159           0 :   printf("  buffer %p  size %d", fPtr, fSize);
    1160           0 :   cout << "  used buffers: " << fUsedBuffers.size() << endl;
    1161           0 :   AliHLTRawBufferPList::iterator iter=fUsedBuffers.begin();
    1162           0 :   for (; iter!=fUsedBuffers.end(); iter++) {
    1163           0 :     cout << "  "; (*iter)->Print("min");
    1164             :   }
    1165           0 :   cout << "  free buffers: " << fFreeBuffers.size() << endl;
    1166           0 :   iter=fFreeBuffers.begin();
    1167           0 :   for (; iter!=fFreeBuffers.end(); iter++) {
    1168           0 :     cout << "  "; (*iter)->Print("min");
    1169             :   }
    1170           0 : }
    1171             : 
    1172             : 
    1173         126 : vector<AliHLTDataBuffer::AliHLTRawPage*> AliHLTDataBuffer::AliHLTRawPage::fgGlobalPages;
    1174             : 
    1175             : AliHLTUInt32_t AliHLTDataBuffer::AliHLTRawPage::fgGlobalPageSize=30*1024*1024;
    1176             : 
    1177             : unsigned int AliHLTDataBuffer::GetMaxBufferSize()
    1178             : {
    1179           0 :         return(30 * AliHLTRawPage::GetGlobalPageSize()); //Use a max data size of 30 * GlobalPageSize, as this is the maximum AliHLTRawPage::GlobalAlloc will allocate
    1180             : }
    1181             : 
    1182             : AliHLTDataBuffer::AliHLTRawBuffer* AliHLTDataBuffer::AliHLTRawPage::GlobalAlloc(AliHLTUInt32_t size, int verbosity)
    1183             : {
    1184             :   // alloc a buffer of specified size from the global pages
    1185             :   AliHLTDataBuffer::AliHLTRawBuffer* rawbuffer=NULL;
    1186           0 :   vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=fgGlobalPages.begin();
    1187           0 :   AliHLTLogging log;
    1188           0 :   for (page=fgGlobalPages.begin();page!=fgGlobalPages.end(); page++) {
    1189           0 :     if ((rawbuffer=(*page)->Alloc(size))!=NULL) {
    1190           0 :       if (verbosity>1) {
    1191           0 :         log.Logging(kHLTLogInfo, "AliHLTDataBuffer::AliHLTRawPage::GlobalAlloc", "data buffer handling", "allocated raw buffer %p from page %p\n", rawbuffer, *page);
    1192           0 :         rawbuffer->Print("min");
    1193             :       }
    1194             :       break;
    1195             :     }
    1196             :   }
    1197           0 :   if (!rawbuffer) {
    1198           0 :     AliHLTUInt32_t rawPageSize=fgGlobalPageSize;
    1199           0 :     if (rawPageSize<size) {
    1200           0 :       if (rawPageSize*30+fgkSafetyPatternSize<size) {
    1201           0 :         log.Logging(kHLTLogError, "AliHLTDataBuffer::AliHLTRawPage::GlobalAlloc", "data buffer handling", "refusing to allocate buffer of size %d", size);
    1202           0 :         return NULL;
    1203             :       }
    1204             :       rawPageSize=size;
    1205           0 :     }
    1206           0 :     AliHLTDataBuffer::AliHLTRawPage* rawpage=new AliHLTDataBuffer::AliHLTRawPage(rawPageSize);
    1207           0 :     if (!rawpage) {
    1208           0 :       log.Logging(kHLTLogError, "AliHLTDataBuffer::AliHLTRawPage::GlobalAlloc", "data buffer handling", "can not create raw page");
    1209           0 :       return NULL;
    1210             :     }
    1211             : 
    1212             :     // check is there is at least one unused page which can be replaced by the newly created one
    1213           0 :     for (page=fgGlobalPages.begin(); page!=fgGlobalPages.end(); page++) {
    1214           0 :       if ((*page)->IsUsed()) continue;
    1215           0 :       delete *page;
    1216           0 :       fgGlobalPages.erase(page);
    1217           0 :       break; // delete only one page to be replaced by the new page
    1218             :     }
    1219           0 :     fgGlobalPages.push_back(rawpage);
    1220           0 :     if ((rawbuffer=rawpage->Alloc(size))!=NULL) {
    1221           0 :       if (verbosity>1) {
    1222           0 :         log.Logging(kHLTLogInfo, "AliHLTDataBuffer::AliHLTRawPage::GlobalAlloc", "data buffer handling", "allocated raw buffer %p from page %p\n", rawbuffer, rawpage);
    1223           0 :         rawbuffer->Print("min");
    1224             :       }
    1225             :     }
    1226           0 :   }
    1227             : 
    1228           0 :   return rawbuffer;
    1229           0 : }
    1230             : 
    1231             : AliHLTDataBuffer::AliHLTRawPage* AliHLTDataBuffer::AliHLTRawPage::FindPage(AliHLTDataBuffer::AliHLTRawBuffer* buffer)
    1232             : {
    1233             :   // find buffer in the global pages
    1234           0 :   vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=fgGlobalPages.begin();
    1235           0 :   for (; page!=fgGlobalPages.end(); page++) {
    1236           0 :     if ((*page)->HasBuffer(buffer)) {
    1237           0 :       return *page;
    1238             :     }
    1239             :   }
    1240             : 
    1241           0 :   return NULL;
    1242           0 : }
    1243             : 
    1244             : int AliHLTDataBuffer::AliHLTRawPage::GlobalClean()
    1245             : {
    1246             :   // cleanup the global pages */
    1247           6 :   vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=fgGlobalPages.begin();
    1248           6 :   while (page!=fgGlobalPages.end()) {
    1249           0 :     if (!(*page)->IsUsed()) {
    1250           0 :       delete *page;
    1251           0 :       page=fgGlobalPages.erase(page);
    1252           0 :       continue;
    1253             :     }
    1254           0 :     AliHLTLogging log;
    1255           0 :     log.Logging(kHLTLogError, "AliHLTDataBuffer::AliHLTRawPage::GlobalClean", "data buffer handling", "HLT memory page still in use, skipping cleanup, potential memory leak");
    1256             :     
    1257           0 :     page++;
    1258           0 :   }
    1259             :   
    1260           3 :   return 0;
    1261           3 : }
    1262             : 
    1263             : AliHLTDataBuffer::AliHLTRawPage* AliHLTDataBuffer::AliHLTRawPage::NextPage(const AliHLTDataBuffer::AliHLTRawPage* prev)
    1264             : {
    1265             :   // get next global page
    1266           0 :   vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=fgGlobalPages.begin();
    1267           0 :   for (; page!=fgGlobalPages.end(); page++) {
    1268           0 :     if (prev==NULL) return *page;
    1269           0 :     if (*page!=prev) continue;
    1270           0 :     if (++page!=fgGlobalPages.end()) return *page;
    1271             :     break;
    1272             :   }
    1273           0 :   return NULL;
    1274           0 : }
    1275             : 
    1276             : void AliHLTDataBuffer::AliHLTDataSegment::Print(const char* /*option*/) const
    1277             : {
    1278             :   // print info for data segment
    1279           0 :   cout << "AliHLTDataSegment " << this 
    1280           0 :        << " " << AliHLTComponent::DataType2Text(fDataType)
    1281           0 :        << " " << hex << fSpecification << dec
    1282           0 :        << " Ptr " << (void*)fPtr
    1283           0 :        << " offset " << fSegmentOffset
    1284           0 :        << " size " << fSegmentSize
    1285           0 :        << endl;
    1286           0 : }
    1287             : 
    1288             : void AliHLTDataBuffer::AliHLTForwardedDataSegment::Print(const char* option) const
    1289             : {
    1290             :   // print info for data segment
    1291           0 :   cout << "AliHLTForwardeDataSegment " << this << endl;
    1292           0 :   cout << "    my    : "; AliHLTDataSegment::Print(option);
    1293           0 :   cout << "    parent: "; fParentSegment.Print(option);
    1294           0 :   cout << "    task  : "; 
    1295           0 :   if (fParentTask) fParentTask->Print("");
    1296           0 :   else cout << "nil" << endl;
    1297           0 : }
    1298             : 
    1299             : void AliHLTDataBuffer::Print(const char* option) const
    1300             : {
    1301             :   // print info for data buffer
    1302             :   unsigned i=0;
    1303           0 :   cout << "AliHLTDataBuffer " << this << endl;
    1304           0 :   cout << " raw buffer " << fpBuffer << endl;
    1305           0 :   if (fpBuffer) {
    1306           0 :     cout << " ";
    1307           0 :     fpBuffer->Print(option);
    1308           0 :   }
    1309             : 
    1310           0 :   cout << " total segments: " << GetNofSegments() << endl;
    1311           0 :   cout << "   data segments: " << fSegments.size() << endl;
    1312           0 :   for (i=0; i<fSegments.size(); i++) {
    1313           0 :     cout << "     ";
    1314           0 :     fSegments[i].Print(option);
    1315             :   }
    1316             : 
    1317           0 :   cout << "   forwarded segments: " << fForwardedSegments.size() << endl;
    1318           0 :   for (i=0; i<fForwardedSegments.size(); i++) {
    1319           0 :     cout << "     ";
    1320           0 :     fForwardedSegments[i].Print(option);
    1321             :   }
    1322             : 
    1323           0 :   cout << " consumers: " << GetNofConsumers() << endl;
    1324           0 :   for (i=0; i<fConsumers.size(); i++) {
    1325           0 :     cout << "   ";
    1326           0 :     fConsumers[i]->Print(option);
    1327             :   }
    1328             : 
    1329           0 :   cout << " active consumers: " << GetNofActiveConsumers() << endl;
    1330           0 :   for (i=0; i<fActiveConsumers.size(); i++) {
    1331           0 :     cout << "   ";
    1332           0 :     fActiveConsumers[i]->Print(option);
    1333             :   }
    1334             : 
    1335           0 :   cout << " released consumers: " << fReleasedConsumers.size() << endl;
    1336           0 :   for (i=0; i<fReleasedConsumers.size(); i++) {
    1337           0 :     cout << "   ";
    1338           0 :     fReleasedConsumers[i]->Print(option);
    1339             :   }
    1340             : 
    1341           0 : }

Generated by: LCOV version 1.11