summaryrefslogtreecommitdiff
path: root/src/ralloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ralloc.c')
-rw-r--r--src/ralloc.c426
1 files changed, 0 insertions, 426 deletions
diff --git a/src/ralloc.c b/src/ralloc.c
deleted file mode 100644
index 1f92b51be88..00000000000
--- a/src/ralloc.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/* Block-relocating memory allocator.
- Copyright (C) 1990 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs 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 1, or (at your option)
-any later version.
-
-GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* NOTES:
-
- Only relocate the blocs neccessary for SIZE in r_alloc_sbrk,
- rather than all of them. This means allowing for a possible
- hole between the first bloc and the end of malloc storage. */
-
-#include "config.h"
-#include "lisp.h" /* Needed for xterm.h */
-#undef NULL
-#include "mem_limits.h"
-#include "xterm.h" /* Needed for BLOCK_INPUT */
-
-#define NIL ((POINTER) 0)
-
-
-/* System call to set the break value. */
-extern POINTER sbrk ();
-
-/* The break value, as seen by malloc (). */
-static POINTER virtual_break_value;
-
-/* The break value, viewed by the relocatable blocs. */
-static POINTER break_value;
-
-/* The REAL (i.e., page aligned) break value of the process. */
-static POINTER page_break_value;
-
-/* Macros for rounding. Note that rounding to any value is possible
- 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 ROUND_TO_PAGE(addr) (addr & (~(PAGE - 1)))
-#define EXCEEDS_ELISP_PTR(ptr) ((unsigned int) (ptr) >> VALBITS)
-
-/* Level of warnings issued. */
-static int warnlevel;
-
-/* Function to call to issue a warning;
- 0 means don't issue them. */
-static void (*warnfunction) ();
-
-static void
-check_memory_limits (address)
- POINTER address;
-{
- SIZE data_size = address - data_space_start;
-
- switch (warnlevel)
- {
- case 0:
- if (data_size > (lim_data / 4) * 3)
- {
- warnlevel++;
- (*warnfunction) ("Warning: past 75% of memory limit");
- }
- break;
-
- case 1:
- if (data_size > (lim_data / 20) * 17)
- {
- warnlevel++;
- (*warnfunction) ("Warning: past 85% of memory limit");
- }
- break;
-
- case 2:
- if (data_size > (lim_data / 20) * 19)
- {
- warnlevel++;
- (*warnfunction) ("Warning: past 95% of memory limit");
- }
- break;
-
- default:
- (*warnfunction) ("Warning: past acceptable memory limits");
- break;
- }
-
- if (EXCEEDS_ELISP_PTR (address))
- (*warnfunction) ("Warning: memory in use exceeds lisp pointer size");
-}
-
-/* Obtain SIZE bytes of space. If enough space is not presently available
- in our process reserve, (i.e., (page_break_value - break_value)),
- this means getting more page-aligned space from the system. */
-
-static void
-obtain (size)
- SIZE size;
-{
- SIZE already_available = page_break_value - break_value;
-
- if (already_available < size)
- {
- SIZE get = ROUNDUP (size);
-
- if (warnfunction)
- check_memory_limits (page_break_value);
-
- if (((int) sbrk (get)) < 0)
- abort ();
-
- page_break_value += get;
- }
-
- break_value += size;
-}
-
-/* Obtain SIZE bytes of space and return a pointer to the new area. */
-
-static POINTER
-get_more_space (size)
- SIZE size;
-{
- POINTER ptr = break_value;
- obtain (size);
- return ptr;
-}
-
-/* Note that SIZE bytes of space have been relinquished by the process.
- If SIZE is more than a page, return the space the system. */
-
-static void
-relinquish (size)
- SIZE size;
-{
- SIZE page_part = ROUND_TO_PAGE (size);
-
- if (page_part)
- {
- if (((int) (sbrk (- page_part))) < 0)
- abort ();
-
- page_break_value -= page_part;
- }
-
- break_value -= size;
- bzero (break_value, (size - page_part));
-}
-
-typedef struct bp
-{
- struct bp *next;
- struct bp *prev;
- POINTER *variable;
- POINTER data;
- SIZE size;
-} *bloc_ptr;
-
-#define NIL_BLOC ((bloc_ptr) 0)
-#define BLOC_PTR_SIZE (sizeof (struct bp))
-
-/* Head and tail of the list of relocatable blocs. */
-static bloc_ptr first_bloc, last_bloc;
-
-/* Declared in dispnew.c, this version dosen't fuck up if regions overlap. */
-extern void safe_bcopy ();
-
-/* Find the bloc reference by the address in PTR. Returns a pointer
- to that block. */
-
-static bloc_ptr
-find_bloc (ptr)
- POINTER *ptr;
-{
- register bloc_ptr p = first_bloc;
-
- while (p != NIL_BLOC)
- {
- if (p->variable == ptr && p->data == *ptr)
- return p;
-
- p = p->next;
- }
-
- return p;
-}
-
-/* Allocate a bloc of SIZE bytes and append it to the chain of blocs.
- Returns a pointer to the new bloc. */
-
-static bloc_ptr
-get_bloc (size)
- SIZE size;
-{
- register bloc_ptr new_bloc = (bloc_ptr) malloc (BLOC_PTR_SIZE);
-
- new_bloc->data = get_more_space (size);
- new_bloc->size = size;
- new_bloc->next = NIL_BLOC;
- new_bloc->variable = NIL;
-
- if (first_bloc)
- {
- new_bloc->prev = last_bloc;
- last_bloc->next = new_bloc;
- last_bloc = new_bloc;
- }
- else
- {
- first_bloc = last_bloc = new_bloc;
- new_bloc->prev = NIL_BLOC;
- }
-
- return new_bloc;
-}
-
-/* Relocate all blocs from BLOC on upward in the list to the zone
- indicated by ADDRESS. Direction of relocation is determined by
- the position of ADDRESS relative to BLOC->data.
-
- Note that ordering of blocs is not affected by this function. */
-
-static void
-relocate_some_blocs (bloc, address)
- bloc_ptr bloc;
- POINTER address;
-{
- register bloc_ptr b;
- POINTER data_zone = bloc->data;
- register SIZE data_zone_size = 0;
- register SIZE offset = bloc->data - address;
- POINTER new_data_zone = data_zone - offset;
-
- for (b = bloc; b != NIL_BLOC; b = b->next)
- {
- data_zone_size += b->size;
- b->data -= offset;
- *b->variable = b->data;
- }
-
- safe_bcopy (data_zone, new_data_zone, data_zone_size);
-}
-
-/* Free BLOC from the chain of blocs, relocating any blocs above it
- and returning BLOC->size bytes to the free area. */
-
-static void
-free_bloc (bloc)
- bloc_ptr bloc;
-{
- if (bloc == first_bloc && bloc == last_bloc)
- {
- first_bloc = last_bloc = NIL_BLOC;
- }
- else if (bloc == last_bloc)
- {
- last_bloc = bloc->prev;
- last_bloc->next = NIL_BLOC;
- }
- else if (bloc == first_bloc)
- {
- first_bloc = bloc->next;
- first_bloc->prev = NIL_BLOC;
- relocate_some_blocs (bloc->next, bloc->data);
- }
- else
- {
- bloc->next->prev = bloc->prev;
- bloc->prev->next = bloc->next;
- relocate_some_blocs (bloc->next, bloc->data);
- }
-
- relinquish (bloc->size);
- free (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 them. */
-
-POINTER
-r_alloc_sbrk (size)
- long size;
-{
- POINTER ptr;
-
- if (! use_relocatable_buffers)
- return sbrk (size);
-
- if (size > 0)
- {
- obtain (size);
- if (first_bloc)
- {
- relocate_some_blocs (first_bloc, first_bloc->data + size);
- bzero (virtual_break_value, size);
- }
- }
- else if (size < 0)
- {
- if (first_bloc)
- relocate_some_blocs (first_bloc, first_bloc->data + size);
- relinquish (- size);
- }
-
- ptr = virtual_break_value;
- virtual_break_value += size;
- return ptr;
-}
-
-/* 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
- which will use the data area. */
-
-POINTER
-r_alloc (ptr, size)
- POINTER *ptr;
- SIZE size;
-{
- register bloc_ptr new_bloc;
-
- BLOCK_INPUT;
- new_bloc = get_bloc (size);
- new_bloc->variable = ptr;
- *ptr = new_bloc->data;
- UNBLOCK_INPUT;
-
- return *ptr;
-}
-
-/* Free a bloc of relocatable storage whose data is pointed to by PTR. */
-
-void
-r_alloc_free (ptr)
- register POINTER *ptr;
-{
- register bloc_ptr dead_bloc;
-
- BLOCK_INPUT;
- dead_bloc = find_bloc (ptr);
- if (dead_bloc == NIL_BLOC)
- abort ();
-
- free_bloc (dead_bloc);
- UNBLOCK_INPUT;
-}
-
-/* Given a pointer at address PTR to relocatable data, resize it
- to SIZE. This is done by obtaining a new block and freeing the
- old, unless SIZE is less than or equal to the current bloc size,
- in which case nothing happens and the current value is returned.
-
- The contents of PTR is changed to reflect the new bloc, and this
- value is returned. */
-
-POINTER
-r_re_alloc (ptr, size)
- POINTER *ptr;
- SIZE size;
-{
- register bloc_ptr old_bloc, new_bloc;
-
- BLOCK_INPUT;
- old_bloc = find_bloc (ptr);
- if (old_bloc == NIL_BLOC)
- abort ();
-
- if (size <= old_bloc->size)
- return *ptr;
-
- new_bloc = get_bloc (size);
- new_bloc->variable = ptr;
- safe_bcopy (old_bloc->data, new_bloc->data, old_bloc->size);
- *ptr = new_bloc->data;
-
- free_bloc (old_bloc);
- UNBLOCK_INPUT;
-
- return *ptr;
-}
-
-/* The hook `malloc' uses for the function which gets more space
- from the system. */
-extern POINTER (*__morecore) ();
-
-/* Intialize various things for memory allocation. */
-
-void
-malloc_init (start, warn_func)
- POINTER start;
- void (*warn_func) ();
-{
- static int malloc_initialized = 0;
-
- if (start)
- data_space_start = start;
-
- if (malloc_initialized)
- return;
-
- malloc_initialized = 1;
- __morecore = r_alloc_sbrk;
- virtual_break_value = break_value = sbrk (0);
- page_break_value = (POINTER) ROUNDUP (break_value);
- bzero (break_value, (page_break_value - break_value));
- use_relocatable_buffers = 1;
-
- lim_data = 0;
- warnlevel = 0;
- warnfunction = warn_func;
-
- get_lim_data ();
-}