source: to-imperative/trunk/runtime/pxx_memory_chunk.hh @ 286

Last change on this file since 286 was 286, checked in by orlov, 18 years ago

* empty log message *

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.9 KB
Line 
1// $Source$
2// $Revision: 286 $
3// $Date: 2002-12-17 13:29:30 +0000 (Tue, 17 Dec 2002) $
4
5#ifndef __pxx_memory_chunk_hh__
6#define __pxx_memory_chunk_hh__
7
8#include "pxx_heap_allocator.hh"
9
10namespace pxx {
11
12class Memory_Chunk
13{
14  //
15  // Можно было бы сделать такие поля:
16  //
17  //    uintptr_t dummy_field;
18  //    uintptr_t order;
19  //    uintptr_t size;
20  //    uintptr_t ref_count;
21  //
22  // Тогда не придётся сдвигать order. Но зато уменьшается кол-во полезного
23  // места в chunk'е, в результате возрастает число копирований обоих
24  // выражений и скорость работы уменьшается.
25  //
26  uintptr_t order;
27  uintptr_t ref_count;
28
29#if PARANOIA
30  //
31  // private constructors and operator= for error checking,
32  // construct_mem_chunk() should be used instead of direct constructor calls
33  inline Memory_Chunk();
34  inline Memory_Chunk( const Memory_Chunk & );
35  inline const Memory_Chunk &operator=( const Memory_Chunk & );
36#endif
37  //
38  // nobody from outside should set our internals
39  inline void set_order( size_t _order );
40
41public:
42  //
43  // instead of constructor the following function should be used
44  friend inline Memory_Chunk *construct_mem_chunk(
45      HeapAllocator *_allocator, size_t _size
46  );
47  //
48  // let _allocator to destruct us
49  inline void destruct( HeapAllocator *_allocator );
50  //
51  // return order of the whole chunk
52  inline uintptr_t get_order() const;
53  //
54  // return size of usable memory
55  inline uintptr_t get_size() const;
56  //
57  // return pointer to the begining of usable memory block
58  inline void *get_first() const;
59  //
60  // return pointer beyond the end of usable memory block
61  inline void *get_last() const;
62  //
63  // increment reference counter
64  inline void inc_ref_count();
65  //
66  // decrement reference counter,
67  // return false if it becomes zero
68  inline bool dec_ref_count();
69  //
70  // return true if there is no references to the chunk from outside ???
71  inline bool no_extern_refs() const;
72};
73
74#if PARANOIA
75
76inline Memory_Chunk::Memory_Chunk()
77{
78  FATAL( "Default constructor for Memory_Chunk class shouldn't be used!" );
79}
80
81inline Memory_Chunk::Memory_Chunk( const Memory_Chunk & )
82{
83  FATAL( "Copy constructor for Memory_Chunk class shouldn't be used!" );
84}
85
86inline const Memory_Chunk &Memory_Chunk::operator=( const Memory_Chunk & )
87{
88  FATAL( "operator=() for Memory_Chunk class shouldn't be used!" );
89  return *this;
90}
91
92#endif
93
94inline Memory_Chunk *construct_mem_chunk(
95    HeapAllocator *_allocator, size_t _size
96)
97{
98  //
99  // allocator will set order to the real order of allocated space
100  size_t order;
101  //
102  // allocate memory including space for information about chunk and get
103  // pointer to it
104  Memory_Chunk *chunk =
105    static_cast<Memory_Chunk*>(
106        _allocator->allocate( _size + sizeof(Memory_Chunk), &order )
107    );
108#if PARANOIA
109  //
110  // normally allocator should not return null, but we do not believe
111  if( chunk == null )
112    FATAL( "Unable to allocate expression" );
113#endif
114  //
115  //
116  chunk->set_order( order );
117  //
118  // set initial value of reference counter to 1
119  chunk->ref_count = 1;
120  //
121  //
122  return chunk;
123}
124
125inline void Memory_Chunk::destruct( HeapAllocator *_allocator )
126{
127  _allocator->deallocate( this, get_order() );
128}
129
130inline void Memory_Chunk::set_order( size_t _order )
131{
132  order = _order << 1 | 0x01;
133}
134
135inline uintptr_t Memory_Chunk::get_order() const
136{
137  return order >> 1;
138}
139
140inline uintptr_t Memory_Chunk::get_size() const
141{
142  return rounds[get_order()] - sizeof( Memory_Chunk );
143}
144
145inline void *Memory_Chunk::get_first() const
146{
147  return (void*)( ptr_add( this, sizeof(Memory_Chunk) ));
148}
149
150inline void *Memory_Chunk::get_last() const
151{
152  return (void*)( ptr_add( this, rounds[get_order()] ));
153}
154
155inline void Memory_Chunk::inc_ref_count()
156{
157  //
158  // check for reference counter owerflow
159  if( !(++ref_count) )
160    FATAL( "Reference counter overflow" );
161}
162
163inline bool Memory_Chunk::dec_ref_count()
164{
165  return --ref_count;
166}
167
168inline bool Memory_Chunk::no_extern_refs() const
169{
170  return ref_count == 1;
171}
172
173}
174
175#endif // __pxx_memory_chunk_hh__
Note: See TracBrowser for help on using the repository browser.