1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/* read_load.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include "trivial.h"
#include "programs.h"
#include "sysinfo.h"
#include "read_load.h"
#define MIN_BLK_SIZE 1024
extern char *opt_tmpf;
extern int opt_cold;
extern int opt_prog_bar;
int prep_read_load(void)
{
FILE *fp;
void *buf;
int i;
struct stat statbuf;
long mem;
if(get_ram(&mem)){
printe("ram size not available, aborting\n");
exit(2);
}
printd("ram=%lu\n", mem);
if(stat(opt_tmpf, &statbuf)){
if(errno!=ENOENT){
printsys("could not stat temporary file %s\n",opt_tmpf);
}
printd("file %s not there, creating it\n", opt_tmpf);
} else if(opt_cold){
long diff=statbuf.st_size/1024-mem;
if(diff<0)
diff *= -1;
if(diff<100){
/*
* file is roughly the same size, it may have been
* created by ourselves or do_io_load(), in any case,
* since we open it ro, we might as well use it
* (we're assuming there's no cache for it)
*/
printd("found usable file, returning\n");
return 0;
}
}
printout("Creating temporary file %s of size=%lu kB\n", opt_tmpf, mem);
if(!(fp=fopen(opt_tmpf, "w"))){
printsys("Cannot open temporary file %s, aborting\n", opt_tmpf);
}
if(stat(opt_tmpf, &statbuf)){
printsys("could not stat temporary file %s\n",opt_tmpf);
}
if(statbuf.st_blksize<MIN_BLK_SIZE){
statbuf.st_blksize=MIN_BLK_SIZE;
}
if(!(buf=calloc(1, statbuf.st_blksize))){
printsys("error allocating io buffer\n");
}
printd("mem=%lu, blksize=%lu\n", mem, (unsigned long)statbuf.st_blksize);
mem/=statbuf.st_blksize/1024;
printd("using mem=%lu\n", mem);
for(i=0; i<mem; i++){
if(fwrite(buf, statbuf.st_blksize, 1, fp)!=1){
printsys("Error writing to temporary file %s, "
"aborting\n", opt_tmpf);
}
if(opt_prog_bar){
print_prog_bar((100*i)/mem);
}
}
if(opt_prog_bar){
print_prog_bar(100);
}
printf("\n");
return 0;
}
int do_read_load(void)
{
int tmp, dev_null;
struct stat statbuf;
void *buf;
int rd, i;
unsigned long step, bsize;
if((tmp=open(opt_tmpf, O_RDONLY))==-1){
if(errno!=ENOENT){
printsys("could not open tmp file %s\n", opt_tmpf);
} else {
printe("No tmp file for read load, how does bash "
"contest handle this?\n");
exit(2);
}
}
if((dev_null=open("/dev/null", O_WRONLY))==-1){
printsys("could not open \"/dev/null\" for output\n");
}
if(stat(opt_tmpf, &statbuf)){
printsys("could not stat tmp file %s\n", opt_tmpf);
}
bsize=statbuf.st_blksize>MIN_BLK_SIZE ? statbuf.st_blksize : MIN_BLK_SIZE;
if(!(buf=malloc(bsize))){
printsys("could not allocate buffer of size %lu\n");
}
step=statbuf.st_size/(10 * bsize);
printd("bsize=%lu, st_size=%llu, using step=%lu\n", bsize,
(unsigned long long)statbuf.st_size, step);
for(;;){
i=0;
while((rd=read(tmp , buf, bsize))>0){
/*
* this is just bug-for-bug compatibility with bash
* contest: since we're just in it for generating
* read load, there's no point in writing the data
* to /dev/null
* TODO: maybe add an option to disable all emulation of
* the side-effects from using bash
*/
if(write(dev_null, buf, rd)!=rd){
printsys("error writing to \"/dev/null\", cowardly "
"aborting\n");
}
if(!(i++ % step)){
if(write(TMP_FD, buf, 10)==-1){
printsys("error reporting progress\n");
}
}
}
if(lseek(tmp, (off_t)0, SEEK_SET)==-1){
printsys("error rewinding tmp file %s\n", opt_tmpf);
}
}
return 0;
}
int cleanup_read_load(void)
{
if(unlink(opt_tmpf)){
printsys("error unlinking %s\n", opt_tmpf);
}
return 0;
}
|