mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-31 14:04:12 +00:00
New memory malloc malloc library, based on GNU malloc.
This commit is contained in:
parent
009898fddb
commit
63abb1e790
50
mmalloc/.Sanitize
Normal file
50
mmalloc/.Sanitize
Normal file
@ -0,0 +1,50 @@
|
||||
# Sanitize.in for devo.
|
||||
# $Id$
|
||||
#
|
||||
|
||||
# Each directory to survive it's way into a release will need a file
|
||||
# like this one called "./.Sanitize". All keyword lines must exist,
|
||||
# and must exist in the order specified by this file. Each directory
|
||||
# in the tree will be processed, top down, in the following order.
|
||||
|
||||
# Hash started lines like this one are comments and will be deleted
|
||||
# before anything else is done. Blank lines will also be squashed
|
||||
# out.
|
||||
|
||||
# The lines between the "Do-first:" line and the "Things-to-keep:"
|
||||
# line are executed as a /bin/sh shell script before anything else is
|
||||
# done in this
|
||||
|
||||
Do-first:
|
||||
|
||||
# All files listed between the "Things-to-keep:" line and the
|
||||
# "Files-to-sed:" line will be kept. All other files will be removed.
|
||||
# Directories listed in this section will have their own Sanitize
|
||||
# called. Directories not listed will be removed in their entirety
|
||||
# with rm -rf.
|
||||
|
||||
Things-to-keep:
|
||||
|
||||
ChangeLog
|
||||
Makefile.in
|
||||
README
|
||||
attach.c
|
||||
config
|
||||
configure.in
|
||||
detach.c
|
||||
keys.c
|
||||
mcalloc.c
|
||||
mfree.c
|
||||
mmalloc.c
|
||||
mmalloc.h
|
||||
mmap-sup.c
|
||||
mmcheck.c
|
||||
mmemalign.c
|
||||
mmstats.c
|
||||
mmtrace.awk
|
||||
mmtrace.c
|
||||
mrealloc.c
|
||||
mvalloc.c
|
||||
sbrk-sup.c
|
||||
|
||||
Do-last:
|
5
mmalloc/ChangeLog
Normal file
5
mmalloc/ChangeLog
Normal file
@ -0,0 +1,5 @@
|
||||
Sat Mar 14 17:34:59 1992 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* Initial release, incorporated into gdb.
|
||||
|
||||
|
156
mmalloc/Makefile.in
Normal file
156
mmalloc/Makefile.in
Normal file
@ -0,0 +1,156 @@
|
||||
#
|
||||
# Makefile
|
||||
# Copyright (C) 1992 Cygnus Support
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#
|
||||
|
||||
#
|
||||
# Makefile for mmalloc directory
|
||||
#
|
||||
|
||||
# Directory containing source files. Don't clean up the spacing,
|
||||
# this exact string is matched for by the "configure" script.
|
||||
srcdir = .
|
||||
|
||||
prefix = /usr/local
|
||||
|
||||
bindir = $(prefix)/bin
|
||||
datadir = $(prefix)/lib
|
||||
libdir = $(prefix)/lib
|
||||
mandir = $(datadir)/man
|
||||
man1dir = $(mandir)/man1
|
||||
man2dir = $(mandir)/man2
|
||||
man3dir = $(mandir)/man3
|
||||
man4dir = $(mandir)/man4
|
||||
man5dir = $(mandir)/man5
|
||||
man6dir = $(mandir)/man6
|
||||
man7dir = $(mandir)/man7
|
||||
man8dir = $(mandir)/man8
|
||||
man9dir = $(mandir)/man9
|
||||
infodir = $(datadir)/info
|
||||
includedir = $(prefix)/include
|
||||
docdir = $(datadir)/doc
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
INSTALL = install -c
|
||||
INSTALL_PROGRAM = $(INSTALL)
|
||||
INSTALL_DATA = $(INSTALL)
|
||||
|
||||
AR = ar
|
||||
AR_FLAGS = qv
|
||||
BISON = bison
|
||||
MAKEINFO = makeinfo
|
||||
RANLIB = ranlib
|
||||
RM = rm
|
||||
|
||||
TARGETLIB = libmmalloc.a
|
||||
|
||||
MINUS_G = -g
|
||||
CFLAGS = $(MINUS_G) -I. -I$(srcdir)/../include $(HDEFINES)
|
||||
|
||||
CFILES = mcalloc.c mfree.c mmalloc.c mmcheck.c mmemalign.c mmstats.c \
|
||||
mmtrace.c mrealloc.c mvalloc.c mmap-sup.c attach.c detach.c \
|
||||
keys.c sbrk-sup.c
|
||||
|
||||
HFILES = mmalloc.h
|
||||
|
||||
OFILES = mcalloc.o mfree.o mmalloc.o mmcheck.o mmemalign.o mmstats.o \
|
||||
mmtrace.o mrealloc.o mvalloc.o mmap-sup.o attach.o detach.o \
|
||||
keys.o sbrk-sup.o
|
||||
|
||||
#### Host, target, and site specific Makefile fragments come in here.
|
||||
###
|
||||
|
||||
# Do we want/need any config overrides?
|
||||
#
|
||||
|
||||
STAGESTUFF = $(TARGETLIB) *.o
|
||||
|
||||
all: $(TARGETLIB)
|
||||
|
||||
install: all
|
||||
$(INSTALL_DATA) $(TARGETLIB) $(libdir)/$(TARGETLIB).n
|
||||
$(RANLIB) $(libdir)/$(TARGETLIB).n
|
||||
mv -f $(libdir)/$(TARGETLIB).n $(libdir)/$(TARGETLIB)
|
||||
|
||||
$(TARGETLIB): $(OFILES)
|
||||
$(RM) -rf $@
|
||||
$(AR) $(AR_FLAGS) $@ $(OFILES)
|
||||
$(RANLIB) $@
|
||||
|
||||
$(OFILES) : $(HFILES)
|
||||
|
||||
.always.:
|
||||
# Do nothing.
|
||||
|
||||
.PHONEY: all etags tags ls clean stage1 stage2 .always.
|
||||
|
||||
stage1: force
|
||||
-mkdir stage1
|
||||
-mv -f $(STAGESTUFF) stage1
|
||||
|
||||
stage2: force
|
||||
-mkdir stage2
|
||||
-mv -f $(STAGESTUFF) stage2
|
||||
|
||||
stage3: force
|
||||
-mkdir stage3
|
||||
-mv -f $(STAGESTUFF) stage3
|
||||
|
||||
stage4: force
|
||||
-mkdir stage4
|
||||
-mv -f $(STAGESTUFF) stage4
|
||||
|
||||
against=stage2
|
||||
|
||||
comparison: force
|
||||
for i in *.o ; do cmp $$i $(against)/$$i || exit 1 ; done
|
||||
|
||||
de-stage1: force
|
||||
-(cd stage1 ; mv -f * ..)
|
||||
-rmdir stage1
|
||||
|
||||
de-stage2: force
|
||||
-(cd stage2 ; mv -f * ..)
|
||||
-rmdir stage2
|
||||
|
||||
de-stage3: force
|
||||
-(cd stage3 ; mv -f * ..)
|
||||
-rmdir stage3
|
||||
|
||||
de-stage4: force
|
||||
-(cd stage4 ; mv -f * ..)
|
||||
-rmdir stage4
|
||||
|
||||
etags tags: TAGS
|
||||
|
||||
TAGS: $(CFILES)
|
||||
etags $(HFILES) $(CFILES)
|
||||
|
||||
ls:
|
||||
@echo Makefile $(HFILES) $(CFILES)
|
||||
|
||||
# Need to deal with profiled libraries, too.
|
||||
|
||||
clean:
|
||||
rm -f *.a *.o core errs *~ \#* TAGS *.E a.out errors
|
||||
|
||||
force:
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) \
|
||||
$(target_makefile_frag)
|
||||
$(SHELL) ./config.status
|
160
mmalloc/README
Executable file
160
mmalloc/README
Executable file
@ -0,0 +1,160 @@
|
||||
The GNU mmalloc (mapped-malloc) package. fnf@cygnus.com
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
This is a heavily modified version of GNU malloc which has been extended to
|
||||
use mmap() as the basic mechanism for for obtaining memory from the system,
|
||||
rather than sbrk(). This gives it several advantages over the
|
||||
more traditional malloc:
|
||||
|
||||
* Providing suitable precautions are taken to avoid memory region
|
||||
collisions, sbrk() is now available for use by applications that
|
||||
use this package and still need to use some memory management
|
||||
package that includes functions like malloc/realloc/free.
|
||||
|
||||
* Several different memory pools can be used, each of them growing
|
||||
or shinking under control of mmap(), with the mmalloc functions
|
||||
using a specific pool on a call by call basis.
|
||||
|
||||
* By using mmap, it is easy to create data pools which are intended to
|
||||
be persistent and exist as a filesystem object after the creating
|
||||
process has gone away.
|
||||
|
||||
* Because multiple memory pools can be managed, data used for a
|
||||
specific purpose can be allocated into it's own memory pool, making
|
||||
it easier to allow applications to "dump" and "restore" initialized
|
||||
malloc-managed memory regions. I.E., the "unexec" hack popularized
|
||||
by GNU emacs could potentially go away.
|
||||
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
The mmalloc functions contain no internal static state. All of mmalloc
|
||||
internal data is allocated in the mapped in region, along with the user
|
||||
data that it manages. This allows it to manage multiple such regions
|
||||
and to "pick up where it left off" when such regions are later dynamically
|
||||
mapped back in.
|
||||
|
||||
In some sense, malloc has been "purified" to contain no internal state
|
||||
information and generalized to use multiple memory regions rather than a
|
||||
single region managed by sbrk(). However the new routines now need an
|
||||
extra parameter which informs malloc which memory region it is dealing
|
||||
with (along with other information).
|
||||
|
||||
For ease of initial implementation, and to avoid exporting or importing
|
||||
any more global variables or routines than necessary, this package is
|
||||
implemented with all functions contained within a single source file.
|
||||
At some future point, once everything has stabilized, it may be desirable
|
||||
split it up into separate files.
|
||||
|
||||
The functions initially provided by mmalloc are:
|
||||
|
||||
void *mmalloc_attach (int fd, void *baseaddr);
|
||||
void *mmalloc_detach (void *md);
|
||||
int mmalloc_errno (void *md);
|
||||
int mmalloc_setkey (void *md, int keynum, void *key);
|
||||
void *mmalloc_getkey (void *md, int keynum);
|
||||
|
||||
void *mmalloc (void *md, size_t size);
|
||||
void *mrealloc (void *md, void *ptr, size_t size);
|
||||
void *mvalloc (void *md, size_t size);
|
||||
void mfree (void *md, void *ptr);
|
||||
|
||||
Backwards Compatibility
|
||||
-----------------------
|
||||
|
||||
To allow a single malloc package to be used in a given application, provision
|
||||
is made for the traditional malloc/realloc/free functions to be implemented
|
||||
as special cases of the mmalloc functions. In particular, if any of the
|
||||
functions that expect malloc descriptors are called with a NULL pointer rather
|
||||
than a valid malloc descriptor, then they default to using an mmap'd region
|
||||
starting at the current sbrk() value and mapped to /dev/zero. Applications
|
||||
can simply include the following defines to use the mmalloc versions:
|
||||
|
||||
#define malloc(size) mmalloc ((void *)0, (size))
|
||||
#define realloc(ptr,size) mrealloc ((void *)0, (ptr), (size));
|
||||
#define free(ptr) mfree ((void *)0, (ptr))
|
||||
|
||||
or replace the existing malloc/realloc/free calls with the above patterns
|
||||
if the #define's cause problems.
|
||||
|
||||
Note that this does not prevent calls to malloc/realloc/free within
|
||||
libraries from continuing to use the library version of malloc, so if this
|
||||
is a problem, the compatibility issue needs to be dealt with in another way.
|
||||
|
||||
|
||||
Function Descriptions
|
||||
---------------------
|
||||
|
||||
void *mmalloc_attach (int fd, void *baseaddr);
|
||||
|
||||
Initialize access to a mmalloc managed region.
|
||||
|
||||
If FD is a valid file descriptor for an open file then data for the
|
||||
mmalloc managed region is mapped to that file, otherwise "/dev/zero"
|
||||
is used and the data will not exist in any filesystem object.
|
||||
|
||||
If the open file corresponding to FD is from a previous use of
|
||||
mmalloc and passes some basic sanity checks to ensure that it is
|
||||
compatible with the current mmalloc package, then it's data is
|
||||
mapped in and is immediately accessible at the same addresses in
|
||||
the current process as the process that created the file.
|
||||
|
||||
If BASEADDR is not NULL, the mapping is established starting at the
|
||||
specified address in the process address space. If BASEADDR is NULL,
|
||||
the mmalloc package chooses a suitable address at which to start the
|
||||
mapped region, which will be the value of the previous mapping if
|
||||
opening an existing file which was previously built by mmalloc, or
|
||||
for new files will be a value chosen by mmap.
|
||||
|
||||
Specifying BASEADDR provides more control over where the regions
|
||||
start and how big they can be before bumping into existing mapped
|
||||
regions or future mapped regions.
|
||||
|
||||
On success, returns a "malloc descriptor" which is used in subsequent
|
||||
calls to other mmalloc package functions. It is explicitly "void *"
|
||||
("char *" for systems that don't fully support void) so that users
|
||||
of the package don't have to worry about the actual implementation
|
||||
details.
|
||||
|
||||
On failure returns NULL.
|
||||
|
||||
void *mmalloc_detach (void *md);
|
||||
|
||||
Terminate access to a mmalloc managed region by closing the base
|
||||
file and unmapping all memory pages associated with the region.
|
||||
|
||||
Returns NULL on success.
|
||||
|
||||
Returns the malloc descriptor on failure, which can subsequently
|
||||
be used for further action (such as obtaining more information about
|
||||
the nature of the failure).
|
||||
|
||||
void *mmalloc (void *md, size_t size);
|
||||
|
||||
Given an mmalloc descriptor MD, allocate additional memory of
|
||||
SIZE bytes in the associated mapped region.
|
||||
|
||||
void *mrealloc (void *md, void *ptr, size_t size);
|
||||
|
||||
Given an mmalloc descriptor MD and a pointer to memory previously
|
||||
allocated by mmalloc in PTR, reallocate the memory to be SIZE bytes
|
||||
long, possibly moving the existing contents of memory if necessary.
|
||||
|
||||
void *mvalloc (void *md, size_t size);
|
||||
|
||||
Like mmalloc but the resulting memory is aligned on a page boundary.
|
||||
|
||||
void mfree (void *md, void *ptr);
|
||||
|
||||
Given an mmalloc descriptor MD and a pointer to memory previously
|
||||
allocated by mmalloc in PTR, free the previously allocated memory.
|
||||
|
||||
int mmalloc_errno (void *md);
|
||||
|
||||
Given a mmalloc descriptor, if the last mmalloc operation
|
||||
failed for some reason due to a system call failure, then
|
||||
returns the associated errno. Returns 0 otherwise.
|
33
mmalloc/configure.in
Normal file
33
mmalloc/configure.in
Normal file
@ -0,0 +1,33 @@
|
||||
# This file is a shell script that supplies the information necessary
|
||||
# to tailor a template configure script into the configure script
|
||||
# appropriate for this directory. For more information, check any
|
||||
# existing configure script.
|
||||
|
||||
srctrigger=mmalloc.c
|
||||
srcname="mmalloc library"
|
||||
configdirs=""
|
||||
|
||||
# per-host:
|
||||
|
||||
case "${host_os}" in
|
||||
|
||||
sysv4)
|
||||
host_makefile_frag=config/mh-sysv4
|
||||
;;
|
||||
|
||||
sunos4*)
|
||||
host_makefile_frag=config/mh-sunos4
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# per-target:
|
||||
|
||||
#
|
||||
# Local Variables:
|
||||
# fill-column: 131
|
||||
# End:
|
||||
#
|
71
mmalloc/detach.c
Normal file
71
mmalloc/detach.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* Finish access to a mmap'd malloc managed region.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Fred Fish at Cygnus Support. fnf@cygnus.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "mmalloc.h"
|
||||
|
||||
/* Terminate access to a mmalloc managed region by unmapping all memory pages
|
||||
associated with the region, and closing the file descriptor if it is one
|
||||
that we opened.
|
||||
|
||||
Returns NULL on success.
|
||||
|
||||
Returns the malloc descriptor on failure, which can subsequently be used
|
||||
for further action, such as obtaining more information about the nature of
|
||||
the failure by examining the preserved errno value.
|
||||
|
||||
Note that the malloc descriptor that we are using is currently located in
|
||||
region we are about to unmap, so we first make a local copy of it on the
|
||||
stack and use the copy. */
|
||||
|
||||
PTR
|
||||
mmalloc_detach (md)
|
||||
void *md;
|
||||
{
|
||||
struct mdesc mtemp;
|
||||
|
||||
if (md != NULL)
|
||||
{
|
||||
|
||||
mtemp = *(struct mdesc *) md;
|
||||
|
||||
/* Now unmap all the pages associated with this region by asking for a
|
||||
negative increment equal to the current size of the region. */
|
||||
|
||||
if ((mtemp.morecore (&mtemp, mtemp.base - mtemp.top)) == NULL)
|
||||
{
|
||||
/* Update the original malloc descriptor with any changes */
|
||||
*(struct mdesc *) md = mtemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mtemp.flags & MMALLOC_DEVZERO)
|
||||
{
|
||||
(void) close (mtemp.fd);
|
||||
}
|
||||
md = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (md);
|
||||
}
|
||||
|
||||
|
||||
|
1841
mmalloc/fsf.shar.orig
Executable file
1841
mmalloc/fsf.shar.orig
Executable file
File diff suppressed because it is too large
Load Diff
64
mmalloc/keys.c
Normal file
64
mmalloc/keys.c
Normal file
@ -0,0 +1,64 @@
|
||||
/* Access for application keys in mmap'd malloc managed region.
|
||||
Copyright 1992 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Fred Fish at Cygnus Support. fnf@cygnus.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* This module provides access to some keys that the application can use to
|
||||
provide persistent access to locations in the mapped memory section.
|
||||
The intent is that these keys are to be used sparingly as sort of
|
||||
persistent global variables which the application can use to reinitialize
|
||||
access to data in the mapped region.
|
||||
|
||||
For the moment, these keys are simply stored in the malloc descriptor
|
||||
itself, in an array of fixed length. This should be fixed so that there
|
||||
can be an unlimited number of keys, possibly using a multilevel access
|
||||
scheme of some sort. */
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
int
|
||||
mmalloc_setkey (md, keynum, key)
|
||||
PTR md;
|
||||
int keynum;
|
||||
PTR key;
|
||||
{
|
||||
struct mdesc *mdp = (struct mdesc *) md;
|
||||
int result = 0;
|
||||
|
||||
if ((mdp != NULL) && (keynum >= 0) && (keynum < MMALLOC_KEYS))
|
||||
{
|
||||
mdp -> keys [keynum] = key;
|
||||
result++;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
PTR
|
||||
mmalloc_getkey (md, keynum)
|
||||
PTR md;
|
||||
int keynum;
|
||||
{
|
||||
struct mdesc *mdp = (struct mdesc *) md;
|
||||
PTR keyval = NULL;
|
||||
|
||||
if ((mdp != NULL) && (keynum >= 0) && (keynum < MMALLOC_KEYS))
|
||||
{
|
||||
keyval = mdp -> keys [keynum];
|
||||
}
|
||||
return (keyval);
|
||||
}
|
53
mmalloc/mcalloc.c
Normal file
53
mmalloc/mcalloc.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
/* Allocate an array of NMEMB elements each SIZE bytes long.
|
||||
The entire array is initialized to zeros. */
|
||||
|
||||
PTR
|
||||
mcalloc (md, nmemb, size)
|
||||
PTR md;
|
||||
register size_t nmemb;
|
||||
register size_t size;
|
||||
{
|
||||
register PTR result;
|
||||
|
||||
if ((result = mmalloc (md, nmemb * size)) != NULL)
|
||||
{
|
||||
(void) memset (result, 0, nmemb * size);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* When using this package, provide a version of malloc/realloc/free built
|
||||
on top of it, so that if we use the default sbrk() region we will not
|
||||
collide with another malloc package trying to do the same thing, if
|
||||
the application contains any "hidden" calls to malloc/realloc/free (such
|
||||
as inside a system library).
|
||||
|
||||
NOTE: Defining our own copy of this breaks ANSI conformance. */
|
||||
|
||||
PTR
|
||||
calloc (nmemb, size)
|
||||
size_t nmemb;
|
||||
size_t size;
|
||||
{
|
||||
return (mcalloc ((void *) NULL, nmemb, size));
|
||||
}
|
249
mmalloc/mfree.c
Normal file
249
mmalloc/mfree.c
Normal file
@ -0,0 +1,249 @@
|
||||
/* Free a block of memory allocated by `mmalloc'.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation
|
||||
|
||||
Written May 1989 by Mike Haertel.
|
||||
Heavily modified Mar 1992 by Fred Fish. (fnf@cygnus.com)
|
||||
|
||||
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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA.
|
||||
|
||||
The author may be reached (Email) at the address mike@ai.mit.edu,
|
||||
or (US mail) as Mike Haertel c/o Free Software Foundation. */
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
/* Return memory to the heap.
|
||||
Like `mfree' but don't call a mfree_hook if there is one. */
|
||||
|
||||
void
|
||||
__mmalloc_free (mdp, ptr)
|
||||
struct mdesc *mdp;
|
||||
PTR ptr;
|
||||
{
|
||||
int type;
|
||||
size_t block, blocks;
|
||||
register size_t i;
|
||||
struct list *prev, *next;
|
||||
|
||||
block = BLOCK (ptr);
|
||||
|
||||
type = mdp -> heapinfo[block].busy.type;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
/* Get as many statistics as early as we can. */
|
||||
mdp -> heapstats.chunks_used--;
|
||||
mdp -> heapstats.bytes_used -=
|
||||
mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
|
||||
mdp -> heapstats.bytes_free +=
|
||||
mdp -> heapinfo[block].busy.info.size * BLOCKSIZE;
|
||||
|
||||
/* Find the free cluster previous to this one in the free list.
|
||||
Start searching at the last block referenced; this may benefit
|
||||
programs with locality of allocation. */
|
||||
i = mdp -> heapindex;
|
||||
if (i > block)
|
||||
{
|
||||
while (i > block)
|
||||
{
|
||||
i = mdp -> heapinfo[i].free.prev;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
i = mdp -> heapinfo[i].free.next;
|
||||
}
|
||||
while (i > 0 && i < block);
|
||||
i = mdp -> heapinfo[i].free.prev;
|
||||
}
|
||||
|
||||
/* Determine how to link this block into the free list. */
|
||||
if (block == i + mdp -> heapinfo[i].free.size)
|
||||
{
|
||||
/* Coalesce this block with its predecessor. */
|
||||
mdp -> heapinfo[i].free.size +=
|
||||
mdp -> heapinfo[block].busy.info.size;
|
||||
block = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Really link this block back into the free list. */
|
||||
mdp -> heapinfo[block].free.size =
|
||||
mdp -> heapinfo[block].busy.info.size;
|
||||
mdp -> heapinfo[block].free.next = mdp -> heapinfo[i].free.next;
|
||||
mdp -> heapinfo[block].free.prev = i;
|
||||
mdp -> heapinfo[i].free.next = block;
|
||||
mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
|
||||
mdp -> heapstats.chunks_free++;
|
||||
}
|
||||
|
||||
/* Now that the block is linked in, see if we can coalesce it
|
||||
with its successor (by deleting its successor from the list
|
||||
and adding in its size). */
|
||||
if (block + mdp -> heapinfo[block].free.size ==
|
||||
mdp -> heapinfo[block].free.next)
|
||||
{
|
||||
mdp -> heapinfo[block].free.size
|
||||
+= mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.size;
|
||||
mdp -> heapinfo[block].free.next
|
||||
= mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.next;
|
||||
mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev = block;
|
||||
mdp -> heapstats.chunks_free--;
|
||||
}
|
||||
|
||||
/* Now see if we can return stuff to the system. */
|
||||
blocks = mdp -> heapinfo[block].free.size;
|
||||
if (blocks >= FINAL_FREE_BLOCKS && block + blocks == mdp -> heaplimit
|
||||
&& mdp -> morecore (mdp, 0) == ADDRESS (block + blocks))
|
||||
{
|
||||
register size_t bytes = blocks * BLOCKSIZE;
|
||||
mdp -> heaplimit -= blocks;
|
||||
mdp -> morecore (mdp, -bytes);
|
||||
mdp -> heapinfo[mdp -> heapinfo[block].free.prev].free.next
|
||||
= mdp -> heapinfo[block].free.next;
|
||||
mdp -> heapinfo[mdp -> heapinfo[block].free.next].free.prev
|
||||
= mdp -> heapinfo[block].free.prev;
|
||||
block = mdp -> heapinfo[block].free.prev;
|
||||
mdp -> heapstats.chunks_free--;
|
||||
mdp -> heapstats.bytes_free -= bytes;
|
||||
}
|
||||
|
||||
/* Set the next search to begin at this block. */
|
||||
mdp -> heapindex = block;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Do some of the statistics. */
|
||||
mdp -> heapstats.chunks_used--;
|
||||
mdp -> heapstats.bytes_used -= 1 << type;
|
||||
mdp -> heapstats.chunks_free++;
|
||||
mdp -> heapstats.bytes_free += 1 << type;
|
||||
|
||||
/* Get the address of the first free fragment in this block. */
|
||||
prev = (struct list *)
|
||||
((char *) ADDRESS(block) +
|
||||
(mdp -> heapinfo[block].busy.info.frag.first << type));
|
||||
|
||||
if (mdp -> heapinfo[block].busy.info.frag.nfree ==
|
||||
(BLOCKSIZE >> type) - 1)
|
||||
{
|
||||
/* If all fragments of this block are free, remove them
|
||||
from the fragment list and free the whole block. */
|
||||
next = prev;
|
||||
for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i)
|
||||
{
|
||||
next = next -> next;
|
||||
}
|
||||
prev -> prev -> next = next;
|
||||
if (next != NULL)
|
||||
{
|
||||
next -> prev = prev -> prev;
|
||||
}
|
||||
mdp -> heapinfo[block].busy.type = 0;
|
||||
mdp -> heapinfo[block].busy.info.size = 1;
|
||||
|
||||
/* Keep the statistics accurate. */
|
||||
mdp -> heapstats.chunks_used++;
|
||||
mdp -> heapstats.bytes_used += BLOCKSIZE;
|
||||
mdp -> heapstats.chunks_free -= BLOCKSIZE >> type;
|
||||
mdp -> heapstats.bytes_free -= BLOCKSIZE;
|
||||
|
||||
mfree (mdp, ADDRESS(block));
|
||||
}
|
||||
else if (mdp -> heapinfo[block].busy.info.frag.nfree != 0)
|
||||
{
|
||||
/* If some fragments of this block are free, link this
|
||||
fragment into the fragment list after the first free
|
||||
fragment of this block. */
|
||||
next = (struct list *) ptr;
|
||||
next -> next = prev -> next;
|
||||
next -> prev = prev;
|
||||
prev -> next = next;
|
||||
if (next -> next != NULL)
|
||||
{
|
||||
next -> next -> prev = next;
|
||||
}
|
||||
++mdp -> heapinfo[block].busy.info.frag.nfree;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No fragments of this block are free, so link this
|
||||
fragment into the fragment list and announce that
|
||||
it is the first free fragment of this block. */
|
||||
prev = (struct list *) ptr;
|
||||
mdp -> heapinfo[block].busy.info.frag.nfree = 1;
|
||||
mdp -> heapinfo[block].busy.info.frag.first =
|
||||
RESIDUAL (ptr, BLOCKSIZE) >> type;
|
||||
prev -> next = mdp -> fraghead[type].next;
|
||||
prev -> prev = &mdp -> fraghead[type];
|
||||
prev -> prev -> next = prev;
|
||||
if (prev -> next != NULL)
|
||||
{
|
||||
prev -> next -> prev = prev;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return memory to the heap. */
|
||||
|
||||
void
|
||||
mfree (md, ptr)
|
||||
PTR md;
|
||||
PTR ptr;
|
||||
{
|
||||
struct mdesc *mdp;
|
||||
register struct alignlist *l;
|
||||
|
||||
if (ptr != NULL)
|
||||
{
|
||||
mdp = MD_TO_MDP (md);
|
||||
for (l = mdp -> aligned_blocks; l != NULL; l = l -> next)
|
||||
{
|
||||
if (l -> aligned == ptr)
|
||||
{
|
||||
l -> aligned = NULL; /* Mark the slot in the list as free. */
|
||||
ptr = l -> exact;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mdp -> mfree_hook != NULL)
|
||||
{
|
||||
(*mdp -> mfree_hook) (md, ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
__mmalloc_free (mdp, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* When using this package, provide a version of malloc/realloc/free built
|
||||
on top of it, so that if we use the default sbrk() region we will not
|
||||
collide with another malloc package trying to do the same thing, if
|
||||
the application contains any "hidden" calls to malloc/realloc/free (such
|
||||
as inside a system library).
|
||||
|
||||
NOTE: Defining our own copy of this breaks ANSI conformance. */
|
||||
|
||||
void
|
||||
free (ptr)
|
||||
PTR ptr;
|
||||
{
|
||||
mfree ((void *) NULL, ptr);
|
||||
}
|
64
mmalloc/mmemalign.c
Normal file
64
mmalloc/mmemalign.c
Normal file
@ -0,0 +1,64 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
PTR
|
||||
mmemalign (md, alignment, size)
|
||||
PTR md;
|
||||
size_t alignment;
|
||||
size_t size;
|
||||
{
|
||||
PTR result;
|
||||
unsigned long int adj;
|
||||
struct alignlist *l;
|
||||
struct mdesc *mdp;
|
||||
|
||||
size = ((size + alignment - 1) / alignment) * alignment;
|
||||
|
||||
if ((result = mmalloc (md, size)) != NULL)
|
||||
{
|
||||
adj = RESIDUAL (result, alignment);
|
||||
if (adj != 0)
|
||||
{
|
||||
mdp = MD_TO_MDP (md);
|
||||
for (l = mdp -> aligned_blocks; l != NULL; l = l -> next)
|
||||
{
|
||||
if (l -> aligned == NULL)
|
||||
{
|
||||
/* This slot is free. Use it. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (l == NULL)
|
||||
{
|
||||
l = (struct alignlist *) mmalloc (md, sizeof (struct alignlist));
|
||||
if (l == NULL)
|
||||
{
|
||||
mfree (md, result);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
l -> exact = result;
|
||||
result = l -> aligned = (char *) result + alignment - adj;
|
||||
l -> next = mdp -> aligned_blocks;
|
||||
mdp -> aligned_blocks = l;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
46
mmalloc/mmstats.c
Normal file
46
mmalloc/mmstats.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Access the statistics maintained by `mmalloc'.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation
|
||||
|
||||
Written May 1989 by Mike Haertel.
|
||||
Modified Mar 1992 by Fred Fish. (fnf@cygnus.com)
|
||||
|
||||
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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA.
|
||||
|
||||
The author may be reached (Email) at the address mike@ai.mit.edu,
|
||||
or (US mail) as Mike Haertel c/o Free Software Foundation. */
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
/* FIXME: See the comment in mmalloc.h where struct mstats is defined.
|
||||
None of the internal mmalloc structures should be externally visible
|
||||
outside the library. */
|
||||
|
||||
struct mstats
|
||||
mmstats (md)
|
||||
PTR md;
|
||||
{
|
||||
struct mstats result;
|
||||
struct mdesc *mdp;
|
||||
|
||||
mdp = MD_TO_MDP (md);
|
||||
result.bytes_total =
|
||||
(char *) mdp -> morecore (mdp, 0) - mdp -> heapbase;
|
||||
result.chunks_used = mdp -> heapstats.chunks_used;
|
||||
result.bytes_used = mdp -> heapstats.bytes_used;
|
||||
result.chunks_free = mdp -> heapstats.chunks_free;
|
||||
result.bytes_free = mdp -> heapstats.bytes_free;
|
||||
return (result);
|
||||
}
|
36
mmalloc/mmtrace.awk
Normal file
36
mmalloc/mmtrace.awk
Normal file
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Awk program to analyze mtrace.c output.
|
||||
#
|
||||
$1 == "+" { if (allocated[$2] != "")
|
||||
print "+", $2, "Alloc", NR, "duplicate:", allocated[$2];
|
||||
else
|
||||
allocated[$2] = $3;
|
||||
}
|
||||
$1 == "-" { if (allocated[$2] != "") {
|
||||
allocated[$2] = "";
|
||||
if (allocated[$2] != "")
|
||||
print "DELETE FAILED", $2, allocated[$2];
|
||||
} else
|
||||
print "-", $2, "Free", NR, "was never alloc'd";
|
||||
}
|
||||
$1 == "<" { if (allocated[$2] != "")
|
||||
allocated[$2] = "";
|
||||
else
|
||||
print "-", $2, "Realloc", NR, "was never alloc'd";
|
||||
}
|
||||
$1 == ">" { if (allocated[$2] != "")
|
||||
print "+", $2, "Realloc", NR, "duplicate:", allocated[$2];
|
||||
else
|
||||
allocated[$2] = $3;
|
||||
}
|
||||
|
||||
# Ignore "= Start"
|
||||
$1 == "=" { }
|
||||
# Ignore failed realloc attempts for now
|
||||
$1 == "!" { }
|
||||
|
||||
|
||||
END { for (x in allocated)
|
||||
if (allocated[x] != "")
|
||||
print "+", x, allocated[x];
|
||||
}
|
151
mmalloc/mrealloc.c
Normal file
151
mmalloc/mrealloc.c
Normal file
@ -0,0 +1,151 @@
|
||||
/* Change the size of a block allocated by `mmalloc'.
|
||||
Copyright 1990, 1991 Free Software Foundation
|
||||
Written May 1989 by Mike Haertel.
|
||||
|
||||
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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA.
|
||||
|
||||
The author may be reached (Email) at the address mike@ai.mit.edu,
|
||||
or (US mail) as Mike Haertel c/o Free Software Foundation. */
|
||||
|
||||
#include "mmalloc.h"
|
||||
|
||||
/* Resize the given region to the new size, returning a pointer
|
||||
to the (possibly moved) region. This is optimized for speed;
|
||||
some benchmarks seem to indicate that greater compactness is
|
||||
achieved by unconditionally allocating and copying to a
|
||||
new region. This module has incestuous knowledge of the
|
||||
internals of both mfree and mmalloc. */
|
||||
|
||||
PTR
|
||||
mrealloc (md, ptr, size)
|
||||
PTR md;
|
||||
PTR ptr;
|
||||
size_t size;
|
||||
{
|
||||
struct mdesc *mdp;
|
||||
PTR result;
|
||||
int type;
|
||||
size_t block, blocks, oldlimit;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
mfree (md, ptr);
|
||||
return (mmalloc (md, 0));
|
||||
}
|
||||
else if (ptr == NULL)
|
||||
return (mmalloc (md, size));
|
||||
|
||||
mdp = MD_TO_MDP (md);
|
||||
|
||||
if (mdp -> mrealloc_hook != NULL)
|
||||
{
|
||||
return ((*mdp -> mrealloc_hook) (md, ptr, size));
|
||||
}
|
||||
|
||||
block = BLOCK(ptr);
|
||||
|
||||
type = mdp -> heapinfo[block].busy.type;
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
/* Maybe reallocate a large block to a small fragment. */
|
||||
if (size <= BLOCKSIZE / 2)
|
||||
{
|
||||
result = mmalloc (md, size);
|
||||
if (result != NULL)
|
||||
{
|
||||
memcpy (result, ptr, size);
|
||||
mfree (md, ptr);
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
/* The new size is a large allocation as well;
|
||||
see if we can hold it in place. */
|
||||
blocks = BLOCKIFY(size);
|
||||
if (blocks < mdp -> heapinfo[block].busy.info.size)
|
||||
{
|
||||
/* The new size is smaller; return
|
||||
excess memory to the free list. */
|
||||
mdp -> heapinfo[block + blocks].busy.type = 0;
|
||||
mdp -> heapinfo[block + blocks].busy.info.size
|
||||
= mdp -> heapinfo[block].busy.info.size - blocks;
|
||||
mdp -> heapinfo[block].busy.info.size = blocks;
|
||||
mfree (md, ADDRESS(block + blocks));
|
||||
result = ptr;
|
||||
}
|
||||
else if (blocks == mdp -> heapinfo[block].busy.info.size)
|
||||
/* No size change necessary. */
|
||||
result = ptr;
|
||||
else
|
||||
{
|
||||
/* Won't fit, so allocate a new region that will.
|
||||
Free the old region first in case there is sufficient
|
||||
adjacent free space to grow without moving. */
|
||||
blocks = mdp -> heapinfo[block].busy.info.size;
|
||||
/* Prevent free from actually returning memory to the system. */
|
||||
oldlimit = mdp -> heaplimit;
|
||||
mdp -> heaplimit = 0;
|
||||
mfree (md, ptr);
|
||||
mdp -> heaplimit = oldlimit;
|
||||
result = mmalloc (md, size);
|
||||
if (result == NULL)
|
||||
{
|
||||
(void) mmalloc (md, blocks * BLOCKSIZE);
|
||||
return NULL;
|
||||
}
|
||||
if (ptr != result)
|
||||
memmove (result, ptr, blocks * BLOCKSIZE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Old size is a fragment; type is logarithm
|
||||
to base two of the fragment size. */
|
||||
if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type))
|
||||
/* The new size is the same kind of fragment. */
|
||||
result = ptr;
|
||||
else
|
||||
{
|
||||
/* The new size is different; allocate a new space,
|
||||
and copy the lesser of the new size and the old. */
|
||||
result = mmalloc (md, size);
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
memcpy (result, ptr, MIN(size, (size_t) 1 << type));
|
||||
mfree (md, ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* When using this package, provide a version of malloc/realloc/free built
|
||||
on top of it, so that if we use the default sbrk() region we will not
|
||||
collide with another malloc package trying to do the same thing, if
|
||||
the application contains any "hidden" calls to malloc/realloc/free (such
|
||||
as inside a system library).
|
||||
|
||||
NOTE: Defining our own copy of this breaks ANSI conformance. */
|
||||
|
||||
PTR
|
||||
realloc (ptr, size)
|
||||
PTR ptr;
|
||||
size_t size;
|
||||
{
|
||||
return (mrealloc ((void *) NULL, ptr, size));
|
||||
}
|
39
mmalloc/mvalloc.c
Normal file
39
mmalloc/mvalloc.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* Allocate memory on a page boundary.
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
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., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "mmalloc.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
|
||||
elsewhere, not clutter up this file with lots of kluges to try to figure
|
||||
it out. */
|
||||
|
||||
static size_t pagesize;
|
||||
|
||||
PTR
|
||||
mvalloc (md, size)
|
||||
PTR md;
|
||||
size_t size;
|
||||
{
|
||||
if (pagesize == 0)
|
||||
{
|
||||
pagesize = getpagesize ();
|
||||
}
|
||||
|
||||
return (mmemalign (md, pagesize, size));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user