// $Id$ /************************************************************************** * This file is property of and copyright by the ALICE HLT Project * * ALICE Experiment at CERN, All rights reserved. * * * * Primary Authors: Matthias Richter * * 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 testAliHLTDataBuffer.C @author Matthias Richter @date @brief Test program for the AliHLTDataBuffer class */ #ifndef __CINT__ #include "TDatime.h" #include "TRandom.h" #include "AliHLTDataTypes.h" #include "algorithm" #include "TObjArray.h" #include "TObjString.h" #include "TString.h" #include "AliHLTDAQ.h" #include #include #include #include #include "AliHLTDataBuffer.h" #endif using namespace std; int gVerbosity=0; const int gPagesize=1024*1024*10; int testAliHLTRawPage(); int GetRandom(int min, int max); struct testProcessDescription { int fLevel; AliHLTUInt32_t fBufferSize; AliHLTDataBuffer::AliHLTRawBuffer* fRawBuffer; }; int testAliHLTDataBuffer() { int iResult=0; if ((iResult=testAliHLTRawPage())<0) return iResult; return 0; } int fillTestSample(int levels, int processes, vector& descriptions) { int availableProcesses=processes; for (int level=0; level& descriptions, vector& pages, int level=-1) { for (unsigned i=0; i=0 && descriptions[i].fLevel=0 && descriptions[i].fLevel>level) break; if (descriptions[i].fRawBuffer) { cerr << "warning: buffer already allocated" << endl; continue; } vector::iterator page=pages.begin(); for (page=pages.begin();page!=pages.end(); page++) { if ((descriptions[i].fRawBuffer=(*page)->Alloc(GetRandom(descriptions[i].fBufferSize/2, descriptions[i].fBufferSize)))!=NULL) { if (gVerbosity>1) { printf("allocated raw buffer %p from page %p\n", descriptions[i].fRawBuffer, *page); descriptions[i].fRawBuffer->Print("min"); } break; } } if (!descriptions[i].fRawBuffer) { AliHLTDataBuffer::AliHLTRawPage* rawpage=new AliHLTDataBuffer::AliHLTRawPage(gPagesize); if (!rawpage) { cerr << "can not create raw page" << endl; return -ENOMEM; } pages.push_back(rawpage); if ((descriptions[i].fRawBuffer=rawpage->Alloc(GetRandom(descriptions[i].fBufferSize/2, descriptions[i].fBufferSize)))!=NULL) { if (gVerbosity>1) { printf("allocated raw buffer %p from page %p\n", descriptions[i].fRawBuffer, rawpage); descriptions[i].fRawBuffer->Print("min"); } } } if (!descriptions[i].fRawBuffer) { cerr << "failed to allocate buffer for process " << i << endl; return -EFAULT; } } return 0; } int setBufferSizes(vector& descriptions, vector& pages, int level=-1) { // set buffer size for all processes of the specified level // buffer size is chosen randomly between 0 and the allocated size vector positions; for (unsigned i=0; i=0 && descriptions[i].fLevel=0 && descriptions[i].fLevel>level) break; positions.push_back(i); } random_shuffle(positions.begin(), positions.end()); for (vector::iterator position=positions.begin(); position!=positions.end(); position++) { vector::iterator page=pages.begin(); for (; page!=pages.end(); page++) { if ((*page)->SetSize(descriptions[*position].fRawBuffer, GetRandom(0, descriptions[*position].fBufferSize))==0) { if (gVerbosity>1) { cout << "setting size for raw buffer " << descriptions[*position].fRawBuffer << " of page " << *page << ", process level " << descriptions[*position].fLevel << endl; descriptions[*position].fRawBuffer->Print("min"); } break; } } if (page==pages.end()) { cerr << "failed to set size for raw buffer " << descriptions[*position].fRawBuffer << "of process " << *position << endl; return -EFAULT; } } return 0; } int releaseBuffers(vector& descriptions, vector& pages, int level=-1) { // find the processes to be releases according to the specified level // shuffle the processes and then release in this random order vector positions; for (unsigned i=0; i=0 && descriptions[i].fLevel=0 && descriptions[i].fLevel>level) break; positions.push_back(i); } random_shuffle(positions.begin(), positions.end()); for (vector::iterator position=positions.begin(); position!=positions.end(); position++) { vector::iterator page=pages.begin(); for (; page!=pages.end(); page++) { if ((*page)->Free(descriptions[*position].fRawBuffer)==0) { if (gVerbosity>1) cout << "released raw buffer " << descriptions[*position].fRawBuffer << " from page " << *page << ", process level " << descriptions[*position].fLevel << endl; descriptions[*position].fRawBuffer=NULL; break; } } if (page==pages.end()) { cerr << "failed to release raw buffer " << descriptions[*position].fRawBuffer << "of process " << *position << endl; return -EFAULT; } } return 0; } int testAliHLTRawPage() { int iResult=0; int nofLevels=GetRandom(3,5); int nofProcesses=GetRandom(nofLevels,10); int nofCycles=GetRandom(5,10); vector descriptions; if ((iResult=fillTestSample(nofLevels, nofProcesses, descriptions))<0) { cerr << "failed to fill test sample" << endl; return iResult; } if (gVerbosity>1) { for (unsigned i=0; i pages; vector::iterator page=pages.end(); for (int cycle=0; cycle0) cout << "level " << level << " - status of pages: " << pages.size() << endl; for (page=pages.begin();page!=pages.end(); page++) { if (gVerbosity>0) (*page)->Print(""); } if (level0) cout << "level " << level << " - status of pages: " << pages.size() << endl; for (page=pages.begin();page!=pages.end(); page++) { if (gVerbosity>0) (*page)->Print(""); } if (level>0) { if ((iResult=releaseBuffers(descriptions, pages, level-1))<0) { cerr << "failed to release buffers" << endl; return iResult; } } } if (gVerbosity>0) cout << "status of released pages:" << endl; for (page=pages.begin();page!=pages.end(); page++) { if (gVerbosity>0) (*page)->Print(""); if ((*page)->IsUsed()) { cerr << "page " << *page << " has used buffers" << endl; return -EFAULT; } if ((*page)->Size()!=(*page)->Capacity()) { cerr << "page " << *page << " not completely released" << endl; return -EFAULT; } if ((*page)->IsFragmented()) { cerr << "page " << *page << " is still fragmented" << endl; return -EFAULT; } } } return 0; } /** * Get a random number in the given range. */ int GetRandom(int min, int max) { if (max-min<2) return min; static TRandom rand; static bool seedSet=false; if (!seedSet) { TDatime dt; rand.SetSeed(dt.Get()); seedSet=true; } return min+rand.Integer(max-min); } ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // // main functions int main(int /*argc*/, const char** /*argv*/) { int iResult=0; iResult=testAliHLTDataBuffer(); return iResult; }