#include #include #include #include #include #include #include #include #include #define MAXTHREADS 32 #define MAXLEN 100 #define FILEPREFIX "testfdescfs_thr" /* Good margin :) */ #define MAXFNAME 128 #define MAXFD 4 #define FOPSLEEP 1000000 pthread_t threadpool[MAXTHREADS]; struct tdata { int len; int id; }; /* Perform file operations. */ void * perform_fileop(void *arg) { struct tdata *tdp; char fname[MAXFNAME]; int duplicates[MAXFD]; int len, id, sleeptime, i, sim, fd, numdups; tdp = (struct tdata *)arg; len = tdp->len; id = tdp->id; snprintf(fname, MAXFNAME, "%s%d", FILEPREFIX, id); sim = 0; fprintf(stderr, "Doing fileop id %d, length %d\n", id, len); while (sim < len) { fd = -1; fd = open(fname, O_CREAT | O_RDWR, 0777); if (fd < 0) { fprintf(stderr, "Error opening %s\n", fname); return (NULL); } /*fprintf(stderr, "Opened %s\n", fname);*/ /* Make a certain number of duplicates. */ numdups = rand() % MAXFD; for (i = 0; i < numdups; i++) { duplicates[i] = dup(fd); if (duplicates[i] < 0) { fprintf(stderr, "Error duping %s\n", fname); return (NULL); } } /* Then close it. */ close(fd); /* Sleep for a random amount of microseconds. */ /* sleeptime = rand() % FOPSLEEP; usleep(sleeptime);*/ sim++; } } /* Perform operations related to fdescfs. */ void * perform_fdescop(void *arg) { struct dirent de; struct dirent *result; struct stat st; DIR *dirp; int sim, len, sleeptime; char fdname[MAXFNAME]; sim = 0; len = *(int *)arg; fprintf(stderr, "Doing fdesc op len %d\n", len); while (sim < len) { dirp = opendir("/dev/fd"); /* Unable to open. */ if (dirp == NULL) { /* fprintf(stderr, "Unable to open dir\n");*/ sim++; continue; } while (readdir_r(dirp, &de, &result) >= 0) { if (result == NULL) break; snprintf(fdname, MAXFNAME, "/dev/fd/%s", de.d_name); /* fprintf(stderr, "Read in dir '%s'\n", fdname);*/ stat(fdname, &st); } closedir(dirp); /* Sleep for a random amount of microseconds. */ /* sleeptime = rand() % FOPSLEEP; usleep(sleeptime);*/ sim++; } } int main(int argc, char **argv) { struct tdata *tdp; pthread_t *tp; int numfdesc; int numfops; int i, *len; srand(time(0)); if (argc < 3) { fprintf(stderr, "Usage: %s <#threads on fdescf ops> <#threads on file ops>\n", argv[0]); return (-1); } numfdesc = strtol(argv[1], NULL, 10); numfops = strtol(argv[2], NULL, 10); if (numfdesc + numfops > MAXTHREADS) { fprintf(stderr, "#threads > MAXTHREADS\n"); return (-1); } /* Start threads doing file operations. */ for (i = 0; i < numfops; i++) { tp = &threadpool[i]; tdp = malloc(sizeof(struct tdata)); if (tdp == NULL) { fprintf(stderr, "Not enough memory\n"); return (-1); } tdp->len = rand() % MAXLEN; tdp->id = i; pthread_create(tp, NULL, perform_fileop, tdp); } /* Then start threads doing fdesc operations. */ for (i = numfops; i < (numfdesc + numfops); i++) { tp = &threadpool[i]; len = malloc(sizeof(int)); *len = rand() % MAXLEN; pthread_create(tp, NULL, perform_fdescop, len); } for (i = 0; i < MAXTHREADS; i++) { tp = &threadpool[i]; pthread_join(*tp, NULL); } return (0); }