Added: dSpaceSetSublevel/dSpaceGetSublevel and possibility to collide a space as...
[ode.git] / ode / src / obstack.cpp
blob084039633a1272bff88926772f337018baa46a21
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 *************************************************************************/
23 #include <ode/common.h>
24 #include <ode/error.h>
25 #include <ode/memory.h>
26 #include "obstack.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 //****************************************************************************
38 // dObStack
40 dObStack::dObStack()
42 first = 0;
43 last = 0;
44 current_arena = 0;
45 current_ofs = 0;
49 dObStack::~dObStack()
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;
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
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);
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;
81 last = last->next;
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);
91 return c;
95 void dObStack::freeAll()
97 last = first;
98 if (first) {
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);
109 if (current_arena) {
110 ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs)
111 return ((char*) current_arena) + current_ofs;
113 else return 0;
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;