summaryrefslogtreecommitdiff
path: root/gprofng/testsuite/gprofng.display/synprog/iosyn.c
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/testsuite/gprofng.display/synprog/iosyn.c')
-rw-r--r--gprofng/testsuite/gprofng.display/synprog/iosyn.c614
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");
+}