mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-24 14:30:43 -08:00
(check_memory_limits): Reduce warnlevel when usage drops far enough.
(memory_warnings): New function; just set warning data. Use start_of_data if start is 0. [!emacs]: Don't include config.h or lisp.h; instead, use stddef.h. Define POINTER, SIZE, EXCEEDS_LISP_PTR. [!emacs] (safe_bcopy): Define as macro using memmove. (r_alloc_free): Clear *ptr. (r_alloc_init): Renamed from malloc_init. Take no args. Make it static; declare at top of file. (r_alloc): Call r_alloc_init, if not initialized yet. (r_alloc_initialized): Renamed from malloc_initialized; moved to top. (ROUNDUP): Subtract 1, in case arg is already aligned. (check_memory_limits): EXCEEDS_LISP_PTR renamed from EXCEEDS_ELISP_PTR.
This commit is contained in:
parent
54c908b57c
commit
2c46d29fbd
1 changed files with 77 additions and 32 deletions
109
src/ralloc.c
109
src/ralloc.c
|
|
@ -23,14 +23,39 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
rather than all of them. This means allowing for a possible
|
||||
hole between the first bloc and the end of malloc storage. */
|
||||
|
||||
#ifdef emacs
|
||||
#include "config.h"
|
||||
#include "lisp.h" /* Needed for VALBITS. */
|
||||
|
||||
/* Declared in dispnew.c, this version doesn't screw up if regions
|
||||
overlap. */
|
||||
extern void safe_bcopy ();
|
||||
#endif
|
||||
|
||||
#ifndef emacs
|
||||
#include <stddef.h>
|
||||
typedef size_t SIZE;
|
||||
typedef void *POINTER;
|
||||
#define EXCEEDS_LISP_PTR(x) 0
|
||||
|
||||
#define safe_bcopy(x, y, z) memmove (y, x, z)
|
||||
#endif
|
||||
|
||||
#undef NULL
|
||||
#include "mem_limits.h"
|
||||
#include "getpagesize.h"
|
||||
|
||||
#define NIL ((POINTER) 0)
|
||||
|
||||
/* A flag to indicate whether we have initialized ralloc yet. For
|
||||
Emacs's sake, please do not make this local to malloc_init; on some
|
||||
machines, the dumping procedure makes all static variables
|
||||
read-only. On these machines, the word static is #defined to be
|
||||
the empty string, meaning that r_alloc_initialized becomes an
|
||||
automatic variable, and loses its value each time Emacs is started up. */
|
||||
static int r_alloc_initialized = 0;
|
||||
|
||||
static void r_alloc_init ();
|
||||
|
||||
/* Declarations for working with the malloc, ralloc, and system breaks. */
|
||||
|
||||
|
|
@ -50,7 +75,7 @@ static POINTER page_break_value;
|
|||
by changing the definition of PAGE. */
|
||||
#define PAGE (getpagesize ())
|
||||
#define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0)
|
||||
#define ROUNDUP(size) (((unsigned int) (size) + PAGE) & ~(PAGE - 1))
|
||||
#define ROUNDUP(size) (((unsigned int) (size) + PAGE - 1) & ~(PAGE - 1))
|
||||
#define ROUND_TO_PAGE(addr) (addr & (~(PAGE - 1)))
|
||||
|
||||
/* Managing "almost out of memory" warnings. */
|
||||
|
|
@ -67,11 +92,12 @@ check_memory_limits (address)
|
|||
POINTER address;
|
||||
{
|
||||
SIZE data_size = address - data_space_start;
|
||||
int five_percent = lim_data / 20;
|
||||
|
||||
switch (warnlevel)
|
||||
{
|
||||
case 0:
|
||||
if (data_size > (lim_data / 4) * 3)
|
||||
if (data_size > five_percent * 15)
|
||||
{
|
||||
warnlevel++;
|
||||
(*warn_function) ("Warning: past 75% of memory limit");
|
||||
|
|
@ -79,7 +105,7 @@ check_memory_limits (address)
|
|||
break;
|
||||
|
||||
case 1:
|
||||
if (data_size > (lim_data / 20) * 17)
|
||||
if (data_size > five_percent * 17)
|
||||
{
|
||||
warnlevel++;
|
||||
(*warn_function) ("Warning: past 85% of memory limit");
|
||||
|
|
@ -87,7 +113,7 @@ check_memory_limits (address)
|
|||
break;
|
||||
|
||||
case 2:
|
||||
if (data_size > (lim_data / 20) * 19)
|
||||
if (data_size > five_percent * 19)
|
||||
{
|
||||
warnlevel++;
|
||||
(*warn_function) ("Warning: past 95% of memory limit");
|
||||
|
|
@ -99,8 +125,21 @@ check_memory_limits (address)
|
|||
break;
|
||||
}
|
||||
|
||||
if (EXCEEDS_ELISP_PTR (address))
|
||||
memory_full ();
|
||||
/* If we go down below 70% full, issue another 75% warning
|
||||
when we go up again. */
|
||||
if (data_size < five_percent * 14)
|
||||
warnlevel = 0;
|
||||
/* If we go down below 80% full, issue another 85% warning
|
||||
when we go up again. */
|
||||
else if (warnlevel > 1 && data_size < five_percent * 16)
|
||||
warnlevel = 1;
|
||||
/* If we go down below 90% full, issue another 95% warning
|
||||
when we go up again. */
|
||||
else if (warnlevel > 2 && data_size < five_percent * 18)
|
||||
warnlevel = 2;
|
||||
|
||||
if (EXCEEDS_LISP_PTR (address))
|
||||
memory_full ();
|
||||
}
|
||||
|
||||
/* Functions to get and return memory from the system. */
|
||||
|
|
@ -196,10 +235,6 @@ typedef struct bp
|
|||
/* Head and tail of the list of relocatable blocs. */
|
||||
static bloc_ptr first_bloc, last_bloc;
|
||||
|
||||
/* Declared in dispnew.c, this version doesn't screw up if regions
|
||||
overlap. */
|
||||
extern void safe_bcopy ();
|
||||
|
||||
/* Find the bloc referenced by the address in PTR. Returns a pointer
|
||||
to that block. */
|
||||
|
||||
|
|
@ -323,7 +358,7 @@ free_bloc (bloc)
|
|||
static int use_relocatable_buffers;
|
||||
|
||||
/* Obtain SIZE bytes of storage from the free pool, or the system, as
|
||||
neccessary. If relocatable blocs are in use, this means relocating
|
||||
necessary. If relocatable blocs are in use, this means relocating
|
||||
them. This function gets plugged into the GNU malloc's __morecore
|
||||
hook.
|
||||
|
||||
|
|
@ -380,6 +415,9 @@ r_alloc (ptr, size)
|
|||
{
|
||||
register bloc_ptr new_bloc;
|
||||
|
||||
if (! r_alloc_initialized)
|
||||
r_alloc_init ();
|
||||
|
||||
new_bloc = get_bloc (size);
|
||||
if (new_bloc)
|
||||
{
|
||||
|
|
@ -392,7 +430,8 @@ r_alloc (ptr, size)
|
|||
return *ptr;
|
||||
}
|
||||
|
||||
/* Free a bloc of relocatable storage whose data is pointed to by PTR. */
|
||||
/* Free a bloc 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 (ptr)
|
||||
|
|
@ -405,6 +444,7 @@ r_alloc_free (ptr)
|
|||
abort ();
|
||||
|
||||
free_bloc (dead_bloc);
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
/* Given a pointer at address PTR to relocatable data, resize it to SIZE.
|
||||
|
|
@ -450,42 +490,47 @@ r_re_alloc (ptr, size)
|
|||
from the system. */
|
||||
extern POINTER (*__morecore) ();
|
||||
|
||||
/* A flag to indicate whether we have initialized ralloc yet. For
|
||||
Emacs's sake, please do not make this local to malloc_init; on some
|
||||
machines, the dumping procedure makes all static variables
|
||||
read-only. On these machines, the word static is #defined to be
|
||||
the empty string, meaning that malloc_initialized becomes an
|
||||
automatic variable, and loses its value each time Emacs is started
|
||||
up. */
|
||||
static int malloc_initialized = 0;
|
||||
|
||||
/* Intialize various things for memory allocation. */
|
||||
|
||||
void
|
||||
malloc_init (start, warn_func)
|
||||
POINTER start;
|
||||
void (*warn_func) ();
|
||||
static void
|
||||
r_alloc_init ()
|
||||
{
|
||||
if (start)
|
||||
data_space_start = start;
|
||||
|
||||
if (malloc_initialized)
|
||||
if (r_alloc_initialized)
|
||||
return;
|
||||
|
||||
malloc_initialized = 1;
|
||||
r_alloc_initialized = 1;
|
||||
__morecore = r_alloc_sbrk;
|
||||
|
||||
virtual_break_value = break_value = sbrk (0);
|
||||
if (break_value == (POINTER)NULL)
|
||||
(*warn_func)("Malloc initialization returned 0 from sbrk(0).");
|
||||
abort ();
|
||||
#if 0 /* The following is unreasonable because warn_func may be 0. */
|
||||
(*warn_func)("memory initialization got 0 from sbrk(0).");
|
||||
#endif
|
||||
|
||||
page_break_value = (POINTER) ROUNDUP (break_value);
|
||||
/* Clear the rest of the last page; this memory is in our address space
|
||||
even though it is after the sbrk value. */
|
||||
bzero (break_value, (page_break_value - break_value));
|
||||
use_relocatable_buffers = 1;
|
||||
|
||||
lim_data = 0;
|
||||
warnlevel = 0;
|
||||
warn_function = warn_func;
|
||||
|
||||
get_lim_data ();
|
||||
}
|
||||
|
||||
/* This is the name Emacs expects to call. */
|
||||
|
||||
void
|
||||
memory_warnings (start, warn_func)
|
||||
POINTER start;
|
||||
void (*warn_func) ();
|
||||
{
|
||||
if (start)
|
||||
data_space_start = start;
|
||||
else
|
||||
data_space_start = start_of_data ();
|
||||
|
||||
warn_function = warn_func;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue