/* Author: Mark Moraes */ /*LINTLIBRARY*/ #include "defs.h" #include "globals.h" RCSID("$Id: getmem.c,v 1.1.1.1 1998/02/10 21:01:46 mea Exp $") /* gets memory from the system via the sbrk() system call. Most Un*xes */ univptr_t _mal_sbrk(nbytes) size_t nbytes; { static char *lastsbrk = NULL; char *p; p = (char *) sbrk((int) nbytes); if (p == (char*)-1L) { return p; /* Ran out of memory! */ } /* * Some old SVR3 apparently have a kernel bug: after several sbrk * calls, sbrk suddenly starts returning values lower than the ones it * returned before. Yeesh! */ if (nbytes > 0) { ASSERT(p > lastsbrk, "system call error? sbrk returned value lower than previous calls"); lastsbrk = p; } return p; } /* * gets memory from the system via mmaping a file. This was written for SunOS * versions greater than 4.0. The filename is specified by the environment * variable CSRIMALLOC_MMAPFILE or by the call to mal_mmapset(). Using this * instead of sbrk() has the advantage of bypassing the swap system, allowing * processes to run with huge heaps even on systems configured with small swap * space. */ static char *mmap_filename; #ifdef HAVE_MMAP /* Sun gets size_t wrong, and these follow, thanks to my #defines! */ #undef caddr_t /* #undef size_t */ #undef u_char #include #include #include #include univptr_t _mal_mmap(nbytes) size_t nbytes; { static struct { int i_fd; caddr_t i_data; caddr_t i_end; size_t i_size; size_t i_alloced; } mmf; struct stat stbuf; if (mmf.i_data != NULL) { /* Already initialized & mmaped the file */ univptr_t p = mmf.i_data + mmf.i_alloced; if ((char *) p + nbytes > mmf.i_end) { errno = ENOMEM; return (univptr_t) -1; } mmf.i_alloced += nbytes; return p; } /* * This code is run the first time the function is called, it opens * the file and mmaps the */ if (mmap_filename == NULL) { mmap_filename = getenv("CSRIMALLOC_MMAPFILE"); if (mmap_filename == NULL) { errno = ENOMEM; return (univptr_t) -1; } } mmf.i_fd = open(mmap_filename, O_RDWR, 0666); if (mmf.i_fd < 0 || fstat(mmf.i_fd, &stbuf) < 0) return (univptr_t) -1; if (stbuf.st_size < nbytes) { errno = ENOMEM; return (univptr_t) -1; } mmf.i_size = stbuf.st_size; mmf.i_data = mmap((caddr_t) 0, mmf.i_size, PROT_READ|PROT_WRITE, MAP_SHARED, mmf.i_fd, (off_t) 0); if (mmf.i_data == (caddr_t) -1) return (univptr_t) -1; mmf.i_end = mmf.i_data + mmf.i_size; mmf.i_alloced = nbytes; #if defined(MADV_RANDOM) && !defined(NO_MADVISE) /* Advise vm system of random access pattern */ (void) madvise(mmf.i_data, mmf.i_size, MADV_RANDOM); #endif return mmf.i_data; } #else /* !HAVE_MMAP */ univptr_t _mal_mmap(nbytes) size_t nbytes; { return (univptr_t) -1; } #endif /* HAVE_MMAP */ void mal_mmap(fname) char *fname; { _malloc_memfunc = _mal_mmap; mmap_filename = fname; }