1
0
Files
irix-657m-src/irix/cmd/stress/IO/diskrand.c
2022-09-29 17:59:04 +03:00

363 lines
7.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <sys/syssgi.h>
#define USESYSSGI 0
#define USEDATAPATTERN 0
#define OFFSET 0
#define DELAY 0 /* delays before seek to allow more diskrands */
#define BUFSIZE (512 * 1024)
#if USEDATAPATTERN
unsigned int *buf;
unsigned int *buf2;
#else
char *buf;
char *buf2;
#endif
#define SIZE_PREV_BUF 50
int iterations = 0;
int64_t prevblock[SIZE_PREV_BUF];
int prevblockcount[SIZE_PREV_BUF];
int rotor = 0;
void
generate_pattern(char *string, int64_t block, int blockcount)
{
register int i, j;
#if USEDATAPATTERN
register unsigned *p;
p = buf;
#endif
for (i = 0; i < blockcount; i++)
{
#if USEDATAPATTERN
for (j = 0; j < 32; j++)
{
*p = 0xaaaaaaaa; p++;
*p = 0x55555555; p++;
*p = (((block + i) << 8) + j); p++;
*p = ~(((block + i) << 8) + j); p++;
}
#else
j = sprintf(&buf[512 * i + 0], "%s block %lld cacheline 0\n",
string, block + i);
memset(&buf[512 * i + j + 1], 0xAA, 127 - j);
j = sprintf(&buf[512 * i + 128], "%s block %lld cacheline 1\n",
string, block + i);
memset(&buf[512 * i + j + 129], 0x55, 127 - j);
j = sprintf(&buf[512 * i + 256], "%s block %lld cacheline 2\n",
string, block + i);
memset(&buf[512 * i + j + 257], block + i, 127 - j);
j = sprintf(&buf[512 * i + 384], "%s block %lld cacheline 3\n",
string, block + i);
memset(&buf[512 * i + j + 385], -(block + i), 127 - j);
#endif
}
}
void
read_data(int fd, int64_t block, int blockcount)
{
#if USESYSSGI
if (syssgi(SGI_READB, fd, buf2+OFFSET, block, blockcount) != blockcount)
{
fprintf(stderr, "Unable to read block %lld\n", block);
fflush(stderr);
exit(1);
}
#else
register int count;
register int wanted;
if (lseek64(fd, block * 512, SEEK_SET) != block * 512)
{
fprintf(stderr, "Unable to seek to block %lld\n", block);
fflush(stderr);
exit(1);
}
wanted = blockcount * 512;
if ((count = read(fd, buf2+OFFSET, wanted)) != wanted)
{
fprintf(stderr, "Error reading block %lld -- wanted %d bytes,"
" got %d bytes: ", block, wanted, count);
perror("");
fflush(stderr);
exit(1);
}
#endif
}
void
droutput(char *data)
{
register int j;
j = 0;
while (j < 128 && isprint(data[j]))
{
fprintf(stderr, "%c", data[j]);
j++;
}
if (j > 0)
fprintf(stderr, "\n");
if (j % 16)
fprintf(stderr, " %3d: ", j);
while (j < 128)
{
if (j % 16 == 0)
fprintf(stderr, " %3d: ", j);
fprintf(stderr, "<%d>", data[j]);
if (j % 16 == 15)
fprintf(stderr, "\n");
j++;
}
}
int
check_data(int64_t block, int blockcount)
{
register int i = 0;
int error = 0;
#if USEDATAPATTERN
if (memcmp(&buf[0], &buf2[OFFSET], blockcount * 512))
{
error = 1;
for (i = 0; i < blockcount * 128; i++)
{
if (buf[i] != buf2[OFFSET+i])
{
fprintf(stderr,
" sector %lld, offset %d, got 0x%x, expected 0x%x\n",
block + i / 128, 4 * (i % 128), buf2[OFFSET+i], buf[i]);
fflush(stderr);
}
}
}
#else
for (i = 0; i < blockcount * 512; i += 128)
{
if (memcmp(&buf[i], &buf2[OFFSET+i], 128))
{
error = 1;
fprintf(stderr, "Expected:\n");
droutput(buf + i);
fprintf(stderr, "Got:\n");
droutput(buf2 + OFFSET + i);
fprintf(stderr, "\n");
fflush(stderr);
}
}
#endif
if (error)
{
fprintf(stderr, "Read miscompare(s) start block %lld blockcount %d"
" iteration %d\n", block, blockcount, iterations);
fflush(stderr);
return 1;
}
return 0;
}
void
write_data(int fd, int64_t block, int blockcount)
{
int i;
#if USESYSSGI
if ((i = syssgi(SGI_WRITEB, fd, buf, block, blockcount)) != blockcount)
{
fprintf(stderr, "write to block %lld returns %d\n", block, i);
fflush(stderr);
exit(1);
}
#else
if (lseek64(fd, block * 512, SEEK_SET) != block * 512)
{
fprintf(stderr, "Unable to seek to block %lld\n", block);
fflush(stderr);
exit(1);
}
if ((i = write(fd, buf, blockcount * 512)) != blockcount * 512)
{
fprintf(stderr, "write to block %lld returns %d\n", block, i);
fflush(stderr);
exit(1);
}
#endif
}
void
usage(char *argv0)
{
fprintf(stderr, "Usage: %s <partition name> <start block> <block count>\n",
argv0);
fflush(stderr);
exit(1);
}
void
main(argc, argv)
int argc;
char **argv;
{
register int j;
int64_t minblock;
int64_t blockextent;
int64_t maxblock;
int fd;
int64_t block;
int blockcount;
unsigned sequential;
int action;
buf = memalign(getpagesize(), BUFSIZE+1024);
buf2 = memalign(getpagesize(), BUFSIZE+1024);
if (mpin(buf2, BUFSIZE))
{
fprintf(stderr, "Pin didn't work\n");
fflush(stderr);
exit(1);
}
#define PHYSPAGES 0
#if PHYSPAGES
printf("Physical pages are:\n");
for (j = 0; j < BUFSIZE; j += getpagesize())
{
block = syssgi(1010, ((char *) buf2) + j, &sequential);
if (block != 0)
{
printf("error in syssgi\n");
exit(1);
}
printf("0x%x ", sequential);
}
printf("\n");
fflush(stdout);
#endif
if (argc < 3 || argc > 4)
usage(argv[0]);
if ((fd = open(argv[1], O_RDWR)) == -1)
{
fprintf(stderr,
"%s: unable to open %s\n", argv[0], argv[1]);
usage(argv[0]);
}
if (argc == 3)
{
minblock = 0;
blockextent = (int64_t) atoll(argv[2]);
}
else
{
minblock = (int64_t) atoll(argv[2]);
blockextent = (int64_t) atoll(argv[3]);
}
if (minblock < 0 || blockextent < 0)
usage(argv[0]);
maxblock = minblock + blockextent;
memset(buf, 0, BUFSIZE);
block = minblock;
do
{
blockcount = BUFSIZE / 512;
if (block + blockcount > maxblock)
blockcount = maxblock - block;
generate_pattern(argv[1], block, blockcount);
write_data(fd, block, blockcount);
block += blockcount;
}
while (block < maxblock);
printf("%s initialized block %lld to %lld\n", argv[1], minblock, maxblock - 1);
fflush(stdout);
srandom(time(0) + getpid());
action = 1;
while (1)
{
sequential = random() & 1;
if (sequential)
{
block += blockcount;
if (block == maxblock)
block = minblock;
}
else
block = minblock + (random() % blockextent);
blockcount = (random() % (BUFSIZE / 512)) + 1;
if (block + blockcount > maxblock)
block = maxblock - blockcount;
if (!sequential)
{
action = random() & 3;
#if DELAY
if (random() & 1)
sginap(random() % 50);
#endif
}
if (action)
{
read_data(fd, block, blockcount);
generate_pattern(argv[1], block, blockcount);
if (check_data(block, blockcount))
break;
prevblock[rotor] = block;
}
else
{
generate_pattern(argv[1], block, blockcount);
write_data(fd, block, blockcount);
prevblock[rotor] = -block;
}
prevblockcount[rotor] = blockcount;
rotor++;
if (rotor == SIZE_PREV_BUF)
rotor = 0;
iterations++;
if ((iterations & (1024 - 1)) == 0)
{
printf("-- %d iterations completed on %s --\n",
iterations, argv[1]);
fflush(stdout);
}
}
printf("Data was DMA'd into buffer at 0x%lx\n", buf2+OFFSET);
printf("Previous block/blockcounts:\n");
j = rotor;
do {
printf(" %s block %lld blockcount %d\n",
prevblock[j] < 0 ? " write to" : "read from",
prevblock[j] < 0 ? -prevblock[j] : prevblock[j],
prevblockcount[j]);
if (++j == SIZE_PREV_BUF)
j = 0;
}
while (j != rotor);
close(fd);
exit(1);
}