version 1.1, 2000/01/10 15:35:22 |
version 1.1.1.2, 2000/09/09 14:12:16 |
|
|
/* Stack allocation routines. This is intended for machines without support |
/* Stack allocation routines. This is intended for machines without support |
for the `alloca' function. |
for the `alloca' function. |
|
|
Copyright (C) 1996 Free Software Foundation, Inc. |
Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc. |
|
|
This file is part of the GNU MP Library. |
This file is part of the GNU MP Library. |
|
|
The GNU MP Library is free software; you can redistribute it and/or modify |
The GNU MP 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 |
it under the terms of the GNU Lesser General Public License as published by |
the Free Software Foundation; either version 2 of the License, or (at your |
the Free Software Foundation; either version 2.1 of the License, or (at your |
option) any later version. |
option) any later version. |
|
|
The GNU MP Library is distributed in the hope that it will be useful, but |
The GNU MP Library is distributed in the hope that it will be useful, but |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
License for more details. |
License for more details. |
|
|
You should have received a copy of the GNU Library General Public License |
You should have received a copy of the GNU Lesser General Public License |
along with the GNU MP Library; see the file COPYING.LIB. If not, write to |
along with the GNU MP Library; see the file COPYING.LIB. If not, write to |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
MA 02111-1307, USA. */ |
MA 02111-1307, USA. */ |
|
|
#include "stack-alloc.h" |
#include "stack-alloc.h" |
|
|
|
#define __need_size_t |
|
#include <stddef.h> |
|
#undef __need_size_t |
|
|
|
/* gmp-impl.h and stack-alloc.h conflict when not USE_STACK_ALLOC, so these |
|
declarations are copied here */ |
|
#if __STDC__ |
|
extern void * (*__gmp_allocate_func) (size_t); |
|
extern void (*__gmp_free_func) (void *, size_t); |
|
#else |
|
extern void * (*__gmp_allocate_func) (); |
|
extern void (*__gmp_free_func) (); |
|
#endif |
|
|
typedef struct tmp_stack tmp_stack; |
typedef struct tmp_stack tmp_stack; |
|
|
void *malloc (); |
|
static unsigned long max_total_allocation = 0; |
static unsigned long max_total_allocation = 0; |
static unsigned long current_total_allocation = 0; |
static unsigned long current_total_allocation = 0; |
|
|
static tmp_stack xxx = {&xxx, &xxx, 0}; |
static tmp_stack xxx = {&xxx, &xxx, 0}; |
static tmp_stack *current = &xxx; |
static tmp_stack *current = &xxx; |
|
|
|
/* The rounded size of the header of each allocation block. */ |
|
#define HSIZ ((sizeof (tmp_stack) + __TMP_ALIGN - 1) & -__TMP_ALIGN) |
|
|
/* Allocate a block of exactly <size> bytes. This should only be called |
/* Allocate a block of exactly <size> bytes. This should only be called |
through the TMP_ALLOC macro, which takes care of rounding/alignment. */ |
through the TMP_ALLOC macro, which takes care of rounding/alignment. */ |
void * |
void * |
__tmp_alloc (size) |
#if __STDC__ |
|
__gmp_tmp_alloc (unsigned long size) |
|
#else |
|
__gmp_tmp_alloc (size) |
unsigned long size; |
unsigned long size; |
|
#endif |
{ |
{ |
void *this; |
void *that; |
|
|
if (size > (char *) current->end - (char *) current->alloc_point) |
if (size > (char *) current->end - (char *) current->alloc_point) |
{ |
{ |
Line 56 __tmp_alloc (size) |
|
Line 76 __tmp_alloc (size) |
|
/* We need more temporary memory than ever before. Increase |
/* We need more temporary memory than ever before. Increase |
for future needs. */ |
for future needs. */ |
now = now * 3 / 2; |
now = now * 3 / 2; |
chunk_size = now - current_total_allocation + sizeof (tmp_stack); |
chunk_size = now - current_total_allocation + HSIZ; |
current_total_allocation = now; |
current_total_allocation = now; |
max_total_allocation = current_total_allocation; |
max_total_allocation = current_total_allocation; |
} |
} |
else |
else |
{ |
{ |
chunk_size = max_total_allocation - current_total_allocation + sizeof (tmp_stack); |
chunk_size = max_total_allocation - current_total_allocation + HSIZ; |
current_total_allocation = max_total_allocation; |
current_total_allocation = max_total_allocation; |
} |
} |
|
|
chunk = malloc (chunk_size); |
chunk = (*__gmp_allocate_func) (chunk_size); |
header = chunk; |
header = (tmp_stack *) chunk; |
header->end = (char *) chunk + chunk_size; |
header->end = (char *) chunk + chunk_size; |
header->alloc_point = (char *) chunk + sizeof (tmp_stack); |
header->alloc_point = (char *) chunk + HSIZ; |
header->prev = current; |
header->prev = current; |
current = header; |
current = header; |
} |
} |
|
|
this = current->alloc_point; |
that = current->alloc_point; |
current->alloc_point = (char *) this + size; |
current->alloc_point = (char *) that + size; |
return this; |
return that; |
} |
} |
|
|
/* Typically called at function entry. <mark> is assigned so that __tmp_free |
/* Typically called at function entry. <mark> is assigned so that |
can later be used to reclaim all subsecuently allocated storage. */ |
__gmp_tmp_free can later be used to reclaim all subsequently allocated |
|
storage. */ |
void |
void |
__tmp_mark (mark) |
#if __STDC__ |
|
__gmp_tmp_mark (tmp_marker *mark) |
|
#else |
|
__gmp_tmp_mark (mark) |
tmp_marker *mark; |
tmp_marker *mark; |
|
#endif |
{ |
{ |
mark->which_chunk = current; |
mark->which_chunk = current; |
mark->alloc_point = current->alloc_point; |
mark->alloc_point = current->alloc_point; |
} |
} |
|
|
/* Free everything allocated since <mark> was assigned by __tmp_mark */ |
/* Free everything allocated since <mark> was assigned by __gmp_tmp_mark */ |
void |
void |
__tmp_free (mark) |
#if __STDC__ |
|
__gmp_tmp_free (tmp_marker *mark) |
|
#else |
|
__gmp_tmp_free (mark) |
tmp_marker *mark; |
tmp_marker *mark; |
|
#endif |
{ |
{ |
while (mark->which_chunk != current) |
while (mark->which_chunk != current) |
{ |
{ |
Line 100 __tmp_free (mark) |
|
Line 129 __tmp_free (mark) |
|
|
|
tmp = current; |
tmp = current; |
current = tmp->prev; |
current = tmp->prev; |
current_total_allocation -= (((char *) (tmp->end) - (char *) tmp) |
current_total_allocation -= (((char *) (tmp->end) - (char *) tmp) - HSIZ); |
- sizeof (tmp_stack)); |
(*__gmp_free_func) (tmp, (char *) tmp->end - (char *) tmp); |
free (tmp); |
|
} |
} |
current->alloc_point = mark->alloc_point; |
current->alloc_point = mark->alloc_point; |
} |
} |