[BACK]Return to tal-notreent.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp

Annotation of OpenXM_contrib/gmp/tal-notreent.c, Revision 1.1.1.1

1.1       ohara       1: /* Stack allocation routines.  This is intended for machines without support
                      2:    for the `alloca' function.
                      3:
                      4: Copyright 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
                      5:
                      6: This file is part of the GNU MP Library.
                      7:
                      8: The GNU MP Library is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU Lesser General Public License as published by
                     10: the Free Software Foundation; either version 2.1 of the License, or (at your
                     11: option) any later version.
                     12:
                     13: The GNU MP Library is distributed in the hope that it will be useful, but
                     14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     16: License for more details.
                     17:
                     18: You should have received a copy of the GNU Lesser General Public License
                     19: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
                     20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     21: MA 02111-1307, USA. */
                     22:
                     23: #include "gmp.h"
                     24: #include "gmp-impl.h"
                     25:
                     26:
                     27: struct tmp_stack
                     28: {
                     29:   void *end;
                     30:   void *alloc_point;
                     31:   struct tmp_stack *prev;
                     32: };
                     33: typedef struct tmp_stack tmp_stack;
                     34:
                     35:
                     36: static unsigned long max_total_allocation = 0;
                     37: static unsigned long current_total_allocation = 0;
                     38:
                     39: static tmp_stack xxx = {&xxx, &xxx, 0};
                     40: static tmp_stack *current = &xxx;
                     41:
                     42: /* The rounded size of the header of each allocation block.  */
                     43: #define HSIZ   ROUND_UP_MULTIPLE (sizeof (tmp_stack), __TMP_ALIGN)
                     44:
                     45:
                     46: /* Allocate a block of exactly <size> bytes.  This should only be called
                     47:    through the TMP_ALLOC macro, which takes care of rounding/alignment.  */
                     48: void *
                     49: __gmp_tmp_alloc (unsigned long size)
                     50: {
                     51:   void *that;
                     52:
                     53:   ASSERT ((size % __TMP_ALIGN) == 0);
                     54:   ASSERT (((unsigned) current->alloc_point % __TMP_ALIGN) == 0);
                     55:
                     56:   if (size > (char *) current->end - (char *) current->alloc_point)
                     57:     {
                     58:       void *chunk;
                     59:       tmp_stack *header;
                     60:       unsigned long chunk_size;
                     61:       unsigned long now;
                     62:
                     63:       /* Allocate a chunk that makes the total current allocation somewhat
                     64:         larger than the maximum allocation ever.  If size is very large, we
                     65:         allocate that much.  */
                     66:
                     67:       now = current_total_allocation + size;
                     68:       if (now > max_total_allocation)
                     69:        {
                     70:          /* We need more temporary memory than ever before.  Increase
                     71:             for future needs.  */
                     72:          now = (now * 3 / 2 + __TMP_ALIGN - 1) & -__TMP_ALIGN;
                     73:          chunk_size = now - current_total_allocation + HSIZ;
                     74:          current_total_allocation = now;
                     75:          max_total_allocation = current_total_allocation;
                     76:        }
                     77:       else
                     78:        {
                     79:          chunk_size = max_total_allocation - current_total_allocation + HSIZ;
                     80:          current_total_allocation = max_total_allocation;
                     81:        }
                     82:
                     83:       chunk = (*__gmp_allocate_func) (chunk_size);
                     84:       header = (tmp_stack *) chunk;
                     85:       header->end = (char *) chunk + chunk_size;
                     86:       header->alloc_point = (char *) chunk + HSIZ;
                     87:       header->prev = current;
                     88:       current = header;
                     89:     }
                     90:
                     91:   that = current->alloc_point;
                     92:   current->alloc_point = (char *) that + size;
                     93:   ASSERT (((unsigned) that % __TMP_ALIGN) == 0);
                     94:   return that;
                     95: }
                     96:
                     97: /* Typically called at function entry.  <mark> is assigned so that
                     98:    __gmp_tmp_free can later be used to reclaim all subsequently allocated
                     99:    storage.  */
                    100: void
                    101: __gmp_tmp_mark (tmp_marker *mark)
                    102: {
                    103:   mark->which_chunk = current;
                    104:   mark->alloc_point = current->alloc_point;
                    105: }
                    106:
                    107: /* Free everything allocated since <mark> was assigned by __gmp_tmp_mark */
                    108: void
                    109: __gmp_tmp_free (tmp_marker *mark)
                    110: {
                    111:   while (mark->which_chunk != current)
                    112:     {
                    113:       tmp_stack *tmp;
                    114:
                    115:       tmp = current;
                    116:       current = tmp->prev;
                    117:       current_total_allocation -= (((char *) (tmp->end) - (char *) tmp) - HSIZ);
                    118:       (*__gmp_free_func) (tmp, (char *) tmp->end - (char *) tmp);
                    119:     }
                    120:   current->alloc_point = mark->alloc_point;
                    121: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>