]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/testsuite/gprofng.display/synprog/iosyn.c
gprofng: a new GNU profiler
[thirdparty/binutils-gdb.git] / gprofng / testsuite / gprofng.display / synprog / iosyn.c
1 /* Copyright (C) 2021 Free Software Foundation, Inc.
2 Contributed by Oracle.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <strings.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/mman.h>
31 #include <sys/time.h>
32
33 #include "stopwatch.h"
34
35 /* parameters defining various tasks */
36 #define BUFSIZE 16384
37 #define NBLKS 1024
38
39 #define SIZE ((int)(16*1024*1024))
40 unsigned buffer[SIZE];
41 extern FILE *fid2;
42
43 /* ioerror - do some erroneous file IO operations */
44 int
45 ioerror ()
46 {
47 FILE *fp; /* FILE pointer for stdio */
48 char *fname = NULL;
49 char *ptr = NULL;
50 int fd; /* file descriptor for raw IO */
51 int fd2; /* file descriptor for raw IO */
52 int stat;
53 char buf[BUFSIZE];
54 unsigned long size = 0;
55 char sfn[23] = "";
56
57 /* Log the regular read */
58 wlog ("start of ioerror", NULL);
59
60 /* fname is set to NULL.
61 Use various calls to create
62 a file.
63 */
64
65 fd = creat (fname, 0666);
66 fd = open (fname, 0666);
67 fd2 = 0;
68 fd = openat (fd2, fname, 0666);
69 fp = fopen (fname, "w");
70 fp = fopen ("/iotest", "w");
71 fp = NULL;
72 stat = fflush (fp);
73 stat = chmod (fname, 755);
74 stat = access (fname, 755);
75 fname = "/tmp/synprogXXXXXX";
76 strncpy (sfn, fname, sizeof (sfn));
77 fd = mkstemp (sfn);
78 stat = unlink (sfn);
79 stat = rename (fname, NULL);
80 unlink (fname);
81 fp = fopen (fname, "w");
82 stat = fclose (fp);
83 stat = fread (buf, 100, 2, fp);
84 stat = fwrite (buf, 100, 2, fp);
85 ptr = fgets (buf, size, fp);
86 read (10000, buf, 100);
87 write (10000, buf, 100);
88 stat = unlink (fname);
89 fname = NULL;
90 stat = mkdir (fname, 755);
91 stat = unlink (fname);
92 /*
93 These functions cannot be executed
94 if the File Pointer (fp) is set
95 to NULL. They generate segv failure
96 in actual call not inside of
97 the wrapper.
98
99 stat = fread(buf, size, 2, fp);
100 stat = fwrite(buf, size, 2, fp);
101 ptr = fgets(buf, size, fp);
102 stat = fputs(buf, fp);
103 stat = fprintf(fp, "%d\n", size);
104 stat = fseek(fp, size, size);
105 rewind(fp);
106 ftell(fp);
107 fpos_t pos;
108 stat = fsetpos(fp, &pos);
109 stat = fgetpos(fp, &pos);
110 */
111 return 0;
112 }
113
114 /*=======================================================*/
115
116 /* iofile - do some file io operations */
117 int
118 iofile ()
119 {
120 FILE *fp; /* FILE pointer for stdio */
121 int k; /* temp value for loop */
122 int i;
123 char *buf;
124 hrtime_t start;
125 hrtime_t vstart;
126 char sfn[23] = "";
127 char *fname = "/tmp/synprogXXXXXX";
128 int ret;
129 int readCnt = 0;
130 int bRead = 0;
131 int writeCnt = 0;
132 int bWritten = 0;
133 int otherIOCnt = 0;
134 int bytes = 0;
135
136 start = gethrtime ();
137 vstart = gethrvtime ();
138
139 /* Log the event */
140 bytes = wlog ("start of iofile -- stdio", NULL);
141 bWritten += bytes;
142 writeCnt++;
143
144 strncpy (sfn, fname, sizeof (sfn));
145 ret = mkstemp (sfn);
146 otherIOCnt++;
147 if (ret == -1)
148 {
149 fprintf (stderr, "Unable to make a temporary name\n");
150 exit (1);
151 }
152 bytes = fprintf (stderr, "\tUsing %s as scratch file\n", sfn);
153 bWritten += bytes;
154 writeCnt++;
155
156 /* allocate a buffer for the reading */
157 /* note that this buffer is leaked! */
158 buf = (char *) malloc (BUFSIZE);
159
160 /* open the file */
161 fp = fdopen (ret, "w");
162 otherIOCnt++;
163 if (fp == NULL)
164 {
165 fprintf (stderr, "++ERROR opening %s, error %d\n", sfn, errno);
166 exit (1);
167 }
168
169 /* loop, writing the buffer to the file... */
170 for (i = 0; i < NBLKS; i++)
171 {
172 k = fwrite (buf, sizeof (char), BUFSIZE, fp);
173 writeCnt++;
174 if (k != BUFSIZE)
175 {
176 fprintf (stderr, "++ERROR writing %s, error %d\n", sfn, errno);
177 exit (1);
178 }
179 bWritten += k;
180 }
181
182 fclose (fp);
183 fp = NULL;
184 otherIOCnt++;
185
186 sprintf (buf, "fwrite: %d blocks of %d", i, BUFSIZE);
187 bytes = whrvlog (gethrtime () - start, gethrvtime () - vstart, buf, NULL);
188 bWritten += bytes;
189 writeCnt++;
190
191
192 /* now reopen the file, and read it */
193 start = gethrtime ();
194 vstart = gethrvtime ();
195
196 fp = fopen (sfn, "r");
197 otherIOCnt++;
198 if (fp == NULL)
199 {
200 fprintf (stderr, "++ERROR opening %s, error %d\n", sfn, errno);
201 exit (1);
202 }
203 i = 0;
204 for (;;)
205 {
206 k = fread (buf, sizeof (char), BUFSIZE, fp);
207 readCnt++;
208 if (k < 0)
209 fprintf (stderr, "++ERROR reading %s, error %d\n", sfn, errno);
210
211
212 if (k == 0)
213 {
214 /* close the file */
215 fclose (fp);
216 fp = NULL;
217 otherIOCnt++;
218 break;
219
220 }
221 else if (k != BUFSIZE)
222 {
223 /* short read */
224 sprintf (buf, "\tunexpecter short read %d on %s\n", k, sfn);
225 fprintf (stderr, buf);
226 bRead += k;
227 break;
228 }
229 else
230 {
231 /* bump the block counter */
232 i++;
233 bRead += k;
234 }
235 }
236
237 if (fp != NULL)
238 {
239 fclose (fp);
240 fp = NULL;
241 }
242 sprintf (buf, "fread: %d blocks of %d", i, BUFSIZE);
243 bytes = whrvlog (gethrtime () - start, gethrvtime () - vstart, buf, NULL);
244 bWritten += bytes;
245 writeCnt++;
246
247 bWritten += 99; /* the number of bytes are written by the next fprintf */
248 writeCnt++;
249
250 unlink (sfn);
251 otherIOCnt++;
252 fprintf (fid2, "X %14d %14d %17d %15d %17d iofile\n",
253 bRead, readCnt, bWritten, writeCnt, otherIOCnt);
254 return 0;
255 }
256
257 /* iotest - do various io syscalls */
258 int
259 iotest ()
260 {
261 char *fname = "/tmp/foobar";
262 int fd; /* file descriptor for raw IO */
263 int fd2; /* file descriptor for raw IO */
264 int k; /* temp value for loop */
265 char buf[BUFSIZE];
266 unsigned long size = 0;
267 int readCnt = 0;
268 int bRead = 0;
269 int writeCnt = 0;
270 int bWritten = 0;
271 int otherIOCnt = 0;
272 int bytes = 0;
273
274 /* Log the regular read */
275 bytes = wlog ("start of iotest", NULL);
276 bWritten += bytes;
277 writeCnt++;
278
279 /* create an empty file */
280 fd = creat (fname, 0666);
281 otherIOCnt++;
282
283 /* dup the file descriptor */
284 fd2 = dup (fd);
285 otherIOCnt++;
286 close (fd2);
287 otherIOCnt++;
288 close (fd);
289 otherIOCnt++;
290
291 /* now open the empty file */
292 fd = open (fname, O_RDONLY);
293 otherIOCnt++;
294
295 /* loop, reading into the buffer */
296 size = 0;
297 for (;;)
298 {
299 k = read (fd, buf, BUFSIZE);
300 readCnt++;
301 if (k < 0)
302 fprintf (stderr, "++ERROR reading %s, error %d\n", fname, errno);
303 else
304 {
305 size = size + k;
306 bRead += k;
307 }
308 if (k != BUFSIZE)
309 {
310 /* close the file */
311 close (fd);
312 fd = -1;
313 otherIOCnt++;
314 bRead += k;
315
316 /* short eread = EOF */
317 break;
318 }
319 }
320 if (fd != -1)
321 {
322 close (fd);
323 fd = -1;
324 }
325 bWritten += 99; /* the number of bytes are written by the next fprintf */
326 writeCnt++;
327
328 /* remove the file */
329 unlink (fname);
330 otherIOCnt++;
331 fprintf (fid2, "X %14d %14d %17d %15d %17d iotest\n",
332 bRead, readCnt, bWritten, writeCnt, otherIOCnt);
333
334 return 0;
335 }
336
337 /*
338 * Memory mapping routines-
339 *
340 * Allocate and deallocate memory using mmap and malloc.
341 *
342 * There is one parameter--the total number of megabytes to write,
343 * written in as many 16 megabyte files as are needed
344 */
345
346 unsigned char *start = (unsigned char*) 0x80000000;
347 unsigned char *stop;
348 int nblocks;
349
350 void
351 memorymap (int megabytes)
352 {
353 int readCnt = 0;
354 int bRead = 0;
355 int writeCnt = 0;
356 int bWritten = 0;
357 int otherIOCnt = 0;
358 int bytes;
359
360 /*
361 * First, see how much time it takes to mmap all the files.
362 *
363 * Second, pull in just a few pages of information to see how much
364 * time the "How much IBM do I hold?" question would take.
365 *
366 * Next, compare updating the database shared with updating it private
367 * and then recopying the changed segments.
368
369 * (We could catch the pages that we have altered by mapping the
370 * entire BIS read-only and then punching holes in it via an
371 * mprotect call as we catch segfaults. This gives us a list
372 * of the pages that we need to write, at the added expense of
373 * handling lots of interrupts.)
374 * (Notice that we don't test the case where we are adding to
375 * the BIS files. This is an interesting situation as we either
376 * have to open the last page past the last write point or reopen
377 * extendable in some way. We could do that by opening /dev/zero
378 * with MAP_ANON for addresses above our current usage point.
379 */
380
381 int i;
382 stop = start + 1024 * 1024 * (long long) megabytes;
383
384 printf ("Creating %d random numbers\n", SIZE);
385 for (i = 0; i < SIZE; i++)
386 buffer[i] = random (); // set pseudo-bis to noise
387 printf ("Done creating random numbers\n");
388
389
390 /*
391 * Write a database consisting of 16 megabyte files.
392 * Each filename contains the memory address into which
393 * the file should be reloaded.
394 */
395
396 printf ("Writing pseudo-bis files\n");
397 unsigned char* base = start;
398 nblocks = 0;
399 for (i = 0; i < megabytes; i += 16)
400 {
401 nblocks++;
402 // write data in 16MB files
403 char filename[256];
404 sprintf (filename, "bistest.%p.%d", base, i);
405 int fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, 0660);
406 otherIOCnt++;
407 if (fd == -1)
408 {
409 printf ("open of %s failed: %s\n", filename, strerror (errno));
410 exit (0);
411 }
412 bytes = write (fd, buffer, SIZE);
413 bWritten += bytes;
414 writeCnt++;
415 close (fd);
416 otherIOCnt++;
417 printf ("\twrote %d megabytes\n", i + 16);
418 base += 16 * 1024 * 1024;
419 }
420 printf ("Done writing files from %p to %p\n", start, stop);
421
422 int j;
423
424 printf ("Memory map all the files (private)\n");
425 for (i = 0; i < megabytes; i += 16)
426 {
427 unsigned char* base = start;
428 base += i * 1024 * 1024;
429 char filename[256];
430 sprintf (filename, "bistest.%p.%d", base, i);
431 int fd = open (filename, O_RDWR);
432 otherIOCnt++;
433 if (fd < 0)
434 printf ("open of %s failed: %s\n", filename, strerror (errno));
435 unsigned char *mp = (unsigned char*) mmap ((char*) base,
436 SIZE, PROT_READ | PROT_WRITE,
437 MAP_PRIVATE | MAP_FIXED, fd, 0);
438 if (mp == MAP_FAILED || mp != base)
439 {
440 printf ("mmap of %s failed: %s\n", filename, strerror (errno));
441 exit (1);
442 }
443
444 printf ("mapped %d bytes at %p\n", SIZE, base);
445 close (fd); // mmap will hold the file open for us
446 otherIOCnt++;
447 }
448
449 printf ("Mapping done\n");
450 fflush (stdout);
451 otherIOCnt++;
452
453 int ranlimit = 1000;
454 printf ("Access %d bytes at random\n", ranlimit);
455 int sum = 0;
456 for (i = 0; i < ranlimit; i++)
457 {
458 unsigned char *where = start +
459 (((unsigned long) random ()) % (stop - start));
460 sum += (int) *where;
461 }
462 printf ("Random byte access done\n");
463
464 ranlimit = 1000;
465 int ranrange = 256;
466 printf ("Alter %d random locations, %d bytes each (private)\n",
467 ranlimit, ranrange);
468
469 for (i = 0; i < ranlimit; i++)
470 {
471 unsigned char *where = start +
472 (((unsigned long) random ()) % (stop - start));
473 for (j = 0; j < ranrange; j++)
474 *where++ = j;
475 }
476
477 printf ("Memory alteration done\n");
478 fflush (stdout);
479 otherIOCnt++;
480
481 printf ("Copy all memory back to disk\n");
482
483 for (i = 0; i < megabytes; i += 16)
484 {
485 unsigned char* base = start;
486 base += i * 1024 * 1024;
487 char filename[256];
488 sprintf (filename, "bistest2.%p.%d", base, i);
489 int fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0660);
490 otherIOCnt++;
491 if ((bytes = write (fd, base, SIZE)) == -1)
492 {
493 printf ("write of %s failed: %s\n", filename, strerror (errno));
494 exit (1);
495 }
496 bWritten += bytes;
497 writeCnt++;
498 close (fd);
499 otherIOCnt++;
500 }
501
502 printf ("Disk copy complete\n");
503 fflush (stdout);
504 otherIOCnt++;
505
506 printf ("Unmap all segments\n");
507 for (i = 0; i < megabytes; i += 16)
508 {
509 unsigned char* base = start;
510 base += i * 1024 * 1024;
511 if (munmap ((char*) base, SIZE) == -1)
512 {
513 printf ("munmap failed: %s\n", strerror (errno));
514 exit (1);
515 }
516 printf ("unmapped %d bytes at %p\n", SIZE, base);
517 }
518 printf ("Segment unmapping complete\n");
519 fflush (stdout);
520 otherIOCnt++;
521
522 printf ("Remap all segments as shared\n");
523 for (i = 0; i < megabytes; i += 16)
524 {
525 unsigned char* base = start;
526 base += i * 1024 * 1024;
527 char filename[256];
528 sprintf (filename, "bistest.%p.%d", base, i);
529 int fd = open (filename, O_RDWR);
530 otherIOCnt++;
531 char* mp = mmap ((char*) base, SIZE, PROT_READ | PROT_WRITE,
532 MAP_SHARED | MAP_FIXED, fd, 0);
533 if (mp == MAP_FAILED || (unsigned char*) mp != base)
534 {
535 printf ("re mmap of %s failed: %s\n", filename, strerror (errno));
536 exit (1);
537 }
538 printf ("remapped %d bytes at %p\n", SIZE, base);
539 close (fd); // mmap will hold the file open for us
540 otherIOCnt++;
541 }
542 printf ("Remapping complete\n");
543 fflush (stdout);
544 otherIOCnt++;
545
546 ranlimit = 1000;
547 ranrange = 256;
548 printf ("Alter %d random locations, %d bytes each (shared)\n",
549 ranlimit, ranrange);
550 for (i = 0; i < ranlimit; i++)
551 {
552 unsigned char* where = start +
553 (((unsigned long) random ()) % (stop - start));
554 for (j = 0; j < ranrange; j++)
555 *where++ = j;
556 }
557 printf ("Memory alteration done\n");
558 fflush (stdout);
559 otherIOCnt++;
560
561 printf ("Unmap all segments\n");
562 for (i = 0; i < megabytes; i += 16)
563 {
564 unsigned char *base = start;
565 base += i * 1024 * 1024;
566 if (munmap ((char*) base, SIZE) == -1)
567 {
568 printf ("munmap failed: %s\n", strerror (errno));
569 exit (1);
570 }
571 printf ("unmapped %d bytes at %p\n", SIZE, base);
572 }
573 printf ("Segment unmapping complete\n");
574 fflush (stdout);
575 otherIOCnt++;
576
577 base = start;
578
579 for (i = 0; i < megabytes; i += 16)
580 {
581 // write data in 16MB files
582 char filename[256];
583 sprintf (filename, "bistest.%p.%d", base, i);
584 if (unlink (filename) != 0)
585 {
586 printf ("unlink of %s failed: %s\n", filename, strerror (errno));
587 }
588 base += 16 * 1024 * 1024;
589 otherIOCnt++;
590 }
591
592 for (i = 0; i < megabytes; i += 16)
593 {
594 unsigned char* base = start;
595 base += i * 1024 * 1024;
596 char filename[256];
597 sprintf (filename, "bistest2.%p.%d", base, i);
598 if (unlink (filename) != 0)
599 {
600 printf ("unlink of %s failed: %s\n", filename, strerror (errno));
601 }
602 otherIOCnt++;
603 }
604 bWritten += 102; /* the number of bytes are written by the next fprintf */
605 writeCnt++;
606
607 fflush (fid2);
608 otherIOCnt++;
609
610 /* Record accounting record */
611 fprintf (fid2, "X %14d %14d %17d %15d %17d memorymap\n",
612 bRead, readCnt, bWritten, writeCnt, otherIOCnt);
613 printf ("Deleted scratch files\n");
614 }