1 /*************************************************************************
3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org Web: www.q12.org *
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 *
13 * (2) The BSD-style license that is included with this library in *
14 * the file LICENSE-BSD.TXT. *
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. *
21 *************************************************************************/
23 #include <ode/common.h>
24 #include <ode/error.h>
25 #include <ode/memory.h>
28 //****************************************************************************
29 // macros and constants
31 #define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \
32 ofs = (size_t) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) );
34 #define MAX_ALLOC_SIZE \
35 ((size_t)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1))
37 //****************************************************************************
56 dFree (a
,dOBSTACK_ARENA_SIZE
);
62 void *dObStack::alloc (int num_bytes
)
64 if ((size_t)num_bytes
> MAX_ALLOC_SIZE
) dDebug (0,"num_bytes too large");
66 // allocate or move to a new arena if necessary
68 // allocate the first arena if necessary
69 first
= last
= (Arena
*) dAlloc (dOBSTACK_ARENA_SIZE
);
71 first
->used
= sizeof (Arena
);
72 ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first
,first
->used
);
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
) {
78 last
->next
= (Arena
*) dAlloc (dOBSTACK_ARENA_SIZE
);
82 last
->used
= sizeof (Arena
);
83 ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last
,last
->used
);
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
);
95 void dObStack::freeAll()
99 first
->used
= sizeof(Arena
);
100 ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first
,first
->used
);
105 void *dObStack::rewind()
107 current_arena
= first
;
108 current_ofs
= sizeof (Arena
);
110 ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena
,current_ofs
)
111 return ((char*) current_arena
) + current_ofs
;
117 void *dObStack::next (int num_bytes
)
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
);
129 return ((char*) current_arena
) + current_ofs
;