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

376 lines
7.8 KiB
C

/**************************************************************************
* *
* Copyright (C) 1992-1992 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "$Revision: 1.11 $"
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>
#include <ulocks.h>
#include <wait.h>
#include <errno.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "stress.h"
/*
* semstdio - basic semaphored stdio testing
* Basically works over fopen//flush/fclose and dir routines
*/
char *Cmd;
char *afile;
usptr_t *handle;
void slave(void *), simple1(void), closeem(void);
extern void quitit(), abrt();
extern void rmit(char *dir);
extern void segcatch(int sig, int code, struct sigcontext *sc);
int debug = 0;
int verbose = 0;
int mpid;
int nusers = 8;
int nfiles = 140;
int nloops = 80;
int spinonabort;
DIR *dp;
struct files {
char *name; /* basename of file */
FILE *f; /* open file handle */
int visited; /* # times visited */
int access; /* # of folks accessing */
ulock_t olock; /* spin lock */
} *files;
char *dir = NULL;
int
main(int argc, char **argv)
{
int c;
int err = 0;
int i;
FILE *f;
char *tf;
char dirtemps[PATH_MAX];
Cmd = errinit(argv[0]);
while ((c = getopt(argc, argv, "al:vdf:u:")) != EOF) {
switch (c) {
case 'a':
spinonabort++;
break;
case 'v':
verbose++;
break;
case 'd':
debug++;
break;
case 'u':
nusers = atoi(optarg);
break;
case 'l':
nloops = atoi(optarg);
break;
case 'f':
nfiles = atoi(optarg);
break;
case '?':
err++;
break;
}
}
if (err) {
fprintf(stderr, "Usage: %s [-v][-d][-l loops][-u users][-f nfiles]\n", Cmd);
exit(1);
}
/* This is really to protect 032 which has a max of 255.
*/
#if (_MIPS_SIM == _MIPS_SIM_ABI64)
#define FD_MAX INT_MAX
#elif (_MIPS_SIM == _MIPS_SIM_NABI32)
#define FD_MAX USHRT_MAX
#else
#define FD_MAX UCHAR_MAX
#endif
if (nfiles + 3 > FD_MAX) {
fprintf(stderr, "nfiles too large [%d]\n", FD_MAX - 3);
exit(1);
}
mpid = get_pid();
sigset(SIGSEGV, segcatch);
sigset(SIGBUS, segcatch);
if (debug)
sigset(SIGINT, quitit);
parentexinit(0);
if (spinonabort)
sigset(SIGABRT, abrt);
if (debug)
usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
printf("%s:%d:# users %d # files %d\n",
Cmd, getpid(), nusers, nfiles);
if (usconfig(CONF_INITUSERS, nusers) < 0) {
errprintf(1, "INITUSERS");
/* NOTREACHED */
}
usconfig(CONF_ARENATYPE, US_SHAREDONLY);
afile = tempnam(NULL, "semlibc");
if ((handle = usinit(afile)) == NULL)
errprintf(1, "usinit of %s failed", afile);
/* NOTREACHED */
/*
* set up temp dir for roaming around in
*/
dir = tempnam(NULL, "semlibc");
if (mkdir(dir, 0777) != 0)
errprintf(1, "cannot create directory %s", dir);
/* NOTREACHED */
if ((dp = opendir(dir)) == NULL)
errprintf(1, "cannot opendir directory %s", dir);
/* NOTREACHED */
files = calloc(nfiles, sizeof(struct files));
for (i = 0; i < nfiles; i++) {
sprintf(dirtemps, "%s/%d", dir, i);
tf = dirtemps;
files[i].name = strdup(tf);
if ((f = fopen(tf, "w+")) == NULL) {
errprintf(3, "cannot create file %s", tf);
goto err;
}
fwrite("Hello", 10, 1, f);
fclose(f);
if ((files[i].olock = usnewlock(handle)) == NULL) {
errprintf(3, "cannot alloc lock");
goto err;
}
}
prctl(PR_SETSTACKSIZE, 64*1024);
/* start up all users */
for (i = 0; i < nusers-1; i++) {
if (sproc(slave, PR_SALL, 0) < 0) {
if (errno != EAGAIN) {
errprintf(ERR_ERRNO_RET, "sproc failed i:%d", i);
goto err;
} else {
fprintf(stderr, "%s:can't sproc:%s\n",
Cmd, strerror(errno));
rmit(dir);
exit(1);
}
}
}
simple1();
while (wait(0) >= 0 || errno == EINTR)
;
if (verbose) {
for (i = 0; i < nfiles; i++) {
printf("File %s visited %d times\n",
files[i].name, files[i].visited);
}
}
rmit(dir);
printf("%s:%d:PASSED\n", Cmd, getpid());
return 0;
err:
rmit(dir);
abort();
/* NOTREACHED */
}
/* ARGSUSED */
void
slave(void *arg)
{
sigset(SIGINT, SIG_DFL);
slaveexinit();
simple1();
}
void
simple1(void)
{
register int found, i, j;
struct dirent *res, *dent;
int randdirent;
dent = malloc(sizeof(struct dirent) + NAME_MAX + 1);
if ((handle = usinit(afile)) == NULL) {
errprintf(ERR_ERRNO_EXIT, "%d slave usinit", get_pid());
/* NOTREACHED */
}
for (j = 0; j < nloops; j++) {
randdirent = rand() % (nfiles >> (nfiles > 16 ? 4 : 0));
do {
while (readdir_r(dp, dent, &res) || res == NULL) {
/* error or EOF ... */
/* XXX single thread?? */
rewinddir(dp);
}
} while (--randdirent > 0);
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
/* find name in list */
for (i = 0, found = 0; i < nfiles; i++) {
if (strcmp(strrchr(files[i].name, '/') + 1,
dent->d_name) == 0) {
found++;
break;
}
}
if (!found) {
errprintf(0, "%d name %s not found in dir!",
get_pid(), dent->d_name);
/* NOTREACHED */
}
again:
/* grab olock */
if (ussetlock(files[i].olock) != 1) {
errprintf(1, "%d ussetlock olock failed",
get_pid());
/* NOTREACHED */
}
if (!files[i].f) {
if ((files[i].f = fopen(files[i].name, "w+")) == NULL) {
/* couldn't open file - perhaps cause
* we got so many open??
*/
if (errno == EMFILE) {
usunsetlock(files[i].olock);
closeem();
goto again;
} else
errprintf(1, "%d fopen on %s failed",
get_pid(), files[i].name);
/* NOTREACHED */
}
} else {
FILE *tf;
char tmp[256];
strcpy(tmp, dir);
strcat(tmp, "/tmp");
if ((tf = fopen("tmp", "w+")) != NULL) {
/* Close fp for slot we are about to use.
*/
fclose(files[i].f);
if ((files[i].f = freopen(files[i].name, "w+", tf)) == NULL) {
if (errno == EMFILE) {
usunsetlock(files[i].olock);
closeem();
goto again;
} else
errprintf(1, "%d freopen on %s failed",
get_pid(), files[i].name);
/* NOTREACHED */
}
}
}
files[i].access++;
files[i].visited++;
usunsetlock(files[i].olock);
/* now play with it */
if (fwrite("Hello", 10, 1, files[i].f) != 1)
errprintf(0, "%d fwrite failed", get_pid());
/* NOTREACHED */
fflush(files[i].f);
/* un-access lock */
if (ussetlock(files[i].olock) != 1) {
errprintf(1, "%d ussetlock olock failed",
get_pid());
/* NOTREACHED */
}
if (files[i].access <= 0) {
errprintf(0, "%d access cnt is %d",
get_pid(), files[i].access);
/* NOTREACHED */
}
files[i].access--;
usunsetlock(files[i].olock);
if (verbose > 1)
printf("%s:%d pass:%d file %d %s\n", Cmd, get_pid(),
j+1, i, files[i].name);
}
}
void
segcatch(int sig, int code, struct sigcontext *sc)
{
fprintf(stderr, "%s:%d:ERROR: caught signal %d at pc 0x%llx code %d badvaddr %llx\n",
Cmd, getpid(), sig, sc->sc_pc, code,
sc->sc_badvaddr);
abort();
/* NOTREACHED */
}
void
quitit()
{
rmit(dir);
exit(0);
}
void
abrt()
{
write(2, "spin in abrt catcher\n", 21);
for (;;) ;
}
void
rmit(char *dir)
{
char cmd[1024];
strcpy(cmd, "/bin/rm -fr ");
strcat(cmd, dir);
system(cmd);
}
void
closeem(void)
{
int i;
for (i = 0; i < nfiles; i++) {
if (ussetlock(files[i].olock) != 1) {
errprintf(1, "%d ussetlock olock failed",
get_pid());
/* NOTREACHED */
}
if (files[i].f && files[i].access == 0) {
fclose(files[i].f);
files[i].f = NULL;
}
usunsetlock(files[i].olock);
}
}