1ref -D_def_map_ast=1 2 3sys mman 4 5tst lib_mmap note{ standard mmap interface that works }end execute{ 6 #include <unistd.h> 7 #include <fcntl.h> 8 #include <sys/types.h> 9 #include <sys/mman.h> 10 #include <sys/stat.h> 11 #include <sys/times.h> 12 13 #define MAPSIZE (64*1024) 14 #define BUFSIZE (8*1024) 15 #define WRITE (64) 16 17 #define Failed(file) (remove(file),1) 18 19 int 20 #if _STD_ 21 main(int argc, char** argv) 22 #else 23 main(argc,argv) 24 int argc; 25 char** argv; 26 #endif 27 { 28 caddr_t mm; 29 char *t, *u, *f; 30 int i, fd, okfixed; 31 char file[1024], buf[MAPSIZE]; 32 struct tms stm, etm; 33 clock_t rdtm, mmtm; 34 35 /* create data file in a local fs if possible */ 36 t = file; 37 if (access(f = "/tmp", 0) == 0 || 38 access(f = "/usr/tmp", 0) == 0) 39 { 40 while (*t = *f++) 41 t++; 42 *t++ = '/'; 43 } 44 u = t; 45 f = argv[0]; 46 while (*t = *f++) 47 if (*t == '/') 48 t = u; 49 else if (*t != '.') 50 t++; 51 *t++ = '.'; *t++ = 'D'; *t = 0; 52 if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0) 53 return 1; 54 55 for (i = 0; i < sizeof(buf); ++i) 56 buf[i] = '0' + (i%10); 57 for (i = 0; i < WRITE; ++i) 58 if (write(fd,buf,sizeof(buf)) != sizeof(buf)) 59 return Failed(file); 60 close(fd); 61 62 /* see if can overwrite fixed map */ 63 #ifndef MAP_VARIABLE 64 #define MAP_VARIABLE 0 65 #endif 66 if ((fd = open(file, O_RDWR)) < 0) 67 return Failed(file); 68 69 mm = mmap((caddr_t)0, sizeof(buf), (PROT_READ|PROT_WRITE), 70 (MAP_PRIVATE|MAP_VARIABLE), fd, 0); 71 if(mm == (caddr_t)0 || mm == (caddr_t)(-1)) 72 return Failed(file); 73 mm = mmap(mm, sizeof(buf), (PROT_READ|PROT_WRITE), 74 (MAP_PRIVATE|MAP_FIXED), fd, 0); 75 okfixed = (mm == (caddr_t)0 || mm == (caddr_t)(-1)) ? 0 : 1; 76 munmap(mm, sizeof(buf)); 77 close(fd); 78 79 /* read time */ 80 if((fd = open(file, O_RDWR)) < 0) 81 return Failed(file); 82 times(&stm); 83 for (i = 0; i < WRITE; ++i) 84 if (read(fd,buf,BUFSIZE) != BUFSIZE) 85 return Failed(file); 86 times(&etm); 87 close(fd); 88 rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime); 89 90 /* mmap time */ 91 if ((fd = open(file, O_RDWR)) < 0) 92 return Failed(file); 93 times(&stm); 94 for(i = 0, mm = (caddr_t)0; i < WRITE; ++i) 95 { if(okfixed) 96 { mm = (caddr_t)mmap(mm, MAPSIZE, 97 (PROT_READ|PROT_WRITE), 98 (MAP_PRIVATE | (mm ? MAP_FIXED : MAP_VARIABLE)), 99 fd, i*MAPSIZE ); 100 } 101 else 102 { if(mm) 103 munmap(mm, MAPSIZE); 104 mm = (caddr_t)mmap((caddr_t)0, MAPSIZE, 105 (PROT_READ|PROT_WRITE), 106 (MAP_PRIVATE|MAP_VARIABLE), 107 fd, i*MAPSIZE ); 108 } 109 if(mm == (caddr_t)(-1) || mm == (caddr_t)0) 110 return Failed(file); 111 } 112 times(&etm); 113 close(fd); 114 remove(file); 115 mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime); 116 117 return rdtm+60 < mmtm ? 1 : 0; 118 } 119}end 120 121tst lib_mmap64 -D_LARGEFILE64_SOURCE note{ mmap64 interface and implementation work }end execute{ 122 #if !_lib_mmap 123 ( 124 #endif 125 126 #include <unistd.h> 127 #include <fcntl.h> 128 #include <sys/types.h> 129 #include <sys/mman.h> 130 #include <sys/stat.h> 131 132 int 133 main() 134 { 135 off64_t off; 136 int fd; 137 int n; 138 char* s; 139 struct stat64 st; 140 char file[32] = {'/','t','m','p','/','m','m','X','X','X','X','X','X'}; 141 142 /* hey, stubs are supposed to fail! */ 143 if (stat64(".", &st) || !st.st_mode || !st.st_mtime) 144 return 1; 145 if (!mktemp(file) || (fd = open64(file, O_CREAT|O_WRONLY, 0600)) < 0) 146 { 147 remove(file); 148 return 1; 149 } 150 off = (1<<8); 151 off *= off; 152 if (lseek64(fd, off, SEEK_SET) != off) 153 { 154 remove(file); 155 return 1; 156 } 157 n = strlen(file) + 1; 158 if (write(fd, file, n) != n) 159 { 160 remove(file); 161 return 1; 162 } 163 if (close(fd) < 0 || (fd = open64(file, O_RDWR)) < 0) 164 { 165 remove(file); 166 return 1; 167 } 168 if (!(s = mmap64((caddr_t)0, (size_t)n, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, off))) 169 { 170 remove(file); 171 return 1; 172 } 173 if (strcmp(s, file)) 174 { 175 remove(file); 176 return 1; 177 } 178 close(fd); 179 remove(file); 180 return 0; 181 } 182}end 183 184tst mmap_anon note{ use mmap MAP_ANON to get raw memory }end execute{ 185 #if !_lib_mmap 186 ( 187 #endif 188 #include <unistd.h> 189 #include <fcntl.h> 190 #include <sys/types.h> 191 #include <sys/mman.h> 192 #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON) 193 #define MAP_ANON MAP_ANONYMOUS 194 #endif 195 int 196 main() 197 { void *addr; 198 addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0); 199 return (addr && addr != (void*)(-1)) ? 0 : 1; 200 } 201}end 202 203tst mmap_devzero note{ use mmap on /dev/zero to get raw memory }end execute{ 204 #if !_lib_mmap 205 ( 206 #endif 207 #include <unistd.h> 208 #include <fcntl.h> 209 #include <sys/types.h> 210 #include <sys/mman.h> 211 int 212 main() 213 { int fd; 214 void *addr; 215 if((fd = open("/dev/zero", O_RDWR)) < 0) 216 return 1; 217 addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0); 218 return (addr && addr != (void*)(-1)) ? 0 : 1; 219 } 220}end 221 222tst note{ mmap is worth using }end output{ 223 #if !_lib_mmap 224 ( 225 #endif 226 #include <unistd.h> 227 #include <fcntl.h> 228 #include <sys/types.h> 229 #include <sys/mman.h> 230 #include <sys/stat.h> 231 #include <sys/times.h> 232 233 #define MAPSIZE (64*1024) 234 #define BUFSIZE (MAPSIZE/8) 235 #define WRITE (64) 236 #define RUN (64) 237 238 #define Failed(file) (remove(file),1) 239 240 int 241 #if _STD_ 242 main(int argc, char** argv) 243 #else 244 main(argc,argv) 245 int argc; 246 char** argv; 247 #endif 248 { 249 caddr_t mm; 250 char *t, *f; 251 int i, fd, k, run; 252 char file[1024], buf[MAPSIZE]; 253 struct tms stm, etm; 254 clock_t rdtm, mmtm; 255 256 /* create data file */ 257 f = argv[0]; t = file; 258 while (*t = *f++) 259 t++; 260 *t++ = '.'; *t++ = 'D'; *t = 0; 261 if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0) 262 return 1; 263 264 for (i = 0; i < sizeof(buf); ++i) 265 buf[i] = '0' + (i%10); 266 for (i = 0; i < WRITE; ++i) 267 if (write(fd,buf,sizeof(buf)) != sizeof(buf)) 268 return Failed(file); 269 close(fd); 270 271 /* read time */ 272 times(&stm); 273 for(run = 0; run < RUN; ++run) 274 { if((fd = open(file, O_RDWR)) < 0) 275 return Failed(file); 276 for (i = 0; i < WRITE; ++i) 277 { for(k = 0; k < MAPSIZE; k += BUFSIZE) 278 if (read(fd,buf,BUFSIZE) != BUFSIZE) 279 return Failed(file); 280 } 281 close(fd); 282 } 283 times(&etm); 284 rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime); 285 286 /* mmap time */ 287 times(&stm); 288 for(run = 0; run < RUN; ++run) 289 { if ((fd = open(file, O_RDWR)) < 0) 290 return Failed(file); 291 for(i = 0, mm = (caddr_t)0; i < WRITE; ++i) 292 { if(mm) 293 munmap(mm, MAPSIZE); 294 mm = (caddr_t)mmap((caddr_t)0, MAPSIZE, 295 (PROT_READ|PROT_WRITE), 296 MAP_PRIVATE, fd, i*MAPSIZE ); 297 if(mm == (caddr_t)(-1) || mm == (caddr_t)0) 298 return Failed(file); 299 300 /* the memcpy is < BUFSIZE to simulate the 301 fact that functions like sfreserve/sfgetr do 302 not do buffer copying. 303 */ 304 t = (char*)mm; 305 for(k = 0; k < MAPSIZE; k += BUFSIZE, t += BUFSIZE) 306 memcpy(buf,t,(3*BUFSIZE)/4); 307 } 308 close(fd); 309 } 310 times(&etm); 311 mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime); 312 313 remove(file); 314 315 if(4*mmtm <= 3*rdtm) 316 printf("#define _mmap_worthy 2 /* mmap is great */\n"); 317 else if(4*mmtm <= 5*rdtm) 318 printf("#define _mmap_worthy 1 /* mmap is good */\n"); 319 320 else 321 return 1; 322 return 0; 323 } 324}end 325 326cat{ 327 328 /* some systems get it wrong but escape concise detection */ 329 #ifndef _NO_MMAP 330 #if __CYGWIN__ 331 #define _NO_MMAP 1 332 #endif 333 #endif 334 335 #if _NO_MMAP 336 #undef _lib_mmap 337 #undef _lib_mmap64 338 #undef _mmap_anon 339 #undef _mmap_devzero 340 #undef _mmap_worthy 341 #endif 342}end 343