ode/src/obstack.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*************************************************************************
       
     2  *                                                                       *
       
     3  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
       
     4  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
       
     5  *                                                                       *
       
     6  * This library is free software; you can redistribute it and/or         *
       
     7  * modify it under the terms of EITHER:                                  *
       
     8  *   (1) The GNU Lesser General Public License as published by the Free  *
       
     9  *       Software Foundation; either version 2.1 of the License, or (at  *
       
    10  *       your option) any later version. The text of the GNU Lesser      *
       
    11  *       General Public License is included with this library in the     *
       
    12  *       file LICENSE.TXT.                                               *
       
    13  *   (2) The BSD-style license that is included with this library in     *
       
    14  *       the file LICENSE-BSD.TXT.                                       *
       
    15  *                                                                       *
       
    16  * This library is distributed in the hope that it will be useful,       *
       
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
       
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
       
    19  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
       
    20  *                                                                       *
       
    21  *************************************************************************/
       
    22 
       
    23 #include <ode/common.h>
       
    24 #include <ode/error.h>
       
    25 #include <ode/memory.h>
       
    26 #include "obstack.h"
       
    27 
       
    28 //****************************************************************************
       
    29 // macros and constants
       
    30 
       
    31 #define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \
       
    32   ofs = (size_t) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) );
       
    33 
       
    34 #define MAX_ALLOC_SIZE \
       
    35   ((size_t)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1))
       
    36 
       
    37 //****************************************************************************
       
    38 // dObStack
       
    39 
       
    40 dObStack::dObStack()
       
    41 {
       
    42   first = 0;
       
    43   last = 0;
       
    44   current_arena = 0;
       
    45   current_ofs = 0;
       
    46 }
       
    47 
       
    48 
       
    49 dObStack::~dObStack()
       
    50 {
       
    51   // free all arenas
       
    52   Arena *a,*nexta;
       
    53   a = first;
       
    54   while (a) {
       
    55     nexta = a->next;
       
    56     dFree (a,dOBSTACK_ARENA_SIZE);
       
    57     a = nexta;
       
    58   }
       
    59 }
       
    60 
       
    61 
       
    62 void *dObStack::alloc (int num_bytes)
       
    63 {
       
    64 
       
    65 
       
    66   // allocate or move to a new arena if necessary
       
    67   if (!first) {
       
    68     // allocate the first arena if necessary
       
    69     first = last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE);
       
    70     first->next = 0;
       
    71     first->used = sizeof (Arena);
       
    72     ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used);
       
    73   }
       
    74   else {
       
    75     // we already have one or more arenas, see if a new arena must be used
       
    76     if ((last->used + num_bytes) > dOBSTACK_ARENA_SIZE) {
       
    77       if (!last->next) {
       
    78 	last->next = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE);
       
    79 	last->next->next = 0;
       
    80       }
       
    81       last = last->next;
       
    82       last->used = sizeof (Arena);
       
    83       ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used);
       
    84     }
       
    85   }
       
    86 
       
    87   // allocate an area in the arena
       
    88   char *c = ((char*) last) + last->used;
       
    89   last->used += num_bytes;
       
    90   ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used);
       
    91   return c;
       
    92 }
       
    93 
       
    94 
       
    95 void dObStack::freeAll()
       
    96 {
       
    97   last = first;
       
    98   if (first) {
       
    99     first->used = sizeof(Arena);
       
   100     ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used);
       
   101   }
       
   102 }
       
   103 
       
   104 
       
   105 void *dObStack::rewind()
       
   106 {
       
   107   current_arena = first;
       
   108   current_ofs = sizeof (Arena);
       
   109   if (current_arena) {
       
   110     ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs)
       
   111     return ((char*) current_arena) + current_ofs;
       
   112   }
       
   113   else return 0;
       
   114 }
       
   115 
       
   116 
       
   117 void *dObStack::next (int num_bytes)
       
   118 {
       
   119   // this functions like alloc, except that no new storage is ever allocated
       
   120   if (!current_arena) return 0;
       
   121   current_ofs += num_bytes;
       
   122   ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs);
       
   123   if (current_ofs >= current_arena->used) {
       
   124     current_arena = current_arena->next;
       
   125     if (!current_arena) return 0;
       
   126     current_ofs = sizeof (Arena);
       
   127     ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs);
       
   128   }
       
   129   return ((char*) current_arena) + current_ofs;
       
   130 }