da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinref -D_def_map_ast=1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintst lib_mmap note{ standard mmap interface that works }end execute{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define MAPSIZE (64*1024)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define BUFSIZE (8*1024)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define WRITE (64)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define Failed(file) (remove(file),1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin main(int argc, char** argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin main(argc,argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char** argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin caddr_t mm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *t, *u, *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i, fd, okfixed;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char file[1024], buf[MAPSIZE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tms stm, etm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock_t rdtm, mmtm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* create data file in a local fs if possible */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (access(f = "/tmp", 0) == 0 ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin access(f = "/usr/tmp", 0) == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*t = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*t = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*t == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*t != '.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '.'; *t++ = 'D'; *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < sizeof(buf); ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buf[i] = '0' + (i%10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < WRITE; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (write(fd,buf,sizeof(buf)) != sizeof(buf))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if can overwrite fixed map */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #ifndef MAP_VARIABLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define MAP_VARIABLE 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((fd = open(file, O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mm = mmap((caddr_t)0, sizeof(buf), (PROT_READ|PROT_WRITE),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (MAP_PRIVATE|MAP_VARIABLE), fd, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mm == (caddr_t)0 || mm == (caddr_t)(-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mm = mmap(mm, sizeof(buf), (PROT_READ|PROT_WRITE),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (MAP_PRIVATE|MAP_FIXED), fd, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin okfixed = (mm == (caddr_t)0 || mm == (caddr_t)(-1)) ? 0 : 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin munmap(mm, sizeof(buf));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* read time */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd = open(file, O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&stm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < WRITE; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (read(fd,buf,BUFSIZE) != BUFSIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&etm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* mmap time */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((fd = open(file, O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&stm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(okfixed)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { mm = (caddr_t)mmap(mm, MAPSIZE,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (PROT_READ|PROT_WRITE),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (MAP_PRIVATE | (mm ? MAP_FIXED : MAP_VARIABLE)),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd, i*MAPSIZE );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin munmap(mm, MAPSIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (PROT_READ|PROT_WRITE),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (MAP_PRIVATE|MAP_VARIABLE),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd, i*MAPSIZE );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&etm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return rdtm+60 < mmtm ? 1 : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintst lib_mmap64 -D_LARGEFILE64_SOURCE note{ mmap64 interface and implementation work }end execute{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if !_lib_mmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off64_t off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat64 st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char file[32] = {'/','t','m','p','/','m','m','X','X','X','X','X','X'};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* hey, stubs are supposed to fail! */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!mktemp(file) || (fd = open64(file, O_CREAT|O_WRONLY, 0600)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off = (1<<8);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off *= off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (lseek64(fd, off, SEEK_SET) != off)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(file) + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (write(fd, file, n) != n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (close(fd) < 0 || (fd = open64(file, O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = mmap64((caddr_t)0, (size_t)n, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, off)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strcmp(s, file))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintst mmap_anon note{ use mmap MAP_ANON to get raw memory }end execute{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if !_lib_mmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define MAP_ANON MAP_ANONYMOUS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { void *addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (addr && addr != (void*)(-1)) ? 0 : 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintst mmap_devzero note{ use mmap on /dev/zero to get raw memory }end execute{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if !_lib_mmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd = open("/dev/zero", O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (addr && addr != (void*)(-1)) ? 0 : 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintst note{ mmap is worth using }end output{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if !_lib_mmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define MAPSIZE (64*1024)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define BUFSIZE (MAPSIZE/8)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define WRITE (64)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define RUN (64)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define Failed(file) (remove(file),1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin main(int argc, char** argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin main(argc,argv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char** argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin caddr_t mm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *t, *f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int i, fd, k, run;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char file[1024], buf[MAPSIZE];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct tms stm, etm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clock_t rdtm, mmtm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* create data file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = argv[0]; t = file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*t = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = '.'; *t++ = 'D'; *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < sizeof(buf); ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buf[i] = '0' + (i%10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < WRITE; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (write(fd,buf,sizeof(buf)) != sizeof(buf))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* read time */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&stm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(run = 0; run < RUN; ++run)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((fd = open(file, O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < WRITE; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { for(k = 0; k < MAPSIZE; k += BUFSIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (read(fd,buf,BUFSIZE) != BUFSIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&etm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* mmap time */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&stm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(run = 0; run < RUN; ++run)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if ((fd = open(file, O_RDWR)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin munmap(mm, MAPSIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (PROT_READ|PROT_WRITE),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin MAP_PRIVATE, fd, i*MAPSIZE );
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return Failed(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* the memcpy is < BUFSIZE to simulate the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fact that functions like sfreserve/sfgetr do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin not do buffer copying.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (char*)mm;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(k = 0; k < MAPSIZE; k += BUFSIZE, t += BUFSIZE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(buf,t,(3*BUFSIZE)/4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin times(&etm);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin remove(file);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(4*mmtm <= 3*rdtm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin printf("#define _mmap_worthy 2 /* mmap is great */\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(4*mmtm <= 5*rdtm)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin printf("#define _mmap_worthy 1 /* mmap is good */\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* some systems get it wrong but escape concise detection */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #ifndef _NO_MMAP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if __CYGWIN__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #define _NO_MMAP 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #if _NO_MMAP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #undef _lib_mmap
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #undef _lib_mmap64
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #undef _mmap_anon
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #undef _mmap_devzero
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin #undef _mmap_worthy