Projet_SETI_RISC-V/riscv-gnu-toolchain/gdb/gprofng/testsuite/gprofng.display/synprog/iosyn.c
2023-03-06 14:48:14 +01:00

614 lines
15 KiB
C

/* 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");
}