File: dynmm_default.cpp

package info (click to toggle)
open-amulet 4.3.1-7.1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 7,804 kB
  • ctags: 9,779
  • sloc: cpp: 97,058; sh: 7,698; ansic: 1,881; makefile: 756; lisp: 153; exp: 15
file content (142 lines) | stat: -rw-r--r-- 3,943 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* ************************************************************************
 *         The Amulet User Interface Development Environment              *
 * ************************************************************************
 * This code was written as part of the Amulet project at                 *
 * Carnegie Mellon University, and has been placed in the public          *
 * domain.  If you are using this code or any part of Amulet,             *
 * please contact amulet@cs.cmu.edu to be put on the mailing list.        *
 * ************************************************************************/


#ifdef DEBUG
	#include <iostream>
#endif


Dyn_Memory_Manager::Dyn_Memory_Manager(unsigned short size, char *aPoolName) :
				data_size(size),
				free_list(static_cast<Dyn_Link*>(0)),
#ifdef DEBUG
				blk_count(1),
#endif
				block_size(1), // the minimum size will at least be one byte
				block_length(1),
				block_position(0)
			{
				// the block size we need to handle allocations of the requested 'size'
				// is at least the 'size' itself and the overhead for the links
				unsigned short min_block_size = size + sizeof (Dyn_Link);

				// multiply the block_size by 2 until we can handle min_block_size requests
				while(block_size < min_block_size)
				{
					block_size <<= 1;
				}

				// allocate the first block
				block = (Dyn_Link*)new char [block_size];
				block->next = (0L);
			}

Dyn_Memory_Manager::~Dyn_Memory_Manager()
			{
#ifdef DEBUG
			        unsigned int count=0;
#endif
				Dyn_Link* next;

				// free the allocated blocks
				Dyn_Link* curr = block;
				while(curr != static_cast<Dyn_Link*>(0))
				{
#ifdef DEBUG
			                ++count;
#endif
					// get the next block
					next = curr->next;

					// delete the actual one; this was a char array
					delete[] curr;

					// ok next
					curr = next;
				}

#ifdef DEBUG
				if (count!=blk_count)
				  std::cout << "DEBUG:Memory leak in <Dyn_Memory_Manager "
					    << std::hex << this
					    << ">, alloc'ed:" << blk_count
					    << ", freed:" << count << std::endl;
#endif

				// for safety
				block 		= static_cast<Dyn_Link*>(0);
				free_list 	= static_cast<Dyn_Link*>(0);
			}

void* Dyn_Memory_Manager::New()
			{
				void *new_ptr;

				// Do we have some blocks available in the free-list
				if(free_list != static_cast<Dyn_Link*>(0))
				{
					// assign it and return
					new_ptr 	= free_list;
					free_list 	= free_list->next;

					// we return here to avoid a jmp
					return(new_ptr);
				}
				else
				{
					// do we have to get new memory?
					if(block_position == block_length)
					{
#ifdef DEBUG
			        ++blk_count;
#endif
						// reset the position
						block_position = 0;

						// we now allocate twice as much to better satisfy later requests
						block_size <<= 1;

						// how many blocks of 'data_size' does this give us?
						block_length = (block_size - sizeof(Dyn_Link)) / data_size;

						// next chunk of memory
						Dyn_Link* new_block = reinterpret_cast<Dyn_Link*>(new char[block_size]);

						// put at the beginning of the list, because we calculate the block position
						// from the beginnig of the list
						new_block->next = block;

						// and safe the pointer
						block = new_block;
					}

					// x86 alloc
					#if (!defined( __alpha) && !defined (_MIPS_SIM_ABI64))
						// get the next free block and return it
						new_ptr = reinterpret_cast<void*>(((unsigned)block) + block_position * data_size + sizeof (Dyn_Link));
					#else
						new_ptr = reinterpret_cast<void*>(((unsigned long)block) + block_position * data_size +	sizeof (Dyn_Link));
					#endif

					// update our counter
					block_position++;
				}

				return(new_ptr);
			}

void Dyn_Memory_Manager::Delete (void *ptr)
			{
				// save the free block in the free list
				Dyn_Link *old_ptr 	= static_cast<Dyn_Link*>(ptr);

				old_ptr->next 		= free_list;
				free_list 			= old_ptr;
			}