1 //////////////////////////////////////////////////////////////////////
2 //
3 // Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////
25 //
26 // File : memory.h
27 // Classes : -
28 // Description : This file defines the misc. memory interface routines
29 //
30 ////////////////////////////////////////////////////////////////////////
31 #ifndef MEMORY_H
32 #define MEMORY_H
33
34 #include "common/global.h"
35 #include "common/os.h"
36
37 #include <string.h>
38
39 ///////////////////////////////////////////////////////////////////////
40 // Class : CMemPage
41 // Description : This class coltains memory that's allocated on the fly
42 // Comments :
43 class CMemPage {
44 public:
45 char *memory; // Points to the current free memory
46 char *base; // Points to the base memory
47 int availableSize; // The available number of bytes
48 int totalSize; // The total size of the block
49 CMemPage *next; // Points to the next free memory block
50 CMemPage *prev; // points to the previous valid memory block
51 };
52
53 void memoryInit(CMemPage *&); // Init named memory stack
54 void memoryTini(CMemPage *&); // Destroy the named allocated memory
55 CMemPage *memoryNewPage(int); // Allocate a new memory page
56 void memoryDeletePage(CMemPage *); // Allocate a new memory page
57
58
59
60
61
62 // This macro allocates memory in the named stack
ralloc(int size,CMemPage * & stack)63 inline void *ralloc(int size,CMemPage *&stack) {
64
65 // Align the size with 8 byte boundaries
66 size = (size + 7) & (~7);
67
68 while(stack->availableSize < size) {
69 if (stack->next == NULL) {
70 CMemPage *cPage = memoryNewPage(size);
71 cPage->prev = stack;
72 stack->next = cPage;
73 }
74
75 stack = stack->next;
76 stack->availableSize = stack->totalSize;
77 stack->memory = stack->base;
78 }
79
80
81 void *ptr = stack->memory;
82 stack->memory = stack->memory+size;
83 stack->availableSize -= size;
84 return ptr;
85 }
86
87 // This macro duplicates a string in the stack
rstrdup(const char * string,CMemPage * & stack)88 inline char *rstrdup(const char *string,CMemPage *&stack) {
89 char *dest = (char *) ralloc((int) strlen(string)+1,stack);
90
91 strcpy(dest,string);
92
93 return dest;
94 }
95
96 // This macro places a checkpoint
97 #define memBegin(__page) { \
98 char *savedMem = __page->memory; \
99 int savedAvailable = __page->availableSize; \
100 CMemPage *savedPage = __page;
101
102 // This macro restores the memory to the last checkpoint
103 // It is important that the scope between the matching begin-end
104 // pairs mist not be exitted
105 #define memEnd(__page) \
106 __page = savedPage; \
107 __page->availableSize = savedAvailable; \
108 __page->memory = savedMem; \
109 }
110
111 // This structure can be used to put a checkpoint
112 typedef struct {
113 CMemPage *stack;
114 int availableSize;
115 char *memory;
116 } TMemCheckpoint;
117
118 // Mem save and mem restore does the same thing, but they explicitly store the checkpoint
119 #define memSave(__data,__stack) \
120 __data.memory = __stack->memory; \
121 __data.availableSize = __stack->availableSize; \
122 __data.stack = __stack;
123
124 #define memRestore(__data,__stack) \
125 __stack = __data.stack; \
126 __stack->availableSize = __data.availableSize; \
127 __stack->memory = __data.memory;
128
129
130 #endif
131
132