lib lseek64
lib stat64
-lib mmap64
typ off64_t
typ struct_stat64 compile{
#include <sys/types.h>
}
}end
-#############################################################
-# See if memory mapping is available and fast enough to use
-#############################################################
-sys mman
-
-tst output{
- #include <sys/types.h>
- #include <sys/mman.h>
- #include <sys/times.h>
-
- _BEGIN_EXTERNS_
- int creat(char*, int);
- int open(char*, int);
- int unlink(char*);
- int read(int, char*, int);
- _END_EXTERNS_
-
- #define MAPSIZE (64*1024)
- #define BUFSIZE (MAPSIZE/8)
- #define WRITE (64)
- #define RUN (64)
-
- #define Failed(file) (unlink(file),1)
-
- #if _STD_
- main(int argc, char** argv)
- #else
- main(argc,argv)
- int argc;
- char** argv;
- #endif
- {
- caddr_t mm;
- char *t, *f;
- int i, fd, k, run;
- char file[1024], buf[MAPSIZE];
- struct tms stm, etm;
- clock_t rdtm, mmtm;
-
- /* create data file */
- f = argv[0]; t = file;
- while (*t = *f++)
- t++;
- *t++ = '.'; *t++ = 'D'; *t = 0;
- if ((fd = creat(file,0666)) < 0)
- return 1;
-
- for (i = 0; i < sizeof(buf); ++i)
- buf[i] = '0' + (i%10);
- for (i = 0; i < WRITE; ++i)
- if (write(fd,buf,sizeof(buf)) != sizeof(buf))
- return Failed(file);
- close(fd);
-
- /* read time */
- times(&stm);
- for(run = 0; run < RUN; ++run)
- { if((fd = open(file, 0)) < 0)
- return Failed(file);
- for (i = 0; i < WRITE; ++i)
- { for(k = 0; k < MAPSIZE; k += BUFSIZE)
- if (read(fd,buf,BUFSIZE) != BUFSIZE)
- return Failed(file);
- }
- close(fd);
- }
- times(&etm);
- rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
-
- /* mmap time */
- times(&stm);
- for(run = 0; run < RUN; ++run)
- { if ((fd = open(file,0)) < 0)
- return Failed(file);
- for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
- { if(mm)
- munmap(mm, MAPSIZE);
- mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
- (PROT_READ|PROT_WRITE),
- MAP_PRIVATE, fd, i*MAPSIZE );
- if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
- return Failed(file);
-
- /* the memcpy is < BUFSIZE to simulate the
- fact that functions like sfreserve/sfgetr do
- not do buffer copying.
- */
- t = (char*)mm;
- for(k = 0; k < MAPSIZE; k += BUFSIZE, t += BUFSIZE)
- memcpy(buf,t,(3*BUFSIZE)/4);
- }
- close(fd);
- }
- times(&etm);
- mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
-
- unlink(file);
-
- if(4*mmtm <= 3*rdtm) /* mmap is great! */
- printf("#define _mmap_worthy 2 \n");
- else if(4*mmtm <= 5*rdtm) /* mmap is good */
- printf("#define _mmap_worthy 1 \n");
-
- return 0;
- }
-}end
##################################################
# vfork and any associated header files
}
if (f->data && (!local || (f->flags & SF_STRING) || (f->bits & SF_MMAP))) { /* free buffer */
-#ifdef MAP_TYPE
- if (f->bits & SF_MMAP)
- SFMUNMAP(f, f->data, f->endb - f->data);
- else
-#endif
if (f->flags & SF_MALLOC)
data = (void *) f->data;
#define _NO_LARGEFILE64_SOURCE 1
#endif
#if !defined(_NO_LARGEFILE64_SOURCE) && \
- _lib_lseek64 && _lib_stat64 && _lib_mmap64 && defined(_typ_off64_t) && \
+ _lib_lseek64 && _lib_stat64 && defined(_typ_off64_t) && \
_typ_struct_stat64
# if !defined(_LARGEFILE64_SOURCE)
# define _LARGEFILE64_SOURCE 1
#undef _hdr_vfork
#undef _sys_vfork
#undef _lib_vfork
-#undef _sys_mman
#undef _sys_ioctl
#endif
#ifndef ESPIPE
#define ESPIPE 29
#endif
-/* see if we can use memory mapping for io */
-#if defined(_mmap_worthy)
-# ifdef _LARGEFILE64_SOURCE
-# undef mmap
-# endif
-# if _sys_mman
-# include <sys/mman.h>
-# endif
-# ifdef _LARGEFILE64_SOURCE
-# ifndef off_t
-# define off_t off64_t
-# endif
-# define mmap mmap64
-# endif
-#endif
/* function to get the decimal point for local environment */
#if _lib_locale
#ifdef MAXFLOAT /* we don't need these, so we zap them to avoid compiler warnings */
#ifndef MAP_VARIABLE
#define MAP_VARIABLE 0
#endif
-#ifndef _mmap_fixed
-#define _mmap_fixed 0
-#endif
/* the bottomless bit bucket */
#define DEVNULL "/dev/null"
#endif
#endif
-#if !_sys_mman
- extern void *mmap(void *, size_t, int, int, int, off_t);
- extern int munmap(void *, size_t);
-#endif
-
#ifdef WIN32
#undef SF_ERROR
#include <io.h>
if (f->mode & SF_GETR) {
f->mode &= ~SF_GETR;
-#ifdef MAP_TYPE
- if ((f->bits & SF_MMAP) && (f->tiny[0] += 1) >= (4 * SF_NMAP)) { /* turn off mmap to avoid page faulting */
- sfsetbuf(f, (void *) f->tiny, (size_t) SF_UNBOUND);
- f->tiny[0] = 0;
- } else
-#endif
if (f->getr) {
f->next[-1] = f->getr;
f->getr = 0;
if ((f->flags & (SF_SHARE | SF_PUBLIC)) ==
(SF_SHARE | SF_PUBLIC)
&& (addr = SFSK(f, 0, SEEK_CUR, f->disc)) != f->here) {
-#ifdef MAP_TYPE
- if ((f->bits & SF_MMAP) && f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
-#endif
f->endb = f->endr = f->endw = f->next = f->data;
f->here = addr;
} else {
}
f->mode = SF_WRITE | SF_LOCK;
-#ifdef MAP_TYPE
- if (f->bits & SF_MMAP) {
- if (f->data)
- SFMUNMAP(f, f->data, f->endb - f->data);
- (void) SFSETBUF(f, (void *) f->tiny, (size_t) SF_UNBOUND);
- }
-#endif
if (f->data == f->tiny) {
f->endb = f->data = f->next = NIL(uchar *);
f->size = 0;
SFLOCK(f, 0);
- /* if memory map must be a read stream, pretend data is gone */
-#ifdef MAP_TYPE
- if (f->bits & SF_MMAP) {
- f->here -= f->endb - f->next;
- if (f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- SFSK(f, f->here, SEEK_SET, f->disc);
- }
- SFOPEN(f, 0);
- SFMTXRETURN(f, 0);
- }
-#endif
-
switch (f->mode & ~SF_LOCK) {
default:
SFOPEN(f, 0);
if (f->next < f->endb) {
if (SFSYNC(f) < 0)
SFMTXRETURN(f, -1);
-#ifdef MAP_TYPE
- if ((f->bits & SF_MMAP) && f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
-#endif
f->next = f->endb = f->endr = f->endw = f->data;
}
}
SFMTXRETURN(f, (ssize_t) rv);
}
}
-#ifdef MAP_TYPE
- if (f->bits & SF_MMAP) {
- reg ssize_t a, round;
- Stat_t st;
-
- /* determine if we have to copy data to buffer */
- if ((uchar *) buf >= f->data && (uchar *) buf <= f->endb) {
- n += f->endb - f->next;
- buf = NIL(char *);
- }
-
- /* actual seek location */
- if ((f->flags & (SF_SHARE | SF_PUBLIC)) ==
- (SF_SHARE | SF_PUBLIC)
- && (r = SFSK(f, (Sfoff_t) 0, SEEK_CUR, dc)) != f->here)
- f->here = r;
- else
- f->here -= f->endb - f->next;
-
- /* before mapping, make sure we have data to map */
- if ((f->flags & SF_SHARE)
- || (size_t) (r = f->extent - f->here) < n) {
- if ((r = fstat(f->file, &st)) < 0)
- goto do_except;
- if ((r = (f->extent = st.st_size) - f->here) <= 0) {
- r = 0; /* eof */
- goto do_except;
- }
- }
-
- /* make sure current position is page aligned */
- if ((a = (size_t) (f->here % _Sfpage)) != 0) {
- f->here -= a;
- r += a;
- }
-
- /* map minimal requirement */
- if (r > (round = (1 + (n + a) / f->size) * f->size))
- r = round;
-
- if (f->data)
- SFMUNMAP(f, f->data, f->endb - f->data);
-
- for (;;) {
- f->data = (uchar *) mmap((caddr_t) 0, (size_t) r,
- (PROT_READ | PROT_WRITE),
- MAP_PRIVATE,
- f->file, (off_t) f->here);
- if (f->data && (caddr_t) f->data != (caddr_t) (-1))
- break;
- else {
- f->data = NIL(uchar *);
- if ((r >>= 1) < (_Sfpage * SF_NMAP) ||
- (errno != EAGAIN && errno != ENOMEM))
- break;
- }
- }
-
- if (f->data) {
- if (f->bits & SF_SEQUENTIAL)
- SFMMSEQON(f, f->data, r);
- f->next = f->data + a;
- f->endr = f->endb = f->data + r;
- f->endw = f->data;
- f->here += r;
-
- /* make known our seek location */
- (void) SFSK(f, f->here, SEEK_SET, dc);
-
- if (buf) {
- if (n > (size_t) (r - a))
- n = (ssize_t) (r - a);
- memcpy(buf, f->next, n);
- f->next += n;
- } else
- n = f->endb - f->next;
-
- SFMTXRETURN(f, n);
- } else {
- r = -1;
- f->here += a;
-
- /* reset seek pointer to its physical location */
- (void) SFSK(f, f->here, SEEK_SET, dc);
-
- /* make a buffer */
- (void) SFSETBUF(f, (void *) f->tiny,
- (size_t) SF_UNBOUND);
-
- if (!buf) {
- buf = (void *) f->data;
- n = f->size;
- }
- }
- }
-#endif
/* sync unseekable write streams to prevent deadlock */
if (!dosync && f->extent < 0) {
static void newpos(Sfio_t * f, Sfoff_t p)
{
-#ifdef MAP_TYPE
- if ((f->bits & SF_MMAP) && f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
-#endif
f->next = f->endr = f->endw = f->data;
f->endb = (f->mode & SF_WRITE) ? f->data + f->size : f->data;
if ((f->here = p) < 0) {
if ((p += type == SEEK_CUR ? s : 0) < 0)
goto done;
-#ifdef MAP_TYPE
- if (f->bits & SF_MMAP) { /* if mmap is not great, stop mmaping if moving around too much */
-#if _mmap_worthy < 2
- if ((f->next - f->data) < ((f->endb - f->data) / 4)) {
- SFSETBUF(f, (void *) f->tiny, (size_t) SF_UNBOUND);
- hardseek = 1; /* this forces a hard seek below */
- } else
-#endif
- { /* for mmap, f->here can be virtual */
- newpos(f, p);
- goto done;
- }
- }
-#endif
-
b = f->endb - f->data; /* amount of buffered data */
c = f->next - f->data; /* amount of data consumed */
reg Sfdisc_t *disc;
reg ssize_t osize, blksize;
reg int oflags, init, local;
-#ifdef MAP_TYPE
- reg int okmmap;
-#endif
Stat_t st;
SFONCE();
blksize = 0;
oflags = f->flags;
-#ifdef MAP_TYPE
- /* see if memory mapping is possible (see sfwrite for SF_BOTH) */
- okmmap = (buf || (f->flags & SF_STRING)
- || (f->flags & SF_RDWR) == SF_RDWR) ? 0 : 1;
-
- /* save old buffer info */
- if (f->bits & SF_MMAP) {
- if (f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
- } else
-#endif
if (f->data == f->tiny) {
f->data = NIL(uchar *);
f->size = 0;
if ((blksize = (ssize_t) st.st_blksize) > 0)
while ((blksize + (ssize_t) st.st_blksize) <= SF_PAGE)
blksize += (ssize_t) st.st_blksize;
-#endif
-#ifdef MAP_TYPE
- if (S_ISDIR(st.st_mode) || (int) st.st_size < SF_GRAIN)
- okmmap = 0;
#endif
if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
f->here = SFSK(f, (Sfoff_t) 0, SEEK_CUR, f->disc);
else
f->here = -1;
-
-#if O_TEXT /* no memory mapping with O_TEXT because read()/write() alter data stream */
-#ifdef MAP_TYPE
- if (okmmap && f->here >= 0 &&
- (fcntl((int) f->file, F_GETFL, 0) & O_TEXT))
- okmmap = 0;
-#endif
-#endif
}
if (f->here >= 0) {
_Sfpage = SF_PAGE;
}
}
-#ifdef MAP_TYPE
- if (okmmap && size && (f->mode & SF_READ) && f->extent >= 0) { /* see if we can try memory mapping */
- if (!disc)
- for (disc = f->disc; disc; disc = disc->disc)
- if (disc->readf)
- break;
- if (!disc) {
- f->bits |= SF_MMAP;
- if (size == (size_t) SF_UNBOUND) {
- if (blksize > _Sfpage)
- size = blksize * SF_NMAP;
- else
- size = _Sfpage * SF_NMAP;
- if (size > 256 * 1024)
- size = 256 * 1024;
- }
- }
- }
-#endif
/* get buffer space */
setbuf:
SFOPEN(f, 0);
SFMTXRETURN(f, -1);
}
-#ifdef MAP_TYPE
- if ((f->bits & SF_MMAP) && f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
-#endif
/* make stream appears uninitialized */
f->endb = f->endr = f->endw = f->data;
}
if (f->here != s && (f->mode & SF_READ)) { /* buffered data is known to be invalid */
-#ifdef MAP_TYPE
- if ((f->bits & SF_MMAP) && f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
-#endif
f->next = f->endb = f->endr = f->endw = f->data;
}
SFMTXRETURN(f, (Sfoff_t) (-1));
if (SFSYNC(f) < 0)
SFMTXRETURN(f, (Sfoff_t) (-1));
-#if MAP_TYPE
- if (f->mode == SF_READ && (f->bits & SF_MMAP) && f->data) {
- SFMUNMAP(f, f->data, f->endb - f->data);
- f->data = NIL(uchar *);
- }
-#endif
f->next = f->endb = f->endr = f->endw = f->data;
}