blitz
Version 0.9
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
blitz
memblock.h
Go to the documentation of this file.
1
// -*- C++ -*-
2
/***************************************************************************
3
* blitz/memblock.h MemoryBlock<T> and MemoryBlockReference<T>
4
*
5
* $Id: memblock.h,v 1.18 2005/10/11 21:54:57 julianc Exp $
6
*
7
* Copyright (C) 1997-1999 Todd Veldhuizen <tveldhui@oonumerics.org>
8
*
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License
11
* as published by the Free Software Foundation; either version 2
12
* of the License, or (at your option) any later version.
13
*
14
* This program 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
17
* GNU General Public License for more details.
18
*
19
* Suggestions: blitz-dev@oonumerics.org
20
* Bugs: blitz-bugs@oonumerics.org
21
*
22
* For more information, please see the Blitz++ Home Page:
23
* http://oonumerics.org/blitz/
24
*
25
***************************************************************************/
26
27
#ifndef BZ_MEMBLOCK_H
28
#define BZ_MEMBLOCK_H
29
30
#include <
blitz/blitz.h
>
31
32
#include <stddef.h>
// ptrdiff_t
33
34
#ifdef BZ_THREADSAFE
35
#include <pthread.h>
36
#endif
37
38
BZ_NAMESPACE
(blitz)
39
40
enum
preexistingMemoryPolicy
{
41
duplicateData
,
42
deleteDataWhenDone
,
43
neverDeleteData
44
};
45
46
// Forward declaration of MemoryBlockReference
47
template
<
typename
T_type>
class
MemoryBlockReference
;
48
49
// Class MemoryBlock provides a reference-counted block of memory. This block
50
// may be referred to by multiple vector, matrix and array objects. The memory
51
// is automatically deallocated when the last referring object is destructed.
52
// MemoryBlock may be subclassed to provide special allocators.
53
template
<
typename
P_type>
54
class
MemoryBlock
{
55
56
friend
class
MemoryBlockReference
<P_type>;
57
58
public
:
59
typedef
P_type
T_type
;
60
61
protected
:
62
MemoryBlock
()
63
{
64
length_
= 0;
65
data_
= 0;
66
dataBlockAddress_
= 0;
67
references_
= 0;
68
69
BZ_MUTEX_INIT
(mutex)
70
}
71
72
explicit
MemoryBlock
(
size_t
items)
73
{
74
length_
= items;
75
allocate
(
length_
);
76
77
#ifdef BZ_DEBUG_LOG_ALLOCATIONS
78
cout <<
"MemoryBlock: allocated "
<< setw(8) <<
length_
79
<<
" at "
<< ((
void
*)
dataBlockAddress_
) << endl;
80
#endif
81
82
BZASSERT(dataBlockAddress_ != 0);
83
84
references_
= 0;
85
86
BZ_MUTEX_INIT
(mutex)
87
}
88
89
MemoryBlock
(
size_t
length
,
T_type
*
data
)
90
{
91
length_
=
length
;
92
data_
=
data
;
93
dataBlockAddress_
=
data
;
94
references_
= 0;
95
BZ_MUTEX_INIT
(mutex)
96
}
97
98
virtual
~MemoryBlock
()
99
{
100
if
(
dataBlockAddress_
)
101
{
102
103
#ifdef BZ_DEBUG_LOG_ALLOCATIONS
104
cout <<
"MemoryBlock: freed "
<< setw(8) <<
length_
105
<<
" at "
<< ((
void
*)
dataBlockAddress_
) << endl;
106
#endif
107
108
deallocate
();
109
}
110
111
BZ_MUTEX_DESTROY
(mutex)
112
}
113
114
void
addReference
()
115
{
116
BZ_MUTEX_LOCK
(mutex)
117
++
references_
;
118
119
#ifdef BZ_DEBUG_LOG_REFERENCES
120
cout <<
"MemoryBlock: reffed "
<< setw(8) <<
length_
121
<<
" at "
<< ((
void
*)
dataBlockAddress_
) <<
" (r="
122
<< (int)
references_
<<
")"
<< endl;
123
#endif
124
BZ_MUTEX_UNLOCK
(mutex)
125
126
}
127
128
T_type
*
restrict
data
()
129
{
130
return
data_
;
131
}
132
133
const
T_type
*
restrict
data
()
const
134
{
135
return
data_
;
136
}
137
138
T_type
*&
dataBlockAddress
()
139
{
140
return
dataBlockAddress_
;
141
}
142
143
size_t
length
()
const
144
{
145
return
length_
;
146
}
147
148
int
removeReference
()
149
{
150
151
BZ_MUTEX_LOCK
(mutex)
152
int
refcount = --
references_
;
153
154
#ifdef BZ_DEBUG_LOG_REFERENCES
155
cout <<
"MemoryBlock: dereffed "
<< setw(8) <<
length_
156
<<
" at "
<< ((
void
*)
dataBlockAddress_
) <<
" (r="
<< (int)
references_
157
<<
")"
<< endl;
158
#endif
159
BZ_MUTEX_UNLOCK
(mutex)
160
return
refcount;
161
}
162
163
int
references
()
const
164
{
165
BZ_MUTEX_LOCK
(mutex)
166
int
refcount =
references_
;
167
BZ_MUTEX_UNLOCK
(mutex)
168
169
return
refcount;
170
}
171
172
protected
:
173
inline
void
allocate
(
size_t
length
);
174
void
deallocate
();
175
176
private
:
// Disabled member functions
177
MemoryBlock
(
const
MemoryBlock<T_type>
&)
178
{ }
179
180
void
operator=
(
const
MemoryBlock<T_type>
&)
181
{ }
182
183
private
:
// Data members
184
T_type
*
restrict
data_
;
185
T_type
*
dataBlockAddress_
;
186
187
#ifdef BZ_DEBUG_REFERENCE_ROLLOVER
188
volatile
unsigned
char
references_
;
189
#else
190
volatile
int
references_
;
191
#endif
192
193
BZ_MUTEX_DECLARE
(mutex)
194
size_t
length_
;
195
};
196
197
template<typename P_type>
198
class
UnownedMemoryBlock
: public
MemoryBlock
<P_type> {
199
public
:
200
UnownedMemoryBlock
(
size_t
length
, P_type*
data
)
201
:
MemoryBlock
<P_type>(length,data)
202
{
203
// This ensures that MemoryBlock destructor will not
204
// attempt to delete data
205
MemoryBlock<P_type>::dataBlockAddress
() = 0;
206
}
207
208
virtual
~
UnownedMemoryBlock
()
209
{
210
}
211
};
212
213
template
<
typename
P_type>
214
class
NullMemoryBlock
:
public
MemoryBlock
<P_type> {
215
public
:
216
NullMemoryBlock
()
217
{
218
// This ensures that the delete operator will not be invoked
219
// on an instance of NullMemoryBlock in removeReference().
220
MemoryBlock<P_type>::addReference
();
221
}
222
223
virtual
~
NullMemoryBlock
()
224
{ }
225
};
226
227
template
<
typename
P_type>
228
class
MemoryBlockReference
{
229
230
public
:
231
typedef
P_type
T_type
;
232
233
protected
:
234
T_type
*
restrict
data_
;
235
236
private
:
237
MemoryBlock<T_type>
*
block_
;
238
static
NullMemoryBlock<T_type>
nullBlock_
;
239
240
public
:
241
242
MemoryBlockReference
()
243
{
244
block_ = &nullBlock_;
245
block_->addReference();
246
data_
= 0;
247
}
248
249
MemoryBlockReference
(
MemoryBlockReference<T_type>
& ref,
size_t
offset=0)
250
{
251
block_ = ref.
block_
;
252
block_->
addReference
();
253
data_
= ref.
data_
+ offset;
254
}
255
256
MemoryBlockReference
(
size_t
length
,
T_type
*
data
,
257
preexistingMemoryPolicy
deletionPolicy)
258
{
259
// Create a memory block using already allocated memory.
260
261
// Note: if the deletionPolicy is duplicateData, this must
262
// be handled by the leaf class. In MemoryBlockReference,
263
// this is treated as neverDeleteData; the leaf class (e.g. Array)
264
// must duplicate the data.
265
266
if
((deletionPolicy ==
neverDeleteData
)
267
|| (deletionPolicy ==
duplicateData
))
268
block_ =
new
UnownedMemoryBlock<T_type>
(
length
,
data
);
269
else
if
(deletionPolicy ==
deleteDataWhenDone
)
270
block_ =
new
MemoryBlock<T_type>
(
length
,
data
);
271
block_->
addReference
();
272
273
#ifdef BZ_DEBUG_LOG_ALLOCATIONS
274
cout <<
"MemoryBlockReference: created MemoryBlock at "
275
<< ((
void
*)block_) << endl;
276
#endif
277
278
data_
=
data
;
279
}
280
281
explicit
MemoryBlockReference
(
size_t
items)
282
{
283
block_ =
new
MemoryBlock<T_type>
(items);
284
block_->
addReference
();
285
data_
= block_->data();
286
287
#ifdef BZ_DEBUG_LOG_ALLOCATIONS
288
cout <<
"MemoryBlockReference: created MemoryBlock at "
289
<< ((
void
*)block_) << endl;
290
#endif
291
292
}
293
294
void
blockRemoveReference()
295
{
296
int
refcount = block_->removeReference();
297
if
((refcount == 0) && (block_ != &nullBlock_))
298
{
299
#ifdef BZ_DEBUG_LOG_ALLOCATIONS
300
cout <<
"MemoryBlock: no more refs, delete MemoryBlock object at "
301
<< ((
void
*)block_) << endl;
302
#endif
303
304
delete
block_;
305
}
306
}
307
308
~
MemoryBlockReference
()
309
{
310
blockRemoveReference();
311
}
312
313
int
numReferences()
const
314
{
315
return
block_->references();
316
}
317
318
319
protected
:
320
321
void
changeToNullBlock()
322
{
323
blockRemoveReference();
324
block_ = &nullBlock_;
325
block_->addReference();
326
data_
= 0;
327
}
328
329
void
changeBlock(
MemoryBlockReference<T_type>
& ref,
size_t
offset=0)
330
{
331
blockRemoveReference();
332
block_ = ref.
block_
;
333
block_->
addReference
();
334
data_
= ref.
data_
+ offset;
335
}
336
337
void
newBlock(
size_t
items)
338
{
339
blockRemoveReference();
340
block_ =
new
MemoryBlock<T_type>
(items);
341
block_->
addReference
();
342
data_
= block_->data();
343
344
#ifdef BZ_DEBUG_LOG_ALLOCATIONS
345
cout <<
"MemoryBlockReference: created MemoryBlock at "
346
<< ((
void
*)block_) << endl;
347
#endif
348
}
349
350
private
:
351
void
operator=
(
const
MemoryBlockReference<T_type>
&)
352
{ }
353
};
354
355
356
BZ_NAMESPACE_END
357
358
#include <blitz/memblock.cc>
359
360
#endif // BZ_MEMBLOCK_H
Generated on Fri Jun 15 2012 12:01:11 for blitz by
1.8.1.1