mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Remove everything having to do with the use of mmap.
This commit is contained in:
parent
39c75ccb52
commit
02bb17d31c
1 changed files with 0 additions and 430 deletions
430
src/ralloc.c
430
src/ralloc.c
|
|
@ -926,7 +926,6 @@ r_alloc_sbrk (size)
|
|||
return address;
|
||||
}
|
||||
|
||||
#ifndef REL_ALLOC_MMAP
|
||||
|
||||
/* Allocate a relocatable bloc of storage of size SIZE. A pointer to
|
||||
the data is returned in *PTR. PTR is thus the address of some variable
|
||||
|
|
@ -1217,420 +1216,6 @@ r_alloc_check ()
|
|||
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* not REL_ALLOC_MMAP */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Implementation based on mmap
|
||||
***********************************************************************/
|
||||
|
||||
#ifdef REL_ALLOC_MMAP
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifndef MAP_ANON
|
||||
#ifdef MAP_ANONYMOUS
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#else
|
||||
#define MAP_ANON 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if MAP_ANON == 0
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Memory is allocated in regions which are mapped using mmap(2).
|
||||
The current implementation lets the system select mapped
|
||||
addresses; we're not using MAP_FIXED in general, except when
|
||||
trying to enlarge regions.
|
||||
|
||||
Each mapped region starts with a mmap_region structure, the user
|
||||
area starts after that structure, aligned to MEM_ALIGN.
|
||||
|
||||
+-----------------------+
|
||||
| struct mmap_info + |
|
||||
| padding |
|
||||
+-----------------------+
|
||||
| user data |
|
||||
| |
|
||||
| |
|
||||
+-----------------------+ */
|
||||
|
||||
struct mmap_region
|
||||
{
|
||||
/* User-specified size. */
|
||||
size_t nbytes_specified;
|
||||
|
||||
/* Number of bytes mapped */
|
||||
size_t nbytes_mapped;
|
||||
|
||||
/* Pointer to the location holding the address of the memory
|
||||
allocated with the mmap'd block. The variable actually points
|
||||
after this structure. */
|
||||
POINTER_TYPE **var;
|
||||
|
||||
/* Next and previous in list of all mmap'd regions. */
|
||||
struct mmap_region *next, *prev;
|
||||
};
|
||||
|
||||
/* Doubly-linked list of mmap'd regions. */
|
||||
|
||||
static struct mmap_region *mmap_regions;
|
||||
|
||||
/* File descriptor for mmap. If we don't have anonymous mapping,
|
||||
/dev/zero will be opened on it. */
|
||||
|
||||
static int mmap_fd;
|
||||
|
||||
/* Temporary storage for mmap_set_vars, see there. */
|
||||
|
||||
static struct mmap_region *mmap_regions_1;
|
||||
static int mmap_fd_1;
|
||||
|
||||
/* Value is X rounded up to the next multiple of N. */
|
||||
|
||||
#define ROUND(X, N) (((X) + (N) - 1) / (N) * (N))
|
||||
|
||||
/* Size of mmap_region structure plus padding. */
|
||||
|
||||
#define MMAP_REGION_STRUCT_SIZE \
|
||||
ROUND (sizeof (struct mmap_region), MEM_ALIGN)
|
||||
|
||||
/* Given a pointer P to the start of the user-visible part of a mapped
|
||||
region, return a pointer to the start of the region. */
|
||||
|
||||
#define MMAP_REGION(P) \
|
||||
((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
|
||||
|
||||
/* Given a pointer P to the start of a mapped region, return a pointer
|
||||
to the start of the user-visible part of the region. */
|
||||
|
||||
#define MMAP_USER_AREA(P) \
|
||||
((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
|
||||
|
||||
/* Function prototypes. */
|
||||
|
||||
static int mmap_free P_ ((struct mmap_region *));
|
||||
static int mmap_enlarge P_ ((struct mmap_region *, int));
|
||||
static struct mmap_region *mmap_find P_ ((POINTER_TYPE *, POINTER_TYPE *));
|
||||
POINTER_TYPE *r_alloc P_ ((POINTER_TYPE **, size_t));
|
||||
POINTER_TYPE *r_re_alloc P_ ((POINTER_TYPE **, size_t));
|
||||
void r_alloc_free P_ ((POINTER_TYPE **ptr));
|
||||
|
||||
|
||||
/* Return a region overlapping address range START...END, or null if
|
||||
none. END is not including, i.e. the last byte in the range
|
||||
is at END - 1. */
|
||||
|
||||
static struct mmap_region *
|
||||
mmap_find (start, end)
|
||||
POINTER_TYPE *start, *end;
|
||||
{
|
||||
struct mmap_region *r;
|
||||
char *s = (char *) start, *e = (char *) end;
|
||||
|
||||
for (r = mmap_regions; r; r = r->next)
|
||||
{
|
||||
char *rstart = (char *) r;
|
||||
char *rend = rstart + r->nbytes_mapped;
|
||||
|
||||
if (/* First byte of range, i.e. START, in this region? */
|
||||
(s >= rstart && s < rend)
|
||||
/* Last byte of range, i.e. END - 1, in this region? */
|
||||
|| (e > rstart && e <= rend)
|
||||
/* First byte of this region in the range? */
|
||||
|| (rstart >= s && rstart < e)
|
||||
/* Last byte of this region in the range? */
|
||||
|| (rend > s && rend <= e))
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Unmap a region. P is a pointer to the start of the user-araa of
|
||||
the region. Value is non-zero if successful. */
|
||||
|
||||
static int
|
||||
mmap_free (r)
|
||||
struct mmap_region *r;
|
||||
{
|
||||
if (r->next)
|
||||
r->next->prev = r->prev;
|
||||
if (r->prev)
|
||||
r->prev->next = r->next;
|
||||
else
|
||||
mmap_regions = r->next;
|
||||
|
||||
if (munmap (r, r->nbytes_mapped) == -1)
|
||||
{
|
||||
fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Enlarge region R by NPAGES pages. NPAGES < 0 means shrink R.
|
||||
Value is non-zero if successful. */
|
||||
|
||||
static int
|
||||
mmap_enlarge (r, npages)
|
||||
struct mmap_region *r;
|
||||
int npages;
|
||||
{
|
||||
char *region_end = (char *) r + r->nbytes_mapped;
|
||||
size_t nbytes;
|
||||
int success = 0;
|
||||
|
||||
if (npages < 0)
|
||||
{
|
||||
/* Unmap pages at the end of the region. */
|
||||
nbytes = - npages * page_size;
|
||||
if (munmap (region_end - nbytes, nbytes) == -1)
|
||||
fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
|
||||
else
|
||||
{
|
||||
r->nbytes_mapped -= nbytes;
|
||||
success = 1;
|
||||
}
|
||||
}
|
||||
else if (npages > 0)
|
||||
{
|
||||
struct mmap_region *r2;
|
||||
|
||||
nbytes = npages * page_size;
|
||||
|
||||
/* Try to map additional pages at the end of the region. We
|
||||
cannot do this if the address range is already occupied by
|
||||
something else because mmap deletes any previous mapping.
|
||||
I'm not sure this is worth doing, let's see. */
|
||||
r2 = mmap_find (region_end, region_end + nbytes);
|
||||
if (r2 == NULL)
|
||||
{
|
||||
POINTER_TYPE *p;
|
||||
|
||||
p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
|
||||
if (p == MAP_FAILED)
|
||||
fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
|
||||
else if (p != (POINTER_TYPE *) region_end)
|
||||
{
|
||||
/* Kernels are free to choose a different address. In
|
||||
that case, unmap what we've mapped above; we have
|
||||
no use for it. */
|
||||
if (munmap (p, nbytes) == -1)
|
||||
fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
r->nbytes_mapped += nbytes;
|
||||
success = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/* Set or reset variables holding references to mapped regions. If
|
||||
RESTORE_P is zero, set all variables to null. If RESTORE_P is
|
||||
non-zero, set all variables to the start of the user-areas
|
||||
of mapped regions.
|
||||
|
||||
This function is called from Fdump_emacs to ensure that the dumped
|
||||
Emacs doesn't contain references to memory that won't be mapped
|
||||
when Emacs starts. */
|
||||
|
||||
void
|
||||
mmap_set_vars (restore_p)
|
||||
int restore_p;
|
||||
{
|
||||
struct mmap_region *r;
|
||||
|
||||
if (restore_p)
|
||||
{
|
||||
mmap_regions = mmap_regions_1;
|
||||
mmap_fd = mmap_fd_1;
|
||||
for (r = mmap_regions; r; r = r->next)
|
||||
*r->var = MMAP_USER_AREA (r);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (r = mmap_regions; r; r = r->next)
|
||||
*r->var = NULL;
|
||||
mmap_regions_1 = mmap_regions;
|
||||
mmap_regions = NULL;
|
||||
mmap_fd_1 = mmap_fd;
|
||||
mmap_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Return total number of bytes mapped. */
|
||||
|
||||
size_t
|
||||
mmap_mapped_bytes ()
|
||||
{
|
||||
struct mmap_region *r;
|
||||
size_t n = 0;
|
||||
|
||||
for (r = mmap_regions; r; r = r->next)
|
||||
n += r->nbytes_mapped;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a block of storage large enough to hold NBYTES bytes of
|
||||
data. A pointer to the data is returned in *VAR. VAR is thus the
|
||||
address of some variable which will use the data area.
|
||||
|
||||
The allocation of 0 bytes is valid.
|
||||
|
||||
If we can't allocate the necessary memory, set *VAR to null, and
|
||||
return null. */
|
||||
|
||||
POINTER_TYPE *
|
||||
r_alloc (var, nbytes)
|
||||
POINTER_TYPE **var;
|
||||
size_t nbytes;
|
||||
{
|
||||
void *p;
|
||||
size_t map;
|
||||
|
||||
r_alloc_init ();
|
||||
|
||||
map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, page_size);
|
||||
p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
|
||||
mmap_fd, 0);
|
||||
|
||||
if (p == MAP_FAILED)
|
||||
{
|
||||
if (errno != ENOMEM)
|
||||
fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
|
||||
p = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct mmap_region *r = (struct mmap_region *) p;
|
||||
|
||||
r->nbytes_specified = nbytes;
|
||||
r->nbytes_mapped = map;
|
||||
r->var = var;
|
||||
r->prev = NULL;
|
||||
r->next = mmap_regions;
|
||||
if (r->next)
|
||||
r->next->prev = r;
|
||||
mmap_regions = r;
|
||||
|
||||
p = MMAP_USER_AREA (p);
|
||||
}
|
||||
|
||||
return *var = p;
|
||||
}
|
||||
|
||||
|
||||
/* Given a pointer at address VAR to data allocated with r_alloc,
|
||||
resize it to size NBYTES. Change *VAR to reflect the new block,
|
||||
and return this value. If more memory cannot be allocated, then
|
||||
leave *VAR unchanged, and return null. */
|
||||
|
||||
POINTER_TYPE *
|
||||
r_re_alloc (var, nbytes)
|
||||
POINTER_TYPE **var;
|
||||
size_t nbytes;
|
||||
{
|
||||
POINTER_TYPE *result;
|
||||
|
||||
r_alloc_init ();
|
||||
|
||||
if (*var == NULL)
|
||||
result = r_alloc (var, nbytes);
|
||||
else if (nbytes == 0)
|
||||
{
|
||||
r_alloc_free (var);
|
||||
result = r_alloc (var, nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct mmap_region *r = MMAP_REGION (*var);
|
||||
size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
|
||||
|
||||
if (room < nbytes)
|
||||
{
|
||||
/* Must enlarge. */
|
||||
POINTER_TYPE *old_ptr = *var;
|
||||
|
||||
/* Try to map additional pages at the end of the region.
|
||||
If that fails, allocate a new region, copy data
|
||||
from the old region, then free it. */
|
||||
if (mmap_enlarge (r, ROUND (nbytes - room, page_size) / page_size))
|
||||
{
|
||||
r->nbytes_specified = nbytes;
|
||||
*var = result = old_ptr;
|
||||
}
|
||||
else if (r_alloc (var, nbytes))
|
||||
{
|
||||
bcopy (old_ptr, *var, r->nbytes_specified);
|
||||
mmap_free (MMAP_REGION (old_ptr));
|
||||
result = *var;
|
||||
r = MMAP_REGION (result);
|
||||
r->nbytes_specified = nbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
*var = old_ptr;
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
else if (room - nbytes >= page_size)
|
||||
{
|
||||
/* Shrinking by at least a page. Let's give some
|
||||
memory back to the system. */
|
||||
mmap_enlarge (r, - (room - nbytes) / page_size);
|
||||
result = *var;
|
||||
r->nbytes_specified = nbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Leave it alone. */
|
||||
result = *var;
|
||||
r->nbytes_specified = nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Free a block of relocatable storage whose data is pointed to by
|
||||
PTR. Store 0 in *PTR to show there's no block allocated. */
|
||||
|
||||
void
|
||||
r_alloc_free (var)
|
||||
POINTER_TYPE **var;
|
||||
{
|
||||
r_alloc_init ();
|
||||
|
||||
if (*var)
|
||||
{
|
||||
mmap_free (MMAP_REGION (*var));
|
||||
*var = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* REL_ALLOC_MMAP */
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
@ -1650,24 +1235,9 @@ extern POINTER (*__morecore) ();
|
|||
static void
|
||||
r_alloc_init ()
|
||||
{
|
||||
#if defined REL_ALLOC_MMAP && MAP_ANON == 0
|
||||
/* The value of mmap_fd is initially 0 in temacs, and -1
|
||||
in a dumped Emacs. */
|
||||
if (mmap_fd <= 0)
|
||||
{
|
||||
/* No anonymous mmap -- we need the file descriptor. */
|
||||
mmap_fd = open ("/dev/zero", O_RDONLY);
|
||||
if (mmap_fd == -1)
|
||||
fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
|
||||
}
|
||||
#endif /* REL_ALLOC_MMAP && MAP_ANON == 0 */
|
||||
|
||||
if (r_alloc_initialized)
|
||||
return;
|
||||
r_alloc_initialized = 1;
|
||||
#if defined REL_ALLOC_MMAP && MAP_ANON != 0
|
||||
mmap_fd = -1;
|
||||
#endif
|
||||
|
||||
page_size = PAGE;
|
||||
#ifndef SYSTEM_MALLOC
|
||||
|
|
|
|||
Loading…
Reference in a new issue