/* * LIB/XMAP.C * * Some machines fail if mmap() is passed with odd arguments. The xmap() calls * page-align everything, allowing non-aligned offsets and sizes to be * requested. * * (c)Copyright 1998, Matthew Dillon, All Rights Reserved. Refer to * the COPYRIGHT file in the base directory of this distribution * for specific rights granted. */ #include "defs.h" Prototype void *xmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); Prototype void xadvise(const void *ptr, int bytes, int how); Prototype void xunmap(void *addr, size_t len); static int XPageMask; void * xmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { int n; void *ptr; struct stat st; if (XPageMask == 0) XPageMask = getpagesize() - 1; n = offset & XPageMask; offset -= n; len += n; len = (len + XPageMask) & ~XPageMask; st.st_size = 0; fstat(fd, &st); if (offset + len > ((st.st_size + XPageMask) & ~XPageMask)) { ptr = NULL; } else { ptr = (void *)mmap((caddr_t)addr, len, prot, flags, fd, offset); } if (ptr == (void *)-1) ptr = NULL; if (ptr) return((char *)ptr + n); return(NULL); } void xadvise(const void *ptr, int bytes, int how) { #if USE_MADVISE /* * Some systems require page-bounded requests. * Satisfy them. Note: can use int for off, but * long may be more optimal on 64 bit systems. */ { long off; if (XPageMask == 0) XPageMask = getpagesize() - 1; off = (int)ptr & XPageMask; ptr = (const char *)ptr - off; bytes = bytes + off; bytes = (bytes + XPageMask) & ~XPageMask; } switch(how) { #ifdef MADV_WILLNEED /* * pre-fault pages into the page table that are in the * buffer cache */ case XADV_WILLNEED: madvise((caddr_t)ptr, bytes, MADV_WILLNEED); break; #endif #ifdef MADV_SEQUENTIAL /* * Cause page faults to read-ahead more. */ case XADV_SEQUENTIAL: madvise((caddr_t)ptr, bytes, MADV_SEQUENTIAL); break; } #endif #endif } void xunmap(void *ptr, size_t len) { long n; /* * Some systems require page-bounded arguments * Satisfy them. Note: 'n' can be an int since * it is only used to hold the masked offset. * However, using long may be more optimal on * 64 bit systems. */ if (XPageMask == 0) XPageMask = getpagesize() - 1; n = (long)ptr & XPageMask; ptr = (char *)ptr - n; len += n; len = (len + XPageMask) & ~XPageMask; munmap((caddr_t)ptr, len); }