/* Support for an sbrk-like function that uses mmap.
Copyright 1992, 2000 Free Software Foundation, Inc.
- Contributed by Fred Fish at Cygnus Support. fnf@cygnus.com
+ Contributed by Fred Fish at Cygnus Support. fnf@cygnus.com */
-This file is part of the GNU C Library.
+/* Copyright (c) 2010. The SimGrid Team.
+ * All rights reserved. */
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#if defined(HAVE_MMAP)
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
#ifdef HAVE_UNISTD_H
-#include <unistd.h> /* Prototypes for lseek */
+#include <unistd.h> /* Prototypes for lseek */
#endif
#include <stdio.h>
#include <fcntl.h>
#endif
#include "mmprivate.h"
+#include "xbt/ex.h"
/* Cache the pagesize for the current host machine. Note that if the host
does not readily provide a getpagesize() function, we need to emulate it
static size_t pagesize;
#if NEED_DECLARATION_GETPAGESIZE
-extern int getpagesize PARAMS ((void));
+extern int getpagesize(void);
#endif
-#define PAGE_ALIGN(addr) (PTR) (((long)(addr) + pagesize - 1) & \
+#define PAGE_ALIGN(addr) (void*) (((long)(addr) + pagesize - 1) & \
~(pagesize - 1))
/* Return MAP_PRIVATE if MDP represents /dev/zero. Otherwise, return
MAP_SHARED. */
-#define MAP_PRIVATE_OR_SHARED(MDP) ((MDP -> flags & MMALLOC_DEVZERO) \
+#define MAP_PRIVATE_OR_SHARED(MDP) (( MDP -> flags & MMALLOC_ANONYMOUS) \
? MAP_PRIVATE \
: MAP_SHARED)
amount to either add to or subtract from the existing region. Works
like sbrk(), but using mmap(). */
-PTR
-__mmalloc_mmap_morecore (mdp, size)
- struct mdesc *mdp;
- int size;
+void *__mmalloc_mmap_morecore(struct mdesc *mdp, int size)
{
- PTR result = NULL;
- off_t foffset; /* File offset at which new mapping will start */
- size_t mapbytes; /* Number of bytes to map */
- PTR moveto; /* Address where we wish to move "break value" to */
- PTR mapto; /* Address we actually mapped to */
- char buf = 0; /* Single byte to write to extend mapped file */
+ ssize_t test = 0;
+ void *result = NULL;
+ off_t foffset; /* File offset at which new mapping will start */
+ size_t mapbytes; /* Number of bytes to map */
+ void *moveto; /* Address where we wish to move "break value" to */
+ void *mapto; /* Address we actually mapped to */
+ char buf = 0; /* Single byte to write to extend mapped file */
if (pagesize == 0)
pagesize = getpagesize();
- if (size == 0)
- {
+ if (size == 0) {
/* Just return the current "break" value. */
- result = mdp -> breakval;
- }
- else if (size < 0)
- {
+ result = mdp->breakval;
+
+ } else if (size < 0) {
/* We are deallocating memory. If the amount requested would cause
- us to try to deallocate back past the base of the mmap'd region
- then do nothing, and return NULL. Otherwise, deallocate the
- memory and return the old break value. */
- if (mdp -> breakval + size >= mdp -> base)
- {
- result = (PTR) mdp -> breakval;
- mdp -> breakval += size;
- moveto = PAGE_ALIGN (mdp -> breakval);
- munmap (moveto, (size_t) (mdp -> top - moveto) - 1);
- mdp -> top = moveto;
- }
- }
- else
- {
+ us to try to deallocate back past the base of the mmap'd region
+ then do nothing, and return NULL. Otherwise, deallocate the
+ memory and return the old break value. */
+ if (((char *) mdp->breakval) + size >= (char *) mdp->base) {
+ result = (void *) mdp->breakval;
+ mdp->breakval = (char *) mdp->breakval + size;
+ moveto = PAGE_ALIGN(mdp->breakval);
+ munmap(moveto,
+ (size_t) (((char *) mdp->top) - ((char *) moveto)) - 1);
+ mdp->top = moveto;
+ }
+ } else {
/* We are allocating memory. Make sure we have an open file
- descriptor if not working with anonymous memory. */
- if ( !(mdp->flags & MMALLOC_ANONYMOUS) && mdp -> fd < 0)
- {
- result = NULL;
- }
- else if (mdp -> breakval + size > mdp -> top)
- {
- /* The request would move us past the end of the currently
- mapped memory, so map in enough more memory to satisfy
- the request. This means we also have to grow the mapped-to
- file by an appropriate amount, since mmap cannot be used
- to extend a file. */
- moveto = PAGE_ALIGN (mdp -> breakval + size);
- mapbytes = moveto - mdp -> top;
- foffset = mdp -> top - mdp -> base;
-
- if( mdp -> fd > 0){
- /* FIXME: Test results of lseek() and write() */
- lseek (mdp -> fd, foffset + mapbytes - 1, SEEK_SET);
- write (mdp -> fd, &buf, 1);
+ descriptor if not working with anonymous memory. */
+ if (!(mdp->flags & MMALLOC_ANONYMOUS) && mdp->fd < 0) {
+ THROWF(system_error,0,"mmap file descriptor <0 (%d), without MMALLOC_ANONYMOUS being in the flags",mdp->fd);
+ result = NULL;
+ } else if ((char *) mdp->breakval + size > (char *) mdp->top) {
+ /* The request would move us past the end of the currently
+ mapped memory, so map in enough more memory to satisfy
+ the request. This means we also have to grow the mapped-to
+ file by an appropriate amount, since mmap cannot be used
+ to extend a file. */
+ moveto = PAGE_ALIGN((char *) mdp->breakval + size);
+ mapbytes = (char *) moveto - (char *) mdp->top;
+ foffset = (char *) mdp->top - (char *) mdp->base;
+
+ if (mdp->fd > 0) {
+ /* FIXME: Test results of lseek() */
+ lseek(mdp->fd, foffset + mapbytes - 1, SEEK_SET);
+ test = write(mdp->fd, &buf, 1);
+ if (test == -1)
+ THROWF(system_error, 0, "write to mmap'ed fd failed! error: %s", strerror(errno));
}
-
- /* Let's call mmap. Note that it is possible that mdp->top
- is 0. In this case mmap will choose the address for us */
- mapto = mmap (mdp->top, mapbytes, PROT_READ | PROT_WRITE,
- MAP_PRIVATE_OR_SHARED(mdp) | MAP_IS_ANONYMOUS(mdp) | MAP_FIXED,
- MAP_ANON_OR_FD(mdp), foffset);
-
- if (mapto != (PTR) -1){
-
- if(mdp -> top == 0)
- mdp -> base = mdp -> breakval = mapto;
-
- mdp -> top = PAGE_ALIGN (mdp -> breakval + size);
- result = (PTR) mdp -> breakval;
- mdp -> breakval += size;
+
+ /* Let's call mmap. Note that it is possible that mdp->top
+ is 0. In this case mmap will choose the address for us */
+ mapto = mmap(mdp->top, mapbytes, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE_OR_SHARED(mdp) | MAP_IS_ANONYMOUS(mdp) |
+ MAP_FIXED, MAP_ANON_OR_FD(mdp), foffset);
+
+ if (mapto != (void *) -1/* That's MAP_FAILED */) {
+
+ if (mdp->top == 0)
+ mdp->base = mdp->breakval = mapto;
+
+ mdp->top = PAGE_ALIGN((char *) mdp->breakval + size);
+ result = (void *) mdp->breakval;
+ mdp->breakval = (char *) mdp->breakval + size;
+ } else {
+ THROWF(system_error,0,"mmap returned MAP_FAILED! error: %s",strerror(errno));
}
- }
- else
- {
- result = (PTR) mdp -> breakval;
- mdp -> breakval += size;
- }
+ } else {
+ result = (void *) mdp->breakval;
+ mdp->breakval = (char *) mdp->breakval + size;
+ }
}
return (result);
}
-PTR
-__mmalloc_remap_core (mdp)
- struct mdesc *mdp;
+void *__mmalloc_remap_core(struct mdesc *mdp)
{
- PTR base;
+ void *base;
/* FIXME: Quick hack, needs error checking and other attention. */
- base = mmap (mdp -> base, mdp -> top - mdp -> base,
- PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE_OR_SHARED (mdp) | MAP_FIXED,
- mdp -> fd, 0);
- return ((PTR) base);
+ base = mmap(mdp->base, (char *) mdp->top - (char *) mdp->base,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE_OR_SHARED(mdp) | MAP_FIXED, mdp->fd, 0);
+ return ((void *) base);
}
-PTR
-mmalloc_findbase (size)
- int size;
+void *mmalloc_findbase(int size)
{
int fd;
int flags;
- PTR base = NULL;
+ void *base = NULL;
#ifdef MAP_ANONYMOUS
flags = MAP_PRIVATE | MAP_ANONYMOUS;
#else
flags = MAP_PRIVATE;
#endif
- fd = open ("/dev/zero", O_RDWR);
- if (fd != -1)
- {
- return ((PTR) NULL);
- }
+ fd = open("/dev/zero", O_RDWR);
+ if (fd != -1) {
+ return ((void *) NULL);
+ }
#endif
- base = mmap (0, size, PROT_READ | PROT_WRITE, flags, fd, 0);
- if (base != (PTR) -1)
- {
- munmap (base, (size_t) size);
- }
- if (fd != -1)
- {
- close (fd);
- }
- if (base == 0)
- {
- /* Don't allow mapping at address zero. We use that value
- to signal an error return, and besides, it is useful to
- catch NULL pointers if it is unmapped. Instead start
- at the next page boundary. */
- base = (PTR) getpagesize ();
- }
- else if (base == (PTR) -1)
- {
- base = NULL;
- }
- return ((PTR) base);
+ base = mmap(0, size, PROT_READ | PROT_WRITE, flags, fd, 0);
+ if (base != (void *) -1) {
+ munmap(base, (size_t) size);
+ }
+ if (fd != -1) {
+ close(fd);
+ }
+ if (base == 0) {
+ /* Don't allow mapping at address zero. We use that value
+ to signal an error return, and besides, it is useful to
+ catch NULL pointers if it is unmapped. Instead start
+ at the next page boundary. */
+ base = (void *) (long) getpagesize();
+ } else if (base == (void *) -1) {
+ base = NULL;
+ }
+ return ((void *) base);
}
-
-#else /* defined(HAVE_MMAP) */
-/* Prevent "empty translation unit" warnings from the idiots at X3J11. */
-static char ansi_c_idiots = 69;
-#endif /* defined(HAVE_MMAP) */