aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/ode/src/obstack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/ode/src/obstack.cpp')
-rw-r--r--libraries/ode-0.9/ode/src/obstack.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/libraries/ode-0.9/ode/src/obstack.cpp b/libraries/ode-0.9/ode/src/obstack.cpp
new file mode 100644
index 0000000..0840396
--- /dev/null
+++ b/libraries/ode-0.9/ode/src/obstack.cpp
@@ -0,0 +1,130 @@
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
40dObStack::dObStack()
41{
42 first = 0;
43 last = 0;
44 current_arena = 0;
45 current_ofs = 0;
46}
47
48
49dObStack::~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
62void *dObStack::alloc (int num_bytes)
63{
64 if ((size_t)num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large");
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
95void 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
105void *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
117void *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}