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