1 /* testvm - service-started code that goes with test73.o 2 */ 3 4 #include <minix/drivers.h> 5 #include <minix/chardriver.h> 6 #include <minix/ds.h> 7 #include <sys/stat.h> 8 #include <sys/mman.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <fcntl.h> 12 13 #include "testvm.h" 14 #include "common.h" 15 #include "testcache.h" 16 17 #define MYMAJOR 40 /* doesn't really matter, shouldn't be NO_DEV though */ 18 #define MYDEV makedev(MYMAJOR, 1) 19 20 static char *pipefilename = NULL, *progname; 21 int pipefd = -1; 22 23 int memfd; 24 25 static char *bdata = NULL; 26 27 int dowriteblock(int b, int blocksize, u32_t seed, char *block) 28 { 29 int r; 30 char *bdata; 31 int mustset = 0; 32 u64_t dev_off = (u64_t) b * blocksize; 33 34 if((bdata = vm_map_cacheblock(MYDEV, dev_off, 35 VMC_NO_INODE, 0, NULL, blocksize)) == MAP_FAILED) { 36 if((bdata = mmap(0, blocksize, 37 PROT_READ|PROT_WRITE, MAP_ANON, -1, 0)) == MAP_FAILED) { 38 printf("mmap failed\n"); 39 exit(1); 40 } 41 mustset = 1; 42 } 43 44 memcpy(bdata, block, blocksize); 45 46 if(mustset && (r=vm_set_cacheblock(bdata, MYDEV, dev_off, 47 VMC_NO_INODE, 0, NULL, blocksize, 0)) != OK) { 48 printf("dowriteblock: vm_set_cacheblock failed %d\n", r); 49 exit(1); 50 } 51 52 if(munmap(bdata, blocksize) < 0) { 53 printf("dowriteblock: munmap failed %d\n", r); 54 exit(1); 55 } 56 57 return blocksize; 58 } 59 60 int readblock(int b, int blocksize, u32_t seed, char *block) 61 { 62 char *bdata; 63 u64_t dev_off = (u64_t) b * blocksize; 64 65 if((bdata = vm_map_cacheblock(MYDEV, dev_off, 66 VMC_NO_INODE, 0, NULL, blocksize)) == MAP_FAILED) { 67 return OK_BLOCK_GONE; 68 } 69 70 memcpy(block, bdata, blocksize); 71 72 if(munmap(bdata, blocksize) < 0) { 73 printf("dowriteblock: munmap failed\n"); 74 exit(1); 75 } 76 77 return blocksize; 78 } 79 80 void testend(void) { } 81 82 static void 83 writepipe(struct info *i) 84 { 85 if(write(pipefd, i, sizeof(*i)) != sizeof(*i)) { 86 printf("%s: pipe write failed\n", progname); 87 exit(1); 88 } 89 } 90 91 static int 92 testinit(void) 93 { 94 struct stat st; 95 int attempts = 0; 96 97 for(attempts = 0; attempts < 5 && pipefd < 0; attempts++) { 98 if(attempts > 0) sleep(1); 99 pipefd = open(pipefilename, O_WRONLY | O_NONBLOCK); 100 } 101 102 if(pipefd < 0) { 103 printf("%s: could not open pipe %s, errno %d\n", 104 progname, pipefilename, errno); 105 exit(1); 106 } 107 108 if(fstat(pipefd, &st) < 0) { 109 printf("%s: could not fstat pipe %s\n", progname, pipefilename); 110 exit(1); 111 } 112 113 if(!(st.st_mode & I_NAMED_PIPE)) { 114 printf("%s: file %s is not a pipe\n", progname, pipefilename); 115 exit(1); 116 } 117 118 return OK; 119 } 120 121 static int 122 sef_cb_init(int type, sef_init_info_t *UNUSED(info)) 123 { 124 return OK; 125 } 126 127 static void 128 init(void) 129 { 130 /* SEF init */ 131 sef_setcb_init_fresh(sef_cb_init); 132 sef_setcb_init_lu(sef_cb_init); 133 sef_setcb_init_restart(sef_cb_init); 134 135 sef_startup(); 136 } 137 138 139 140 int 141 main(int argc, char *argv[]) 142 { 143 struct info info; 144 int big; 145 u32_t totalmem, freemem, cachedmem; 146 147 progname = argv[0]; 148 149 if(argc < 2) { printf("no args\n"); return 1; } 150 151 pipefilename=argv[1]; 152 153 big = !!strstr(pipefilename, "big"); 154 155 init(); 156 157 info.result = time(NULL); 158 159 if(testinit() != OK) { printf("%s: testinit failed\n", progname); return 1; } 160 161 cachequiet(!big); 162 163 if(!(bdata = alloc_contig(PAGE_SIZE, 0, NULL))) { 164 printf("could not allocate block\n"); 165 exit(1); 166 } 167 168 if(dotest(PAGE_SIZE, 10, 3)) { e(11); exit(1); } 169 if(dotest(PAGE_SIZE, 1000, 3)) { e(11); exit(1); } 170 if(dotest(PAGE_SIZE, 50000, 3)) { e(11); exit(1); } 171 if(big) { 172 getmem(&totalmem, &freemem, &cachedmem); 173 if(dotest(PAGE_SIZE, totalmem*1.5, 3)) { e(11); exit(1); } 174 } 175 176 info.result = 0; 177 178 writepipe(&info); 179 180 vm_clear_cache(MYDEV); 181 182 return 0; 183 } 184 185