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