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