]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/test/testAliHLTDataBuffer.C
fix user histogram management and style (Ben)
[u/mrichter/AliRoot.git] / HLT / BASE / test / testAliHLTDataBuffer.C
CommitLineData
539ed16e 1// $Id$
2
3/**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
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 testAliHLTDataBuffer.C
20 @author Matthias Richter
21 @date
22 @brief Test program for the AliHLTDataBuffer class
23 */
24
25#ifndef __CINT__
26#include "TDatime.h"
27#include "TRandom.h"
28#include "AliHLTDataTypes.h"
29#include "algorithm"
30#include "TObjArray.h"
31#include "TObjString.h"
32#include "TString.h"
33#include "AliHLTDAQ.h"
34#include <cstdio>
35#include <cstring>
36#include <iostream>
37#include <cerrno>
38#include "AliHLTDataBuffer.h"
39#endif
40
41using namespace std;
42
43int gVerbosity=0;
44const int gPagesize=1024*1024*10;
45
46int testAliHLTRawPage();
47int GetRandom(int min, int max);
48
49struct testProcessDescription {
50 int fLevel;
51 AliHLTUInt32_t fBufferSize;
52 AliHLTDataBuffer::AliHLTRawBuffer* fRawBuffer;
53};
54
55int testAliHLTDataBuffer()
56{
57 int iResult=0;
58 if ((iResult=testAliHLTRawPage())<0) return iResult;
59
60 return 0;
61}
62
63int fillTestSample(int levels, int processes, vector<testProcessDescription>& descriptions)
64{
65 int availableProcesses=processes;
66 for (int level=0; level<levels; level++) {
67 int levelprocesses=GetRandom(availableProcesses/2, availableProcesses-(levels-level));
68 for (int process=0; process<levelprocesses; process++) {
69 testProcessDescription desc;
70 desc.fLevel=level;
71 desc.fBufferSize=GetRandom(1024, 3*gPagesize/processes);
72 desc.fRawBuffer=NULL;
73 descriptions.push_back(desc);
74 }
75 availableProcesses-=levelprocesses;
76 }
77 return 0;
78}
79
80int allocateBuffers(vector<testProcessDescription>& descriptions,
81 vector<AliHLTDataBuffer::AliHLTRawPage*>& pages,
82 int level=-1)
83{
84 for (unsigned i=0; i<descriptions.size(); i++) {
85 if (level>=0 && descriptions[i].fLevel<level) continue;
86 if (level>=0 && descriptions[i].fLevel>level) break;
87 if (descriptions[i].fRawBuffer) {
88 cerr << "warning: buffer already allocated" << endl;
89 continue;
90 }
91
92 vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=pages.begin();
93 for (page=pages.begin();page!=pages.end(); page++) {
94 if ((descriptions[i].fRawBuffer=(*page)->Alloc(GetRandom(descriptions[i].fBufferSize/2, descriptions[i].fBufferSize)))!=NULL) {
95 if (gVerbosity>1) {
96 printf("allocated raw buffer %p from page %p\n", descriptions[i].fRawBuffer, *page);
97 descriptions[i].fRawBuffer->Print("min");
98 }
99 break;
100 }
101 }
102 if (!descriptions[i].fRawBuffer) {
103 AliHLTDataBuffer::AliHLTRawPage* rawpage=new AliHLTDataBuffer::AliHLTRawPage(gPagesize);
104 if (!rawpage) {
105 cerr << "can not create raw page" << endl;
106 return -ENOMEM;
107 }
108 pages.push_back(rawpage);
109 if ((descriptions[i].fRawBuffer=rawpage->Alloc(GetRandom(descriptions[i].fBufferSize/2, descriptions[i].fBufferSize)))!=NULL) {
110 if (gVerbosity>1) {
111 printf("allocated raw buffer %p from page %p\n", descriptions[i].fRawBuffer, rawpage);
112 descriptions[i].fRawBuffer->Print("min");
113 }
114 }
115 }
116 if (!descriptions[i].fRawBuffer) {
117 cerr << "failed to allocate buffer for process " << i << endl;
118 return -EFAULT;
119 }
120 }
121 return 0;
122}
123
124int setBufferSizes(vector<testProcessDescription>& descriptions,
125 vector<AliHLTDataBuffer::AliHLTRawPage*>& pages,
126 int level=-1)
127{
128 // set buffer size for all processes of the specified level
129 // buffer size is chosen randomly between 0 and the allocated size
130 vector<unsigned> positions;
131 for (unsigned i=0; i<descriptions.size(); i++) {
132 if (!descriptions[i].fRawBuffer) continue;
133 if (level>=0 && descriptions[i].fLevel<level) continue;
134 if (level>=0 && descriptions[i].fLevel>level) break;
135 positions.push_back(i);
136 }
137
138 random_shuffle(positions.begin(), positions.end());
139 for (vector<unsigned>::iterator position=positions.begin();
140 position!=positions.end(); position++) {
141 vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=pages.begin();
142 for (; page!=pages.end(); page++) {
143 if ((*page)->SetSize(descriptions[*position].fRawBuffer, GetRandom(0, descriptions[*position].fBufferSize))==0) {
144 if (gVerbosity>1) {
145 cout << "setting size for raw buffer " << descriptions[*position].fRawBuffer << " of page " << *page << ", process level " << descriptions[*position].fLevel << endl;
146 descriptions[*position].fRawBuffer->Print("min");
147 }
148 break;
149 }
150 }
151 if (page==pages.end()) {
152 cerr << "failed to set size for raw buffer " << descriptions[*position].fRawBuffer << "of process " << *position << endl;
153 return -EFAULT;
154 }
155 }
156 return 0;
157}
158
159int releaseBuffers(vector<testProcessDescription>& descriptions,
160 vector<AliHLTDataBuffer::AliHLTRawPage*>& pages,
161 int level=-1)
162{
163 // find the processes to be releases according to the specified level
164 // shuffle the processes and then release in this random order
165 vector<unsigned> positions;
166 for (unsigned i=0; i<descriptions.size(); i++) {
167 if (!descriptions[i].fRawBuffer) continue;
168 if (level>=0 && descriptions[i].fLevel<level) continue;
169 if (level>=0 && descriptions[i].fLevel>level) break;
170 positions.push_back(i);
171 }
172
173 random_shuffle(positions.begin(), positions.end());
174 for (vector<unsigned>::iterator position=positions.begin();
175 position!=positions.end(); position++) {
176 vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=pages.begin();
177 for (; page!=pages.end(); page++) {
178 if ((*page)->Free(descriptions[*position].fRawBuffer)==0) {
179 if (gVerbosity>1) cout << "released raw buffer " << descriptions[*position].fRawBuffer << " from page " << *page << ", process level " << descriptions[*position].fLevel << endl;
180 descriptions[*position].fRawBuffer=NULL;
181 break;
182 }
183 }
184 if (page==pages.end()) {
185 cerr << "failed to release raw buffer " << descriptions[*position].fRawBuffer << "of process " << *position << endl;
186 return -EFAULT;
187 }
188 }
189 return 0;
190}
191
192int testAliHLTRawPage()
193{
194 int iResult=0;
195 int nofLevels=GetRandom(3,5);
196 int nofProcesses=GetRandom(nofLevels,10);
197 int nofCycles=GetRandom(5,10);
198
199 vector<testProcessDescription> descriptions;
200 if ((iResult=fillTestSample(nofLevels, nofProcesses, descriptions))<0) {
201 cerr << "failed to fill test sample" << endl;
202 return iResult;
203 }
204
205 if (gVerbosity>1) {
206 for (unsigned i=0; i<descriptions.size(); i++) {
207 cout << "process " << i << ": level " << descriptions[i].fLevel << " max size " << descriptions[i].fBufferSize << endl;
208 }
209 }
210
211 vector<AliHLTDataBuffer::AliHLTRawPage*> pages;
212 vector<AliHLTDataBuffer::AliHLTRawPage*>::iterator page=pages.end();
213 for (int cycle=0; cycle<nofCycles; cycle++) {
214 unsigned process=0;
215 for (int level=0; level<=nofLevels; level++) {
216 // allocate buffers
217 if (level<nofLevels) {
218 if ((iResult=allocateBuffers(descriptions, pages, level))<0) {
219 cerr << "failed to allocate buffers" << endl;
220 return iResult;
221 }
222 }
223
224 if (gVerbosity>0) cout << "level " << level << " - status of pages: " << pages.size() << endl;
225 for (page=pages.begin();page!=pages.end(); page++) {
226 if (gVerbosity>0) (*page)->Print("");
227 }
228
229 if (level<nofLevels) {
230 if ((iResult=setBufferSizes(descriptions, pages, level))<0) {
231 cerr << "failed setting buffers" << endl;
232 return iResult;
233 }
234 }
235
236 if (gVerbosity>0) cout << "level " << level << " - status of pages: " << pages.size() << endl;
237 for (page=pages.begin();page!=pages.end(); page++) {
238 if (gVerbosity>0) (*page)->Print("");
239 }
240
241 if (level>0) {
242 if ((iResult=releaseBuffers(descriptions, pages, level-1))<0) {
243 cerr << "failed to release buffers" << endl;
244 return iResult;
245 }
246 }
247 }
248
249 if (gVerbosity>0)
250 cout << "status of released pages:" << endl;
251 for (page=pages.begin();page!=pages.end(); page++) {
252 if (gVerbosity>0) (*page)->Print("");
253 if ((*page)->IsUsed()) {
254 cerr << "page " << *page << " has used buffers" << endl;
255 return -EFAULT;
256 }
257 if ((*page)->Size()!=(*page)->Capacity()) {
258 cerr << "page " << *page << " not completely released" << endl;
259 return -EFAULT;
260 }
261 if ((*page)->IsFragmented()) {
262 cerr << "page " << *page << " is still fragmented" << endl;
263 return -EFAULT;
264 }
265 }
266 }
267
268 return 0;
269}
270
271/**
272 * Get a random number in the given range.
273 */
274int GetRandom(int min, int max)
275{
276 if (max-min<2) return min;
277 static TRandom rand;
278 static bool seedSet=false;
279 if (!seedSet) {
280 TDatime dt;
281 rand.SetSeed(dt.Get());
282 seedSet=true;
283 }
284 return min+rand.Integer(max-min);
285}
286
287/////////////////////////////////////////////////////////////////////////
288/////////////////////////////////////////////////////////////////////////
289//
290// main functions
291
292int main(int /*argc*/, const char** /*argv*/)
293{
294 int iResult=0;
295 iResult=testAliHLTDataBuffer();
296 return iResult;
297}