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

Annotation of OpenXM_contrib/gmp/stack-alloc.c, Revision 1.1.1.2

1.1       maekawa     1: /* Stack allocation routines.  This is intended for machines without support
                      2:    for the `alloca' function.
                      3:
1.1.1.2 ! maekawa     4: Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
1.1       maekawa     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
1.1.1.2 ! maekawa     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
1.1       maekawa    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
1.1.1.2 ! maekawa    15: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
1.1       maekawa    16: License for more details.
                     17:
1.1.1.2 ! maekawa    18: You should have received a copy of the GNU Lesser General Public License
1.1       maekawa    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 "stack-alloc.h"
                     24:
1.1.1.2 ! maekawa    25: #define __need_size_t
        !            26: #include <stddef.h>
        !            27: #undef __need_size_t
        !            28:
        !            29: /* gmp-impl.h and stack-alloc.h conflict when not USE_STACK_ALLOC, so these
        !            30:    declarations are copied here */
        !            31: #if __STDC__
        !            32: extern void *  (*__gmp_allocate_func) (size_t);
        !            33: extern void    (*__gmp_free_func) (void *, size_t);
        !            34: #else
        !            35: extern void *  (*__gmp_allocate_func) ();
        !            36: extern void    (*__gmp_free_func) ();
        !            37: #endif
        !            38:
1.1       maekawa    39: typedef struct tmp_stack tmp_stack;
                     40:
                     41: static unsigned long max_total_allocation = 0;
                     42: static unsigned long current_total_allocation = 0;
                     43:
                     44: static tmp_stack xxx = {&xxx, &xxx, 0};
                     45: static tmp_stack *current = &xxx;
                     46:
1.1.1.2 ! maekawa    47: /* The rounded size of the header of each allocation block.  */
        !            48: #define HSIZ ((sizeof (tmp_stack) + __TMP_ALIGN - 1) & -__TMP_ALIGN)
        !            49:
1.1       maekawa    50: /* Allocate a block of exactly <size> bytes.  This should only be called
                     51:    through the TMP_ALLOC macro, which takes care of rounding/alignment.  */
                     52: void *
1.1.1.2 ! maekawa    53: #if __STDC__
        !            54: __gmp_tmp_alloc (unsigned long size)
        !            55: #else
        !            56: __gmp_tmp_alloc (size)
1.1       maekawa    57:      unsigned long size;
1.1.1.2 ! maekawa    58: #endif
1.1       maekawa    59: {
1.1.1.2 ! maekawa    60:   void *that;
1.1       maekawa    61:
                     62:   if (size > (char *) current->end - (char *) current->alloc_point)
                     63:     {
                     64:       void *chunk;
                     65:       tmp_stack *header;
                     66:       unsigned long chunk_size;
                     67:       unsigned long now;
                     68:
                     69:       /* Allocate a chunk that makes the total current allocation somewhat
                     70:         larger than the maximum allocation ever.  If size is very large, we
                     71:         allocate that much.  */
                     72:
                     73:       now = current_total_allocation + size;
                     74:       if (now > max_total_allocation)
                     75:        {
                     76:          /* We need more temporary memory than ever before.  Increase
                     77:             for future needs.  */
                     78:          now = now * 3 / 2;
1.1.1.2 ! maekawa    79:          chunk_size = now - current_total_allocation + HSIZ;
1.1       maekawa    80:          current_total_allocation = now;
                     81:          max_total_allocation = current_total_allocation;
                     82:        }
                     83:       else
                     84:        {
1.1.1.2 ! maekawa    85:          chunk_size = max_total_allocation - current_total_allocation + HSIZ;
1.1       maekawa    86:          current_total_allocation = max_total_allocation;
                     87:        }
                     88:
1.1.1.2 ! maekawa    89:       chunk = (*__gmp_allocate_func) (chunk_size);
        !            90:       header = (tmp_stack *) chunk;
1.1       maekawa    91:       header->end = (char *) chunk + chunk_size;
1.1.1.2 ! maekawa    92:       header->alloc_point = (char *) chunk + HSIZ;
1.1       maekawa    93:       header->prev = current;
                     94:       current = header;
                     95:     }
                     96:
1.1.1.2 ! maekawa    97:   that = current->alloc_point;
        !            98:   current->alloc_point = (char *) that + size;
        !            99:   return that;
1.1       maekawa   100: }
                    101:
1.1.1.2 ! maekawa   102: /* Typically called at function entry.  <mark> is assigned so that
        !           103:    __gmp_tmp_free can later be used to reclaim all subsequently allocated
        !           104:    storage.  */
1.1       maekawa   105: void
1.1.1.2 ! maekawa   106: #if __STDC__
        !           107: __gmp_tmp_mark (tmp_marker *mark)
        !           108: #else
        !           109: __gmp_tmp_mark (mark)
1.1       maekawa   110:      tmp_marker *mark;
1.1.1.2 ! maekawa   111: #endif
1.1       maekawa   112: {
                    113:   mark->which_chunk = current;
                    114:   mark->alloc_point = current->alloc_point;
                    115: }
                    116:
1.1.1.2 ! maekawa   117: /* Free everything allocated since <mark> was assigned by __gmp_tmp_mark */
1.1       maekawa   118: void
1.1.1.2 ! maekawa   119: #if __STDC__
        !           120: __gmp_tmp_free (tmp_marker *mark)
        !           121: #else
        !           122: __gmp_tmp_free (mark)
1.1       maekawa   123:      tmp_marker *mark;
1.1.1.2 ! maekawa   124: #endif
1.1       maekawa   125: {
                    126:   while (mark->which_chunk != current)
                    127:     {
                    128:       tmp_stack *tmp;
                    129:
                    130:       tmp = current;
                    131:       current = tmp->prev;
1.1.1.2 ! maekawa   132:       current_total_allocation -= (((char *) (tmp->end) - (char *) tmp) - HSIZ);
        !           133:       (*__gmp_free_func) (tmp, (char *) tmp->end - (char *) tmp);
1.1       maekawa   134:     }
                    135:   current->alloc_point = mark->alloc_point;
                    136: }

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