int main(int argc, char *argv[]) { /*Socket set up*/ int sockopt = 1; int sock; struct sockaddr_in sockaddr_me; memset(&sockaddr_me, 0, sizeof(sockaddr_me)); sockaddr_me.sin_family = AF_INET; sockaddr_me.sin_port = htons(PORT); sockaddr_me.sin_addr.s_addr = INADDR_ANY; if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { edie("socket"); } if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)) < 0) { edie("setsockopt"); } if(bind(sock, (struct sockaddr *) &sockaddr_me, sizeof(sockaddr_me)) != 0) { edie("bind"); } if(listen(sock, 20) != 0) { edie("listen"); } accept_connection(sock); }
void accept_connection(int sock) { struct sockaddr_in client_addr; int clientfd, pid, addrlen = sizeof(client_addr); /*Loop forever*/ while(1) { if((clientfd = accept(sock, (struct sockaddr *)&client_addr, &addrlen)) < 0) { edie("accept"); } if((pid = fork()) < 0) { edie("fork"); } if(pid == 0) { /*child process, handle client*/ close(sock); handle_client(clientfd); return; } else { /*parent process, return to loop*/ close(clientfd); } } /*parent never returns*/ }
void store_file(prange_t range, const char *filename, mode_t mode) { #define _arg filename int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode); if(fd == -1) { edie("could not open"); } if(write(fd, range.start, range.size) != (ssize_t) range.size) { edie("could not write data"); } close(fd); #undef _arg }
void setaffinity(int c) { #if defined (__SVR4) && defined (__sun) processorid_t obind; if (processor_bind(P_LWPID, P_MYID, c, &obind) < 0) edie("setaffinity, processor_bind failed"); #else cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(c, &cpuset); if (sched_setaffinity(0, sizeof(cpuset), &cpuset) < 0) edie("setaffinity, sched_setaffinity failed"); #endif }
void *worker(void *arg) { struct state *s = arg; s->workfn = s->opi & MFwrt ? wwriter : wreader; s->posfn = s->opi & MFrnd ? randpos : linpos; s->fd = open(fn, (s->opi & MFwrt ? O_WRONLY : O_RDONLY) | oflags); if (s->fd < 0) { int e = errno; decnr(); errno = e; edie(fn); } s->stime = curtime(); for(;;) { if (term) break; if (s->workfn(s, s->posfn(s)) < 0) { perror(ion[s->opi]); break; } ++s->ioc; incc(); if (bm && s->ioc >= bm) break; } decnr(); return 0; }
prange_t load_file(const char *filename, bool rw, mode_t *mode) { #define _arg filename int fd = open(filename, O_RDONLY); if(fd == -1) { edie("could not open"); } if(mode) { struct stat st; if(fstat(fd, &st)) { edie("could not lstat"); } *mode = st.st_mode; } prange_t ret = load_fd(fd, rw); close(fd); return ret; #undef _arg }
prange_t load_fd(int fd, bool rw) { off_t end = lseek(fd, 0, SEEK_END); if(end == 0) { fprintf(stderr, "load_fd: warning: mapping an empty file\n"); } if(sizeof(off_t) > sizeof(size_t) && end > (off_t) SIZE_MAX) { die("too big: %lld", (long long) end); } void *buf = mmap(NULL, (size_t) end, PROT_READ | (rw ? PROT_WRITE : 0), MAP_PRIVATE, fd, 0); if(buf == MAP_FAILED) { edie("could not mmap buf (end=%zu)", (size_t) end); } return (prange_t) {buf, (size_t) end}; }
prange_t pdup(prange_t range, size_t newsize, size_t offset) { if(newsize < offset + range.size) { die("pdup: newsize=%zu < offset=%zu + range.size=%zu", newsize, offset, range.size); } void *buf = mmap(NULL, newsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if(buf == MAP_FAILED) { edie("pdup: could not mmap"); } #ifdef __APPLE__ munmap(buf + offset, range.size); vm_prot_t cur, max; vm_address_t addr = (vm_address_t) (buf + offset); kern_return_t kr = vm_remap(mach_task_self(), &addr, range.size, 0xfff, 0, mach_task_self(), (vm_address_t) range.start, true, &cur, &max, VM_INHERIT_NONE); if(kr) { die("pdup: kr = %d", (int) kr); } #else memcpy(buf + offset, range.start, range.size); #endif return (prange_t) {buf, newsize}; }
int main(int argc, char **argv) { int c; unsigned i, j; unsigned tm = 0; struct state *s; char *buf; while((c = getopt(argc, argv, "r::R::w::W::dsb:n:i:t:h")) != EOF) switch(c) { case 'r': nt[LinRd] = optarg ? atoi(optarg) : 1; break; case 'R': nt[RndRd] = optarg ? atoi(optarg) : 1; break; case 'w': nt[LinWr] = optarg ? atoi(optarg) : 1; break; case 'W': nt[RndWr] = optarg ? atoi(optarg) : 1; break; case 'd': oflags |= O_DIRECT; break; case 's': oflags |= O_SYNC; break; case 'b': bs = atoi(optarg); break; case 'n': bc = atoi(optarg); break; case 'i': bm = atoi(optarg); break; case 't': tm = atoi(optarg); break; case 'h': puts( "iotest: perform I/O speed test\n" "Usage is: iotest [options] device-or-file\n" "options:\n" " -r[n] - linear read test (n readers)\n" " -R[n] - random read test (n readers)\n" " -w[n] - linear write test (n writers)\n" " -W[n] - random write test (n writers)\n" " -d - use direct I/O (O_DIRECT)\n" " -s - use syncronous I/O (O_SYNC)\n" " -b bs - blocksize (default is 8192)\n" " -n bc - block count (default is whole device/file)\n" " -i nb - number of I/O iterations to perform\n" " -t sec - time to spend on all I/O\n" " -h - this help\n" "It's ok to specify all, one or some of -r,-R,-w and -W\n" ); return 0; default: fprintf(stderr, "try `iotest -h' for help\n"); exit(1); } if (optind + 1 != argc) { fprintf(stderr, "exactly one device/file argument expected\n"); return 1; } fn = argv[optind]; ntt = nt[0] + nt[1] + nt[2] + nt[3]; if (!ntt) nt[LinRd] = ntt = 1; c = open(fn, (nt[LinWr] + nt[RndWr] ? O_RDWR : O_RDONLY) | oflags); if (c < 0) edie(fn); if (!bc) { unsigned long long sz; struct stat st; fstat(c, &st); if (st.st_size) sz = st.st_size; else ioctl(c, BLKGETSIZE64, &sz); bc = sz / bs; // fprintf(stderr, "size = %lld (%u blocks)\n", sz, bc); } close(c); if (nt[RndRd] || nt[RndWr]) { #ifdef USE_DEV_URANDOM randfd = open("/dev/urandom", O_RDONLY); if (randfd < 0) edie("/dev/urandom"); #else #if 0 struct timeval tv; gettimeofday(&tv, NULL); srand48(tv.tv_usec ^ getpid()); #else srand48(0xfeda432); // arbitrary, to get repeated values on repeated runs #endif #endif } states = calloc(ntt, sizeof(*states)); s = states; buf = valloc(ntt * bs); if (tm) { signal(SIGALRM, sig); alarm(tm); } running = ntt; for(j = 0; j < 4; ++j) for(i = 0; i < nt[j]; ++i) { pthread_t t; s->buf = buf; buf += bs; s->opi = j; s->i = i; pthread_create(&t, NULL, worker, s++); } while(running) { pthread_cond_wait(&rncond, &rnmtx); putc('\r', stderr); pst(stderr); } putc('\r', stderr); pst(stdout); putc('\n', stdout); return 0; }