1 | /*
|
---|
2 | * Copyright 2007, Haiku, Inc. All rights reserved.
|
---|
3 | * Distributed under the terms of the MIT License.
|
---|
4 | *
|
---|
5 | * Authors:
|
---|
6 | * Vasilis Kaoutsis, kaoutsis@sch.gr
|
---|
7 | */
|
---|
8 |
|
---|
9 |
|
---|
10 | /*! \brief A simple test of areas creation,
|
---|
11 | and deletion, for testing the time-costs.
|
---|
12 | */
|
---|
13 |
|
---|
14 |
|
---|
15 | #include <Application.h>
|
---|
16 | #include <OS.h>
|
---|
17 | #include <String.h>
|
---|
18 |
|
---|
19 | #include <stdio.h>
|
---|
20 | #include <stdlib.h>
|
---|
21 | #include <string.h>
|
---|
22 | #include <sys/utsname.h>
|
---|
23 | #include <sys/time.h>
|
---|
24 | #include <sys/times.h>
|
---|
25 | #include <unistd.h>
|
---|
26 |
|
---|
27 | //#define TRACE_ALL
|
---|
28 | #ifdef TRACE_ALL
|
---|
29 | # define TRACE_AREA_CREAT_DELETE
|
---|
30 | # define TRACE_NULL_FUNCTION
|
---|
31 | # define TRACE_ITERATIONS
|
---|
32 | # define TRACE_PAGE_TOUCHING
|
---|
33 | #endif
|
---|
34 |
|
---|
35 | #ifdef TRACE_AREA_CREAT_DELETE
|
---|
36 | # define TR_AR_CR_DL(x) fprintf x
|
---|
37 | #else
|
---|
38 | # define TR_AR_CR_DL(x) ;
|
---|
39 | #endif
|
---|
40 |
|
---|
41 | #ifdef TRACE_NULL_FUNCTION
|
---|
42 | # define TR_NL_FC(x) fprintf x
|
---|
43 | #else
|
---|
44 | # define TR_NL_FC(x) ;
|
---|
45 | #endif
|
---|
46 |
|
---|
47 | #ifdef TRACE_ITERATIONS
|
---|
48 | # define TR_ITER(x) fprintf x
|
---|
49 | #else
|
---|
50 | # define TR_ITER(x) ;
|
---|
51 | #endif
|
---|
52 |
|
---|
53 | #ifdef TRACE_PAGE_TOUCHING
|
---|
54 | # define TR_TOUCH(x) fprintf x
|
---|
55 | #else
|
---|
56 | # define TR_TOUCH(x) ;
|
---|
57 | #endif
|
---|
58 |
|
---|
59 | void DoNothing()
|
---|
60 | {
|
---|
61 | }
|
---|
62 |
|
---|
63 | enum measuring_t {
|
---|
64 | kUsingGettimeofday = 1,
|
---|
65 | kUsingSystemTime,
|
---|
66 | kAll
|
---|
67 | };
|
---|
68 |
|
---|
69 | const char* kSignature = "application/x-vnd.Haiku.cmd-area_creation_test";
|
---|
70 | const char* kProgramName = "area_creation_test";
|
---|
71 |
|
---|
72 | const int32 kErrorInitFail = 127;
|
---|
73 | const int32 kErrorArgumentsFail = 126;
|
---|
74 |
|
---|
75 |
|
---|
76 | class AreaTestApplication;
|
---|
77 | typedef status_t (AreaTestApplication::*PMFI)(uint32 iterations);
|
---|
78 |
|
---|
79 |
|
---|
80 | class AreaTestApplication : public BApplication {
|
---|
81 | public:
|
---|
82 | AreaTestApplication();
|
---|
83 | virtual ~AreaTestApplication() { }
|
---|
84 |
|
---|
85 | virtual void ReadyToRun();
|
---|
86 | virtual void ArgvReceived(int32 argc, char** argv);
|
---|
87 |
|
---|
88 | bool GoodArguments() const { return fOk; }
|
---|
89 | status_t AreaCreate(uint32 numOfAreas);
|
---|
90 | status_t DeleteAllAreas(uint32 numOfAreas);
|
---|
91 | status_t DeleteEvenAreas(uint32 numOfAreas);
|
---|
92 | status_t DeleteOddAreas(uint32 numOfAreas);
|
---|
93 | status_t TouchPages(uint32 numOfAreas);
|
---|
94 | status_t NullFunction(uint32 counter);
|
---|
95 | unsigned long UsingGettimeofday(PMFI);
|
---|
96 | bigtime_t UsingSystemTime(PMFI);
|
---|
97 | void PrintResults(measuring_t measuringType, PMFI);
|
---|
98 |
|
---|
99 | private:
|
---|
100 | void _Usage() const;
|
---|
101 |
|
---|
102 | private:
|
---|
103 | bool fOk;
|
---|
104 | void* fStartingAddress;
|
---|
105 | uint32 fAddressSpec;
|
---|
106 | uint32 fRequestedSize;
|
---|
107 | uint32 fLockSpec;
|
---|
108 | uint32 fProtection;
|
---|
109 | uint32 fNumOfPages;
|
---|
110 | BString fArchitecture;
|
---|
111 | BString fFileName;
|
---|
112 | uint32 fResultSum;
|
---|
113 | uint32 fResult;
|
---|
114 | uint32 fIterations;
|
---|
115 | uint32 fNumOfAreas;
|
---|
116 | uint32 fAreaIdTag[5000];
|
---|
117 | uint32 fAreaPrepIdTag[5000];
|
---|
118 | uint8* fAreaAddress[5000];
|
---|
119 | bool fFragmentationTest;
|
---|
120 |
|
---|
121 | };
|
---|
122 |
|
---|
123 |
|
---|
124 | AreaTestApplication::AreaTestApplication()
|
---|
125 | : BApplication(kSignature),
|
---|
126 | fOk(false),
|
---|
127 | fStartingAddress(NULL),
|
---|
128 | fAddressSpec(0),
|
---|
129 | fRequestedSize(0),
|
---|
130 | fLockSpec(0),
|
---|
131 | fProtection(0),
|
---|
132 | fNumOfPages(0),
|
---|
133 | fResultSum(0),
|
---|
134 | fResult(0),
|
---|
135 | fIterations(fNumOfAreas),
|
---|
136 | fFragmentationTest(false)
|
---|
137 | {
|
---|
138 | }
|
---|
139 |
|
---|
140 |
|
---|
141 | void
|
---|
142 | AreaTestApplication::_Usage() const
|
---|
143 | {
|
---|
144 | fprintf(stdout,"\nUsage:\n"
|
---|
145 | "%s [pages number] [address spec] [lock spec] [protection] \n\n"
|
---|
146 | " [number of areas to create] [fragm] \n\n"
|
---|
147 | "\t [pages number] is an integer value.\n"
|
---|
148 | "\tBy providing the number of pages, you provide the size of the area.\n"
|
---|
149 | "\tThe size of the area is calculating as: B_PAGE_SIZE * numOfPages\n"
|
---|
150 | "\tB_PAGE_SIZE has the value of one page or 4096 bytes.\n"
|
---|
151 | "\tFor example if you want the size of the area to be 40 kB.\n"
|
---|
152 | "\tyour argument have to be 10, since 4096 * 10 is 40960 bytes or 40 kB.\n"
|
---|
153 | "\n"
|
---|
154 | "\t [addreess spec] is one of the following values:\n"
|
---|
155 | "\tB_EXACT_ADDRESS, B_BASE_ADDRESS, B_ANY_ADDRESS, B_ANY_KERNEL_ADDRESS\n\n"
|
---|
156 | "\t [lock spec] is one of the following values:\n"
|
---|
157 | "\tB_NO_LOCK, B_LAZY_LOCK, B_FULL_LOCK, B_CONTIGUOUS, B_LOMEM\n\n"
|
---|
158 | "\t [protection] is one of the following values:\n"
|
---|
159 | "\tB_READ_AREA, B_WRITE_AREA, B_READ_AREA | B_WRITE_AREA\n\n"
|
---|
160 | "\t [number of areas to create] max value is currently 5000 \n\n"
|
---|
161 | "\t fragm: run the fragmentation test, optional\n"
|
---|
162 | "An example:\n"
|
---|
163 | "area_creation_test.beos 10 B_ANY_ADDRESS B_NO_LOCK 'B_WRITE_AREA|B_READ_AREA' 4000\n"
|
---|
164 | "will create 4000 areas that each one will have 10 pages size.\n"
|
---|
165 | "Another example:\n"
|
---|
166 | "area_creation_test.beos 10 B_ANY_ADDRESS B_NO_LOCK 'B_WRITE_AREA|B_READ_AREA' 4000 fragm\n"
|
---|
167 | "will create 4000 areas that each one will have 10 pages size,\n"
|
---|
168 | "plus the fragmentation test\n"
|
---|
169 | , kProgramName);
|
---|
170 | }
|
---|
171 |
|
---|
172 |
|
---|
173 | void
|
---|
174 | AreaTestApplication::PrintResults(measuring_t measuringType, PMFI BenchFunction)
|
---|
175 | {
|
---|
176 | switch (measuringType) {
|
---|
177 | static bool usingAll;
|
---|
178 |
|
---|
179 | case kAll:
|
---|
180 | usingAll = true;
|
---|
181 |
|
---|
182 | case kUsingGettimeofday:
|
---|
183 | fprintf(stdout, "gettimeofday");
|
---|
184 | fResultSum = UsingGettimeofday(BenchFunction);
|
---|
185 |
|
---|
186 | fResult = fResultSum / fIterations;
|
---|
187 | if (fResult == 0) { // result is ns
|
---|
188 | fResult = 1000 * fResultSum / fIterations;
|
---|
189 | fprintf(stdout, "%11ld ns", fResult);
|
---|
190 | } else
|
---|
191 | fprintf(stdout, "%11ld µs.", fResult);
|
---|
192 |
|
---|
193 | if (usingAll == false)
|
---|
194 | break;
|
---|
195 | fprintf(stdout, "\n");
|
---|
196 |
|
---|
197 | case kUsingSystemTime:
|
---|
198 | fprintf(stdout, "system_time");
|
---|
199 | fResultSum = UsingSystemTime(BenchFunction);
|
---|
200 |
|
---|
201 | fResult = fResultSum / fIterations;
|
---|
202 | if (fResult == 0) { // result is ns
|
---|
203 | fResult = (1000 * fResultSum) / fIterations;
|
---|
204 | fprintf(stdout, "%12ld ns", fResult);
|
---|
205 | } else
|
---|
206 | fprintf(stdout, "%12ld µs.", fResult);
|
---|
207 |
|
---|
208 | if (usingAll == false)
|
---|
209 | break;
|
---|
210 | fprintf(stdout, "\n");
|
---|
211 |
|
---|
212 | }
|
---|
213 | fprintf(stdout, "\n");
|
---|
214 | }
|
---|
215 |
|
---|
216 |
|
---|
217 | void
|
---|
218 | AreaTestApplication::ArgvReceived(int32 argc, char** argv)
|
---|
219 | {
|
---|
220 | if (argc < 2 || argc > 7)
|
---|
221 | return; // bad arguments number!
|
---|
222 |
|
---|
223 | fNumOfPages = atoi(argv[1]);
|
---|
224 |
|
---|
225 | if (argc < 6)
|
---|
226 | fNumOfAreas = 5000;
|
---|
227 | else
|
---|
228 | fNumOfAreas = atoi(argv[5]);
|
---|
229 |
|
---|
230 | if (fNumOfAreas > 5000) {
|
---|
231 | fprintf(stdout, "Currently the test doesn't support the creation of more than 5000 areas!");
|
---|
232 | return;
|
---|
233 | }
|
---|
234 |
|
---|
235 | fIterations = fNumOfAreas;
|
---|
236 |
|
---|
237 | if (argc == 7 && argv[6][0] == 'f'
|
---|
238 | && argv[6][1] == 'r'
|
---|
239 | && argv[6][2] == 'a'
|
---|
240 | && argv[6][3] == 'g'
|
---|
241 | && argv[6][4] == 'm')
|
---|
242 | fFragmentationTest = true;
|
---|
243 |
|
---|
244 | // get the addressSpec
|
---|
245 | BString addressSpecString(argv[2]);
|
---|
246 | if (addressSpecString == "B_EXACT_ADDRESS")
|
---|
247 | fAddressSpec = 1;
|
---|
248 | else if (addressSpecString == "B_BASE_ADDRESS")
|
---|
249 | fAddressSpec = 2;
|
---|
250 | else if (addressSpecString == "B_ANY_ADDRESS")
|
---|
251 | fAddressSpec = 0;
|
---|
252 | else if (addressSpecString == "B_ANY_KERNEL_ADDRESS")
|
---|
253 | fAddressSpec = 4;
|
---|
254 | else {
|
---|
255 | fprintf(stdout, "Wrong address specification: %s\n"
|
---|
256 | "\taddreess specification is one of the following values:\n"
|
---|
257 | "\tB_EXACT_ADDRESS, B_BASE_ADDRESS, B_ANY_ADDRESS, B_ANY_KERNEL_ADDRESS\n\n", argv[2]);
|
---|
258 | return;
|
---|
259 | }
|
---|
260 |
|
---|
261 | // get the lock specification
|
---|
262 | BString lockSpecString(argv[3]);
|
---|
263 | if (lockSpecString == "B_NO_LOCK")
|
---|
264 | fLockSpec = 0;
|
---|
265 | else if (lockSpecString == "B_LAZY_LOCK")
|
---|
266 | fLockSpec = 1;
|
---|
267 | else if (lockSpecString == "B_FULL_LOCK")
|
---|
268 | fLockSpec = 2;
|
---|
269 | else if (lockSpecString == "B_CONTIGUOUS")
|
---|
270 | fLockSpec = 3;
|
---|
271 | else if (lockSpecString == "B_LOMEM")
|
---|
272 | fLockSpec = 4;
|
---|
273 | else {
|
---|
274 | fprintf(stdout, "Wrong lock specification: %s\n"
|
---|
275 | "\tlock specification is one of the following values:\n"
|
---|
276 | "\tB_NO_LOCK, B_LAZY_LOCK, B_FULL_LOCK, B_CONTIGUOUS, B_LOMEM\n\n", argv[3]);
|
---|
277 | return;
|
---|
278 | }
|
---|
279 |
|
---|
280 | // get the protection flags
|
---|
281 | BString protectionFlagStr(argv[4]);
|
---|
282 | if (protectionFlagStr == "B_READ_AREA") {
|
---|
283 | fprintf(stdout,
|
---|
284 | "WARNING: area is read only.\n"
|
---|
285 | "Any attempt for writing should be fail!\n"
|
---|
286 | "Expecting crash!\n");
|
---|
287 | fProtection = 1;
|
---|
288 | } else if (protectionFlagStr == "B_WRITE_AREA")
|
---|
289 | fProtection = 2;
|
---|
290 | else if (protectionFlagStr == "B_READ_AREA | B_WRITE_AREA"
|
---|
291 | || protectionFlagStr == "B_READ_AREA|B_WRITE_AREA"
|
---|
292 | || protectionFlagStr == "B_READ_AREA |B_WRITE_AREA"
|
---|
293 | || protectionFlagStr == "B_READ_AREA| B_WRITE_AREA"
|
---|
294 | || protectionFlagStr == "B_WRITE_AREA | B_READ_AREA"
|
---|
295 | || protectionFlagStr == "B_WRITE_AREA|B_READ_AREA"
|
---|
296 | || protectionFlagStr == "B_WRITE_AREA |B_READ_AREA"
|
---|
297 | || protectionFlagStr == "B_WRITE_AREA| B_READ_AREA")
|
---|
298 | fProtection = 3;
|
---|
299 | else {
|
---|
300 | fprintf(stdout, "Wrong protection flags: %s\n"
|
---|
301 | "\t protection is one of the following values:\n"
|
---|
302 | "\tB_READ_AREA, B_WRITE_AREA, B_READ_AREA | B_WRITE_AREA\n", argv[4]);
|
---|
303 | return;
|
---|
304 | }
|
---|
305 |
|
---|
306 | fOk = true;
|
---|
307 | }
|
---|
308 |
|
---|
309 |
|
---|
310 | status_t
|
---|
311 | AreaTestApplication::AreaCreate(uint32 numOfAreas)
|
---|
312 | {
|
---|
313 | TR_AR_CR_DL((stdout, "numOfAreas is %ld\n", numOfAreas));
|
---|
314 | char error;
|
---|
315 | if (numOfAreas == 0) {
|
---|
316 | error = B_ERROR;
|
---|
317 | throw error;
|
---|
318 | }
|
---|
319 |
|
---|
320 | static bool fragmPreparation = true;
|
---|
321 |
|
---|
322 | for (uint32 indx = 0 ; indx < numOfAreas; indx++) {
|
---|
323 | area_id areaSpace;
|
---|
324 | areaSpace = create_area("AreaSpace", &fStartingAddress, fAddressSpec,
|
---|
325 | fRequestedSize, fLockSpec, fProtection);
|
---|
326 |
|
---|
327 | if (fFragmentationTest && fragmPreparation) {
|
---|
328 | fAreaPrepIdTag[indx] = fAreaIdTag[indx] = areaSpace;
|
---|
329 | // fAreaPrepIdTag is an array that will be used
|
---|
330 | // for deleting the remaining preparation areas
|
---|
331 | } else
|
---|
332 | fAreaIdTag[indx] = areaSpace;
|
---|
333 |
|
---|
334 | TR_AR_CR_DL((stdout, "fAreaIdTag[%ld] is %ld at %p\n", indx, fAreaIdTag[indx],
|
---|
335 | fStartingAddress));
|
---|
336 |
|
---|
337 | if (areaSpace < 0) {
|
---|
338 | fprintf(stdout, "Fail to create area!\n");
|
---|
339 | fprintf(stdout, "fAreaIdTag[%ld] is %ld at %p\n", indx, fAreaIdTag[indx],
|
---|
340 | fStartingAddress);
|
---|
341 | fprintf(stdout, "areaSpace is %ld\n", areaSpace);
|
---|
342 | throw (area_id)(areaSpace);
|
---|
343 | }
|
---|
344 |
|
---|
345 | fAreaAddress[indx] = static_cast<uint8*>(fStartingAddress);
|
---|
346 | fStartingAddress = static_cast<uint8*>(fStartingAddress) + fRequestedSize;
|
---|
347 | }
|
---|
348 |
|
---|
349 | fStartingAddress = static_cast<uint8*>(fAreaAddress[0]);
|
---|
350 |
|
---|
351 | if (fFragmentationTest)
|
---|
352 | fragmPreparation = false;
|
---|
353 |
|
---|
354 | return B_OK;
|
---|
355 | }
|
---|
356 |
|
---|
357 |
|
---|
358 | status_t
|
---|
359 | AreaTestApplication::TouchPages(uint32 numOfAreas)
|
---|
360 | {
|
---|
361 | // Touching requested page(s) of each area.
|
---|
362 |
|
---|
363 | // although it might seems not exact
|
---|
364 | // this function measures only the writing to pages (page fault handling)
|
---|
365 | // namely this: *areaPointer = 1;
|
---|
366 | // comment out the writing, this function
|
---|
367 | // for 500 areas (100 pages per area) costs 310 nanosec per area!
|
---|
368 |
|
---|
369 | for (uint32 index = 0; index < numOfAreas; index++) {
|
---|
370 | uint8* areaPointer = fAreaAddress[index];
|
---|
371 | for (uint32 indx = 0 ; indx < fNumOfPages; indx++) {
|
---|
372 | *areaPointer = 1;
|
---|
373 | TR_TOUCH((stdout, "fAreaAddress[%d] is %p, fNumOfPages are %d,"
|
---|
374 | " writing at %p, the value of %d\n", index, fAreaAddress[index], fNumOfPages,
|
---|
375 | areaPointer, *areaPointer));
|
---|
376 | areaPointer = areaPointer + B_PAGE_SIZE;
|
---|
377 | }
|
---|
378 | }
|
---|
379 | return B_OK;
|
---|
380 | }
|
---|
381 |
|
---|
382 |
|
---|
383 | status_t
|
---|
384 | AreaTestApplication::DeleteAllAreas(uint32 numOfAreas)
|
---|
385 | {
|
---|
386 | status_t error;
|
---|
387 | for (uint32 index = 0 ; index < numOfAreas; index++) {
|
---|
388 | TR_AR_CR_DL((stdout, "deleting area with fAreaIdTag[%ld] %ld \n", index, fAreaIdTag[index]));
|
---|
389 | error = delete_area(fAreaIdTag[index]);
|
---|
390 | if (error == B_ERROR) {
|
---|
391 | fprintf(stdout, "Couldn't delete area with fAreaIdTag[%ld] %ld \n", index, fAreaIdTag[index]);
|
---|
392 | throw (status_t)(error);
|
---|
393 | }
|
---|
394 | }
|
---|
395 | return B_OK;
|
---|
396 | }
|
---|
397 |
|
---|
398 |
|
---|
399 | status_t
|
---|
400 | AreaTestApplication::DeleteEvenAreas(uint32 numOfAreas)
|
---|
401 | {
|
---|
402 | status_t error;
|
---|
403 | for (uint32 index = 0 ; index < numOfAreas; index += 2) {
|
---|
404 | TR_AR_CR_DL((stdout, "deleting area with fAreaPrepIdTag[%ld] %ld \n", index, fAreaPrepIdTag[index]));
|
---|
405 | error = delete_area(fAreaPrepIdTag[index]);
|
---|
406 | if (error == B_ERROR) {
|
---|
407 | fprintf(stdout, "Couldn't delete area with fAreaPrepIdTag[%ld] %ld \n", index, fAreaPrepIdTag[index]);
|
---|
408 | throw (status_t)(error);
|
---|
409 | }
|
---|
410 | }
|
---|
411 | return B_OK;
|
---|
412 | }
|
---|
413 |
|
---|
414 |
|
---|
415 | status_t
|
---|
416 | AreaTestApplication::DeleteOddAreas(uint32 numOfAreas)
|
---|
417 | {
|
---|
418 | status_t error;
|
---|
419 | for (uint32 index = 1 ; index < numOfAreas; index += 2) {
|
---|
420 | TR_AR_CR_DL((stdout, "deleting area with fAreaPrepIdTag[%ld] %ld \n", index, fAreaPrepIdTag[index]));
|
---|
421 | error = delete_area(fAreaPrepIdTag[index]);
|
---|
422 | if (error == B_ERROR) {
|
---|
423 | fprintf(stdout, "Couldn't delete area with fAreaPrepIdTag[%ld] %ld \n", index, fAreaPrepIdTag[index]);
|
---|
424 | throw (status_t)(error);
|
---|
425 | }
|
---|
426 | }
|
---|
427 | return B_OK;
|
---|
428 | }
|
---|
429 |
|
---|
430 | status_t
|
---|
431 | AreaTestApplication::NullFunction(uint32 counter)
|
---|
432 | {
|
---|
433 | fIterations = 5000000;
|
---|
434 | TR_NL_FC((stdout, "inside NullFunction, counter is %ld.\n", counter));
|
---|
435 | // the only usefulness of this function
|
---|
436 | // is to measure function call overhead
|
---|
437 | for (uint32 index = 0; index < 5000000; index++)
|
---|
438 | DoNothing();
|
---|
439 |
|
---|
440 | return B_OK;
|
---|
441 | }
|
---|
442 |
|
---|
443 |
|
---|
444 | unsigned long
|
---|
445 | AreaTestApplication::UsingGettimeofday(PMFI BenchFunction)
|
---|
446 | {
|
---|
447 | struct timeval before;
|
---|
448 | struct timeval after;
|
---|
449 | unsigned long elapsed;
|
---|
450 |
|
---|
451 | gettimeofday(&before, NULL);
|
---|
452 | (this->*BenchFunction)(fIterations);
|
---|
453 | gettimeofday(&after, NULL);
|
---|
454 |
|
---|
455 |
|
---|
456 | elapsed = 1000000 * (after.tv_sec - before.tv_sec);
|
---|
457 | elapsed += after.tv_usec - before.tv_usec;
|
---|
458 | TR_ITER((stdout, "fIterations is %d", fIterations));
|
---|
459 | return elapsed;
|
---|
460 | }
|
---|
461 |
|
---|
462 |
|
---|
463 | bigtime_t
|
---|
464 | AreaTestApplication::UsingSystemTime(PMFI BenchFunction)
|
---|
465 | {
|
---|
466 | bigtime_t start;
|
---|
467 | bigtime_t stop;
|
---|
468 |
|
---|
469 | start = system_time();
|
---|
470 | (this->*BenchFunction)(fIterations);
|
---|
471 | stop = system_time();
|
---|
472 |
|
---|
473 | TR_ITER((stdout, "fIterations is %d", fIterations));
|
---|
474 | return stop - start;
|
---|
475 | }
|
---|
476 |
|
---|
477 |
|
---|
478 | void
|
---|
479 | AreaTestApplication::ReadyToRun()
|
---|
480 | {
|
---|
481 | if (GoodArguments()) {
|
---|
482 |
|
---|
483 | // create the area
|
---|
484 | area_id areaSpace;
|
---|
485 | fRequestedSize = B_PAGE_SIZE * fNumOfPages; // B_PAGE_SIZE = 4096 bytes
|
---|
486 | void* startingAddress = (void*)fRequestedSize;
|
---|
487 | areaSpace = create_area("AreaSpace", &startingAddress, fAddressSpec,
|
---|
488 | fRequestedSize, fLockSpec, fProtection);
|
---|
489 |
|
---|
490 |
|
---|
491 | // errors checking
|
---|
492 |
|
---|
493 | if (areaSpace < 0)
|
---|
494 | fprintf(stdout, "The system said: %s. Error code number is %ld\n", strerror(areaSpace), areaSpace);
|
---|
495 |
|
---|
496 | if (areaSpace == B_BAD_VALUE) {
|
---|
497 | // SUGESTION: here we may want in the future to extend our create_area
|
---|
498 | // implemetation for the bad values,
|
---|
499 | // to see what excactly was going on.
|
---|
500 | fprintf(stdout, "Bad argument value.\n"
|
---|
501 | "Possible errors:\n"
|
---|
502 | " a) You passed an unrecognized constant for addr_spec or lock\n"
|
---|
503 | " b) the addr or size value isn't a multiple of B_PAGE_SIZE,\n"
|
---|
504 | " c) you set addr_spec to B_EXACT_ADDRESS but the address request couldn't\n"
|
---|
505 | " be fulfilled. \n");
|
---|
506 | Quit();
|
---|
507 | return;
|
---|
508 | }
|
---|
509 |
|
---|
510 | if (areaSpace == B_NO_MEMORY) {
|
---|
511 | if (fRequestedSize < (900 * 4096))
|
---|
512 | fprintf(stdout, "Requested size %ld KB is to big!\n", fRequestedSize / 1024);
|
---|
513 | else
|
---|
514 | fprintf(stdout, "Requested size %ld MB is to big!\n", fRequestedSize / (1024 * 1024));
|
---|
515 | Quit();
|
---|
516 | return;
|
---|
517 | }
|
---|
518 |
|
---|
519 | if (areaSpace == B_ERROR) {
|
---|
520 | fprintf(stdout, "A system error prevented the area from being created.\n");
|
---|
521 | Quit();
|
---|
522 | return;
|
---|
523 | }
|
---|
524 |
|
---|
525 |
|
---|
526 | // area has pass errors checking, start the tests
|
---|
527 |
|
---|
528 | delete_area(areaSpace);
|
---|
529 |
|
---|
530 | // show sysname and release
|
---|
531 | struct utsname osName;
|
---|
532 | status_t error = uname(&osName);
|
---|
533 | if (error != B_ERROR)
|
---|
534 | fprintf(stdout, "\nSysname: %s\trelease: %s\tversion: %s\n",
|
---|
535 | osName.sysname, osName.release, osName.version);
|
---|
536 | else {
|
---|
537 | fprintf(stdout, "\nUnable to get system name and release!\n");
|
---|
538 | fprintf(stdout, "Error was %s, and error number is %d\n", strerror(error), error);
|
---|
539 | }
|
---|
540 |
|
---|
541 | // show wheather we are running the fragmentation
|
---|
542 | // test or not
|
---|
543 | if (fFragmentationTest) {
|
---|
544 | fprintf(stdout, "Running the fragmentation test: \n"
|
---|
545 | "Creating preparation areas; will be deleted at even indices.\n"
|
---|
546 | "(The remaining areas will be deleted after the measuring tests!)\n");
|
---|
547 | }
|
---|
548 |
|
---|
549 | // show user's request
|
---|
550 | if (fRequestedSize < (1024 * 1024))
|
---|
551 | fprintf(stdout,
|
---|
552 | "\nRequested %ld areas. Area's size will be %.2f KB (%d pages).\n",
|
---|
553 | fNumOfAreas, fRequestedSize / double(1024), fNumOfPages);
|
---|
554 | else
|
---|
555 | fprintf(stdout,
|
---|
556 | "\nRequested %ld areas. Area's size will be %.2f MB (%d pages).\n",
|
---|
557 | fNumOfAreas, fRequestedSize / double(1024 * 1024), fNumOfPages);
|
---|
558 |
|
---|
559 | // open the file *.data
|
---|
560 | // for writing some infos
|
---|
561 | FILE* pointerToDataFile;
|
---|
562 | BString dataFileName(fFileName.String());
|
---|
563 | dataFileName += ".data";
|
---|
564 | pointerToDataFile = fopen(dataFileName.String(), "w");
|
---|
565 |
|
---|
566 | try {
|
---|
567 | AreaCreate(fNumOfAreas);
|
---|
568 |
|
---|
569 | char* showAddress = static_cast<char*>(fStartingAddress);
|
---|
570 | for (uint32 index = 0; index < fNumOfAreas; index++) {
|
---|
571 | fprintf(pointerToDataFile, "fAreaIdTag[%ld] area_id is %ld starting at %p\n",
|
---|
572 | index, fAreaIdTag[index], showAddress);
|
---|
573 | showAddress = showAddress + fRequestedSize;
|
---|
574 | }
|
---|
575 |
|
---|
576 | } catch(char& error) {
|
---|
577 | fprintf(stdout, "abording time tests, reason: number of areas is 0!\n");
|
---|
578 | fclose(pointerToDataFile);
|
---|
579 | Quit();
|
---|
580 | return;
|
---|
581 | } catch(area_id& areaIdValue) {
|
---|
582 | fprintf(stdout, "abording time tests!\n");
|
---|
583 | fprintf(stdout, "areaIdValue is %ld \n", areaIdValue);
|
---|
584 | fclose(pointerToDataFile);
|
---|
585 | DeleteAllAreas(fNumOfAreas);
|
---|
586 | Quit();
|
---|
587 | return;
|
---|
588 | }
|
---|
589 |
|
---|
590 | if (fFragmentationTest) {
|
---|
591 | try {
|
---|
592 | DeleteEvenAreas(fNumOfAreas);
|
---|
593 | } catch(status_t& deleteAreaError) {
|
---|
594 | fprintf(stdout, "Abording time tests!\n");
|
---|
595 | fprintf(stdout, "deleteAreaError is %ld\n", deleteAreaError);
|
---|
596 | }
|
---|
597 | } else {
|
---|
598 | try {
|
---|
599 | DeleteAllAreas(fNumOfAreas);
|
---|
600 | } catch(status_t& deleteAreaError) {
|
---|
601 | fprintf(stdout, "Abording time tests!\n");
|
---|
602 | fprintf(stdout, "deleteAreaError is %ld\n", deleteAreaError);
|
---|
603 | }
|
---|
604 | }
|
---|
605 |
|
---|
606 | fclose(pointerToDataFile);
|
---|
607 |
|
---|
608 | fprintf(stdout, "\n");
|
---|
609 | fprintf(stdout, "------------------------------------------------------------------\n");
|
---|
610 | fprintf(stdout, " Measuring the time of area's creation and deletion\n");
|
---|
611 | fprintf(stdout, "------------------------------------------------------------------\n");
|
---|
612 |
|
---|
613 | // Print results
|
---|
614 | try {
|
---|
615 | fprintf(stdout, "%1s %15s", "TimeFunction", "AreaCreate\n");
|
---|
616 | PrintResults(kUsingGettimeofday, (&AreaTestApplication::AreaCreate));
|
---|
617 | fprintf(stdout, "%1s %15s", "TimeFunction", "TouchPages\n");
|
---|
618 | PrintResults(kUsingGettimeofday, (&AreaTestApplication::TouchPages));
|
---|
619 | fprintf(stdout, "%1s %15s", "TimeFunction", "DeleteAllAreas\n");
|
---|
620 | PrintResults(kUsingGettimeofday, (&AreaTestApplication::DeleteAllAreas));
|
---|
621 | fprintf(stdout, "------------------------------------\n");
|
---|
622 | } catch(area_id& areaIdVal) {
|
---|
623 | fprintf(stdout, "abording time tests!\n");
|
---|
624 | fprintf(stdout, "areaIdVal is %ld \n", areaIdVal);
|
---|
625 | } catch(status_t& deleteAreaError) {
|
---|
626 | fprintf(stdout, "Abording time tests!\n");
|
---|
627 | fprintf(stdout, "deleteAreaError is %ld\n", deleteAreaError);
|
---|
628 | }
|
---|
629 |
|
---|
630 | // the following is only to keep an eye to the NuullFunctions timings
|
---|
631 | //PrintResults(kAll, (&AreaTestApplication::NullFunction));
|
---|
632 |
|
---|
633 | if (fFragmentationTest) {
|
---|
634 | try {
|
---|
635 | DeleteOddAreas(fNumOfAreas);
|
---|
636 | } catch(status_t& deleteAreaError) {
|
---|
637 | fprintf(stdout, "Abording time tests!\n");
|
---|
638 | fprintf(stdout, "deleteAreaError is %ld\n", deleteAreaError);
|
---|
639 | }
|
---|
640 | }
|
---|
641 |
|
---|
642 | } else
|
---|
643 | _Usage();
|
---|
644 |
|
---|
645 | Quit();
|
---|
646 | }
|
---|
647 |
|
---|
648 |
|
---|
649 | // #pragma mark -
|
---|
650 |
|
---|
651 |
|
---|
652 | int
|
---|
653 | main(int32 argc, const char** argv)
|
---|
654 | {
|
---|
655 | AreaTestApplication app;
|
---|
656 | if (app.InitCheck() != B_OK)
|
---|
657 | return kErrorInitFail;
|
---|
658 |
|
---|
659 | app.Run();
|
---|
660 | if (!app.GoodArguments())
|
---|
661 | return kErrorArgumentsFail;
|
---|
662 |
|
---|
663 | return 0;
|
---|
664 | }
|
---|