diff options
Diffstat (limited to 'gprofng/testsuite/gprofng.display/synprog/iosyn.c')
-rw-r--r-- | gprofng/testsuite/gprofng.display/synprog/iosyn.c | 614 |
1 files changed, 614 insertions, 0 deletions
diff --git a/gprofng/testsuite/gprofng.display/synprog/iosyn.c b/gprofng/testsuite/gprofng.display/synprog/iosyn.c new file mode 100644 index 00000000000..278ceea31eb --- /dev/null +++ b/gprofng/testsuite/gprofng.display/synprog/iosyn.c @@ -0,0 +1,614 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/time.h> + +#include "stopwatch.h" + +/* parameters defining various tasks */ +#define BUFSIZE 16384 +#define NBLKS 1024 + +#define SIZE ((int)(16*1024*1024)) +unsigned buffer[SIZE]; +extern FILE *fid2; + +/* ioerror - do some erroneous file IO operations */ +int +ioerror () +{ + FILE *fp; /* FILE pointer for stdio */ + char *fname = NULL; + char *ptr = NULL; + int fd; /* file descriptor for raw IO */ + int fd2; /* file descriptor for raw IO */ + int stat; + char buf[BUFSIZE]; + unsigned long size = 0; + char sfn[23] = ""; + + /* Log the regular read */ + wlog ("start of ioerror", NULL); + + /* fname is set to NULL. + Use various calls to create + a file. + */ + + fd = creat (fname, 0666); + fd = open (fname, 0666); + fd2 = 0; + fd = openat (fd2, fname, 0666); + fp = fopen (fname, "w"); + fp = fopen ("/iotest", "w"); + fp = NULL; + stat = fflush (fp); + stat = chmod (fname, 755); + stat = access (fname, 755); + fname = "/tmp/synprogXXXXXX"; + strncpy (sfn, fname, sizeof (sfn)); + fd = mkstemp (sfn); + stat = unlink (sfn); + stat = rename (fname, NULL); + unlink (fname); + fp = fopen (fname, "w"); + stat = fclose (fp); + stat = fread (buf, 100, 2, fp); + stat = fwrite (buf, 100, 2, fp); + ptr = fgets (buf, size, fp); + read (10000, buf, 100); + write (10000, buf, 100); + stat = unlink (fname); + fname = NULL; + stat = mkdir (fname, 755); + stat = unlink (fname); + /* + These functions cannot be executed + if the File Pointer (fp) is set + to NULL. They generate segv failure + in actual call not inside of + the wrapper. + + stat = fread(buf, size, 2, fp); + stat = fwrite(buf, size, 2, fp); + ptr = fgets(buf, size, fp); + stat = fputs(buf, fp); + stat = fprintf(fp, "%d\n", size); + stat = fseek(fp, size, size); + rewind(fp); + ftell(fp); + fpos_t pos; + stat = fsetpos(fp, &pos); + stat = fgetpos(fp, &pos); + */ + return 0; +} + +/*=======================================================*/ + +/* iofile - do some file io operations */ +int +iofile () +{ + FILE *fp; /* FILE pointer for stdio */ + int k; /* temp value for loop */ + int i; + char *buf; + hrtime_t start; + hrtime_t vstart; + char sfn[23] = ""; + char *fname = "/tmp/synprogXXXXXX"; + int ret; + int readCnt = 0; + int bRead = 0; + int writeCnt = 0; + int bWritten = 0; + int otherIOCnt = 0; + int bytes = 0; + + start = gethrtime (); + vstart = gethrvtime (); + + /* Log the event */ + bytes = wlog ("start of iofile -- stdio", NULL); + bWritten += bytes; + writeCnt++; + + strncpy (sfn, fname, sizeof (sfn)); + ret = mkstemp (sfn); + otherIOCnt++; + if (ret == -1) + { + fprintf (stderr, "Unable to make a temporary name\n"); + exit (1); + } + bytes = fprintf (stderr, "\tUsing %s as scratch file\n", sfn); + bWritten += bytes; + writeCnt++; + + /* allocate a buffer for the reading */ + /* note that this buffer is leaked! */ + buf = (char *) malloc (BUFSIZE); + + /* open the file */ + fp = fdopen (ret, "w"); + otherIOCnt++; + if (fp == NULL) + { + fprintf (stderr, "++ERROR opening %s, error %d\n", sfn, errno); + exit (1); + } + + /* loop, writing the buffer to the file... */ + for (i = 0; i < NBLKS; i++) + { + k = fwrite (buf, sizeof (char), BUFSIZE, fp); + writeCnt++; + if (k != BUFSIZE) + { + fprintf (stderr, "++ERROR writing %s, error %d\n", sfn, errno); + exit (1); + } + bWritten += k; + } + + fclose (fp); + fp = NULL; + otherIOCnt++; + + sprintf (buf, "fwrite: %d blocks of %d", i, BUFSIZE); + bytes = whrvlog (gethrtime () - start, gethrvtime () - vstart, buf, NULL); + bWritten += bytes; + writeCnt++; + + + /* now reopen the file, and read it */ + start = gethrtime (); + vstart = gethrvtime (); + + fp = fopen (sfn, "r"); + otherIOCnt++; + if (fp == NULL) + { + fprintf (stderr, "++ERROR opening %s, error %d\n", sfn, errno); + exit (1); + } + i = 0; + for (;;) + { + k = fread (buf, sizeof (char), BUFSIZE, fp); + readCnt++; + if (k < 0) + fprintf (stderr, "++ERROR reading %s, error %d\n", sfn, errno); + + + if (k == 0) + { + /* close the file */ + fclose (fp); + fp = NULL; + otherIOCnt++; + break; + + } + else if (k != BUFSIZE) + { + /* short read */ + sprintf (buf, "\tunexpecter short read %d on %s\n", k, sfn); + fprintf (stderr, buf); + bRead += k; + break; + } + else + { + /* bump the block counter */ + i++; + bRead += k; + } + } + + if (fp != NULL) + { + fclose (fp); + fp = NULL; + } + sprintf (buf, "fread: %d blocks of %d", i, BUFSIZE); + bytes = whrvlog (gethrtime () - start, gethrvtime () - vstart, buf, NULL); + bWritten += bytes; + writeCnt++; + + bWritten += 99; /* the number of bytes are written by the next fprintf */ + writeCnt++; + + unlink (sfn); + otherIOCnt++; + fprintf (fid2, "X %14d %14d %17d %15d %17d iofile\n", + bRead, readCnt, bWritten, writeCnt, otherIOCnt); + return 0; +} + +/* iotest - do various io syscalls */ +int +iotest () +{ + char *fname = "/tmp/foobar"; + int fd; /* file descriptor for raw IO */ + int fd2; /* file descriptor for raw IO */ + int k; /* temp value for loop */ + char buf[BUFSIZE]; + unsigned long size = 0; + int readCnt = 0; + int bRead = 0; + int writeCnt = 0; + int bWritten = 0; + int otherIOCnt = 0; + int bytes = 0; + + /* Log the regular read */ + bytes = wlog ("start of iotest", NULL); + bWritten += bytes; + writeCnt++; + + /* create an empty file */ + fd = creat (fname, 0666); + otherIOCnt++; + + /* dup the file descriptor */ + fd2 = dup (fd); + otherIOCnt++; + close (fd2); + otherIOCnt++; + close (fd); + otherIOCnt++; + + /* now open the empty file */ + fd = open (fname, O_RDONLY); + otherIOCnt++; + + /* loop, reading into the buffer */ + size = 0; + for (;;) + { + k = read (fd, buf, BUFSIZE); + readCnt++; + if (k < 0) + fprintf (stderr, "++ERROR reading %s, error %d\n", fname, errno); + else + { + size = size + k; + bRead += k; + } + if (k != BUFSIZE) + { + /* close the file */ + close (fd); + fd = -1; + otherIOCnt++; + bRead += k; + + /* short eread = EOF */ + break; + } + } + if (fd != -1) + { + close (fd); + fd = -1; + } + bWritten += 99; /* the number of bytes are written by the next fprintf */ + writeCnt++; + + /* remove the file */ + unlink (fname); + otherIOCnt++; + fprintf (fid2, "X %14d %14d %17d %15d %17d iotest\n", + bRead, readCnt, bWritten, writeCnt, otherIOCnt); + + return 0; +} + +/* + * Memory mapping routines- + * + * Allocate and deallocate memory using mmap and malloc. + * + * There is one parameter--the total number of megabytes to write, + * written in as many 16 megabyte files as are needed + */ + +unsigned char *start = (unsigned char*) 0x80000000; +unsigned char *stop; +int nblocks; + +void +memorymap (int megabytes) +{ + int readCnt = 0; + int bRead = 0; + int writeCnt = 0; + int bWritten = 0; + int otherIOCnt = 0; + int bytes; + + /* + * First, see how much time it takes to mmap all the files. + * + * Second, pull in just a few pages of information to see how much + * time the "How much IBM do I hold?" question would take. + * + * Next, compare updating the database shared with updating it private + * and then recopying the changed segments. + + * (We could catch the pages that we have altered by mapping the + * entire BIS read-only and then punching holes in it via an + * mprotect call as we catch segfaults. This gives us a list + * of the pages that we need to write, at the added expense of + * handling lots of interrupts.) + * (Notice that we don't test the case where we are adding to + * the BIS files. This is an interesting situation as we either + * have to open the last page past the last write point or reopen + * extendable in some way. We could do that by opening /dev/zero + * with MAP_ANON for addresses above our current usage point. + */ + + int i; + stop = start + 1024 * 1024 * (long long) megabytes; + + printf ("Creating %d random numbers\n", SIZE); + for (i = 0; i < SIZE; i++) + buffer[i] = random (); // set pseudo-bis to noise + printf ("Done creating random numbers\n"); + + + /* + * Write a database consisting of 16 megabyte files. + * Each filename contains the memory address into which + * the file should be reloaded. + */ + + printf ("Writing pseudo-bis files\n"); + unsigned char* base = start; + nblocks = 0; + for (i = 0; i < megabytes; i += 16) + { + nblocks++; + // write data in 16MB files + char filename[256]; + sprintf (filename, "bistest.%p.%d", base, i); + int fd = open (filename, O_CREAT | O_TRUNC | O_WRONLY, 0660); + otherIOCnt++; + if (fd == -1) + { + printf ("open of %s failed: %s\n", filename, strerror (errno)); + exit (0); + } + bytes = write (fd, buffer, SIZE); + bWritten += bytes; + writeCnt++; + close (fd); + otherIOCnt++; + printf ("\twrote %d megabytes\n", i + 16); + base += 16 * 1024 * 1024; + } + printf ("Done writing files from %p to %p\n", start, stop); + + int j; + + printf ("Memory map all the files (private)\n"); + for (i = 0; i < megabytes; i += 16) + { + unsigned char* base = start; + base += i * 1024 * 1024; + char filename[256]; + sprintf (filename, "bistest.%p.%d", base, i); + int fd = open (filename, O_RDWR); + otherIOCnt++; + if (fd < 0) + printf ("open of %s failed: %s\n", filename, strerror (errno)); + unsigned char *mp = (unsigned char*) mmap ((char*) base, + SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0); + if (mp == MAP_FAILED || mp != base) + { + printf ("mmap of %s failed: %s\n", filename, strerror (errno)); + exit (1); + } + + printf ("mapped %d bytes at %p\n", SIZE, base); + close (fd); // mmap will hold the file open for us + otherIOCnt++; + } + + printf ("Mapping done\n"); + fflush (stdout); + otherIOCnt++; + + int ranlimit = 1000; + printf ("Access %d bytes at random\n", ranlimit); + int sum = 0; + for (i = 0; i < ranlimit; i++) + { + unsigned char *where = start + + (((unsigned long) random ()) % (stop - start)); + sum += (int) *where; + } + printf ("Random byte access done\n"); + + ranlimit = 1000; + int ranrange = 256; + printf ("Alter %d random locations, %d bytes each (private)\n", + ranlimit, ranrange); + + for (i = 0; i < ranlimit; i++) + { + unsigned char *where = start + + (((unsigned long) random ()) % (stop - start)); + for (j = 0; j < ranrange; j++) + *where++ = j; + } + + printf ("Memory alteration done\n"); + fflush (stdout); + otherIOCnt++; + + printf ("Copy all memory back to disk\n"); + + for (i = 0; i < megabytes; i += 16) + { + unsigned char* base = start; + base += i * 1024 * 1024; + char filename[256]; + sprintf (filename, "bistest2.%p.%d", base, i); + int fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0660); + otherIOCnt++; + if ((bytes = write (fd, base, SIZE)) == -1) + { + printf ("write of %s failed: %s\n", filename, strerror (errno)); + exit (1); + } + bWritten += bytes; + writeCnt++; + close (fd); + otherIOCnt++; + } + + printf ("Disk copy complete\n"); + fflush (stdout); + otherIOCnt++; + + printf ("Unmap all segments\n"); + for (i = 0; i < megabytes; i += 16) + { + unsigned char* base = start; + base += i * 1024 * 1024; + if (munmap ((char*) base, SIZE) == -1) + { + printf ("munmap failed: %s\n", strerror (errno)); + exit (1); + } + printf ("unmapped %d bytes at %p\n", SIZE, base); + } + printf ("Segment unmapping complete\n"); + fflush (stdout); + otherIOCnt++; + + printf ("Remap all segments as shared\n"); + for (i = 0; i < megabytes; i += 16) + { + unsigned char* base = start; + base += i * 1024 * 1024; + char filename[256]; + sprintf (filename, "bistest.%p.%d", base, i); + int fd = open (filename, O_RDWR); + otherIOCnt++; + char* mp = mmap ((char*) base, SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, fd, 0); + if (mp == MAP_FAILED || (unsigned char*) mp != base) + { + printf ("re mmap of %s failed: %s\n", filename, strerror (errno)); + exit (1); + } + printf ("remapped %d bytes at %p\n", SIZE, base); + close (fd); // mmap will hold the file open for us + otherIOCnt++; + } + printf ("Remapping complete\n"); + fflush (stdout); + otherIOCnt++; + + ranlimit = 1000; + ranrange = 256; + printf ("Alter %d random locations, %d bytes each (shared)\n", + ranlimit, ranrange); + for (i = 0; i < ranlimit; i++) + { + unsigned char* where = start + + (((unsigned long) random ()) % (stop - start)); + for (j = 0; j < ranrange; j++) + *where++ = j; + } + printf ("Memory alteration done\n"); + fflush (stdout); + otherIOCnt++; + + printf ("Unmap all segments\n"); + for (i = 0; i < megabytes; i += 16) + { + unsigned char *base = start; + base += i * 1024 * 1024; + if (munmap ((char*) base, SIZE) == -1) + { + printf ("munmap failed: %s\n", strerror (errno)); + exit (1); + } + printf ("unmapped %d bytes at %p\n", SIZE, base); + } + printf ("Segment unmapping complete\n"); + fflush (stdout); + otherIOCnt++; + + base = start; + + for (i = 0; i < megabytes; i += 16) + { + // write data in 16MB files + char filename[256]; + sprintf (filename, "bistest.%p.%d", base, i); + if (unlink (filename) != 0) + { + printf ("unlink of %s failed: %s\n", filename, strerror (errno)); + } + base += 16 * 1024 * 1024; + otherIOCnt++; + } + + for (i = 0; i < megabytes; i += 16) + { + unsigned char* base = start; + base += i * 1024 * 1024; + char filename[256]; + sprintf (filename, "bistest2.%p.%d", base, i); + if (unlink (filename) != 0) + { + printf ("unlink of %s failed: %s\n", filename, strerror (errno)); + } + otherIOCnt++; + } + bWritten += 102; /* the number of bytes are written by the next fprintf */ + writeCnt++; + + fflush (fid2); + otherIOCnt++; + + /* Record accounting record */ + fprintf (fid2, "X %14d %14d %17d %15d %17d memorymap\n", + bRead, readCnt, bWritten, writeCnt, otherIOCnt); + printf ("Deleted scratch files\n"); +} |