4
4
#include "storage/lwlock.h"
5
5
6
6
7
- static Table * table ;
7
+ // static Table *table;
8
8
static dsm_segment * segment = NULL ;
9
-
9
+ static dsm_handle * segment_handle = 0 ;
10
+ static size_t _first_free = 0 ;
11
+ static size_t _block_size = 0 ;
12
+
13
+ typedef int BlockHeader ;
14
+ typedef BlockHeader * BlockHeaderPtr ;
15
+
16
+ #define FREE_BIT 0x80000000
17
+ #define is_free (header ) \
18
+ ((*header) & FREE_BIT)
19
+ #define set_free (header ) \
20
+ ((*header) | FREE_BIT)
21
+ #define set_used (header ) \
22
+ ((*header) & ~FREE_BIT)
23
+ #define get_length (header ) \
24
+ ((*header) & ~FREE_BIT)
25
+ #define set_length (header ,length ) \
26
+ ((length) | ((*header) & FREE_BIT))
10
27
11
28
void
12
29
alloc_dsm_table ()
13
30
{
14
31
bool found ;
15
- table = ( Table * ) ShmemInitStruct ("dsm table" ,sizeof (Table ),& found );
32
+ segment_handle = ShmemInitStruct ("dsm table" ,sizeof (dsm_handle ),& found );
16
33
if (!found )
17
- table -> segment_handle = 0 ;
34
+ * segment_handle = 0 ;
18
35
}
19
36
20
37
26
43
init_dsm_segment (size_t block_size )
27
44
{
28
45
bool ret ;
29
- dsm_handle handle ;
30
46
31
47
/* lock here */
32
48
LWLockAcquire (dsm_init_lock ,LW_EXCLUSIVE );
33
49
34
50
/* if there is already an existing segment then attach to it */
35
- if (table -> segment_handle != 0 )
51
+ if (* segment_handle != 0 )
36
52
{
37
53
ret = false;
38
- segment = dsm_attach (table -> segment_handle );
54
+ segment = dsm_attach (* segment_handle );
39
55
}
40
56
41
57
/*
42
58
* If segment hasn't been created yet or has already been destroyed
43
59
* (it happens when last session detaches segment) then create new one
44
60
*/
45
- if (table -> segment_handle == 0 || segment == NULL )
61
+ if (* segment_handle == 0 || segment == NULL )
46
62
{
47
63
/* create segment */
48
64
segment = dsm_create (block_size * BLOCKS_COUNT ,0 );
49
- handle = dsm_segment_handle (segment );
50
- init_dsm_table (table , handle , block_size );
65
+ * segment_handle = dsm_segment_handle (segment );
66
+ init_dsm_table (block_size );
51
67
ret = true;
52
68
}
69
+ _block_size = block_size ;
53
70
54
71
/*
55
72
* Keep mapping till the end of the session. Otherwise it would be
@@ -63,25 +80,24 @@ init_dsm_segment(size_t block_size)
63
80
return ret ;
64
81
}
65
82
83
+ /*
84
+ * Initialize allocated segment with block structure
85
+ */
66
86
void
67
- init_dsm_table (Table * tbl , dsm_handle h , size_t block_size )
87
+ init_dsm_table (size_t block_size )
68
88
{
69
89
int i ;
70
- Block * block ;
71
-
72
- memset (table ,0 ,sizeof (Table ));
73
- table -> segment_handle = h ;
74
- table -> block_size = block_size ;
75
- table -> first_free = 0 ;
90
+ BlockHeaderPtr header ;
91
+ char * ptr = dsm_segment_address (segment );
76
92
77
93
/* create blocks */
78
94
for (i = 0 ;i < BLOCKS_COUNT ;i ++ )
79
95
{
80
- block = & table -> blocks [i ];
81
- block -> segment = h ;
82
- block -> offset = i * block_size ;
83
- block -> is_free = true;
96
+ header = (BlockHeaderPtr )& ptr [i * block_size ];
97
+ * header = set_free (header );
98
+ * header = set_length (header ,1 );
84
99
}
100
+ _first_free = 0 ;
85
101
86
102
return ;
87
103
}
@@ -93,71 +109,91 @@ void
93
109
alloc_dsm_array (DsmArray * arr ,size_t entry_size ,size_t length )
94
110
{
95
111
int i = 0 ;
96
- Block * block = NULL ;
97
- int free_count = 0 ;
98
112
int size_requested = entry_size * length ;
99
113
int min_pos = 0 ;
100
114
int max_pos = 0 ;
115
+ size_t offset = 0 ;
116
+ size_t total_length = 0 ;
117
+ char * ptr = dsm_segment_address (segment );
118
+ BlockHeaderPtr header ;
101
119
102
- for (i = table -> first_free ;i < BLOCKS_COUNT ;i ++ )
120
+ for (i = _first_free ;i < BLOCKS_COUNT ; )
103
121
{
104
- if (table -> blocks [i ].is_free )
122
+ header = (BlockHeaderPtr )& ptr [i * _block_size ];
123
+ if (is_free (header ))
105
124
{
106
- if (!block )
125
+ if (!offset )
107
126
{
108
- block = & table -> blocks [i ];
127
+ offset = i * _block_size ;
128
+ total_length = _block_size - sizeof (BlockHeader );
109
129
min_pos = i ;
110
130
}
111
- free_count ++ ;
131
+ else
132
+ {
133
+ total_length += _block_size ;
134
+ }
135
+ i ++ ;
112
136
}
113
137
else
114
138
{
115
- free_count = 0 ;
116
- block = NULL ;
139
+ offset = 0 ;
140
+ total_length = 0 ;
141
+ i += get_length (header );
117
142
}
118
143
119
- if (free_count * table -> block_size >=size_requested )
144
+ if (total_length >=size_requested )
120
145
{
121
- // return block->offset;
122
- max_pos = i ;
146
+ max_pos = i - 1 ;
123
147
break ;
124
148
}
125
149
}
126
150
127
151
/* look up for first free block */
128
- for (i = i + 1 ;i < BLOCKS_COUNT ;i ++ )
129
- if (table -> blocks [i ].is_free == true)
152
+ for (;i < BLOCKS_COUNT ; )
153
+ {
154
+ header = (BlockHeaderPtr )& ptr [i * _block_size ];
155
+ if (is_free (header ))
130
156
{
131
- table -> first_free = i ;
157
+ _first_free = i ;
132
158
break ;
133
159
}
160
+ else
161
+ {
162
+ i += get_length (header );
163
+ }
164
+ }
134
165
135
166
/* if we found enough of space */
136
- if (free_count * table -> block_size >=size_requested )
167
+ if (total_length >=size_requested )
137
168
{
138
- for (i = min_pos ;i <=max_pos ;i ++ )
139
- table -> blocks [i ].is_free = false;
140
- arr -> offset = block -> offset ;
169
+ header = (BlockHeaderPtr )& ptr [min_pos * _block_size ];
170
+ * header = set_used (header );
171
+ * header = set_length (header ,max_pos - min_pos + 1 );
172
+
173
+ arr -> offset = offset ;
141
174
arr -> length = length ;
142
175
}
143
176
}
144
177
145
178
void
146
179
free_dsm_array (DsmArray * arr )
147
180
{
148
- int start = arr -> offset /table -> block_size ;
181
+ int start = arr -> offset /_block_size ;
149
182
int i = 0 ;
183
+ char * ptr = dsm_segment_address (segment );
184
+ BlockHeaderPtr header = (BlockHeaderPtr )& ptr [start * _block_size ];
185
+ size_t blocks_count = get_length (header );
150
186
151
187
/* set blocks free */
152
- for (;;i ++ )
188
+ for (;i < blocks_count ;i ++ )
153
189
{
154
- table -> blocks [ start + i ]. is_free = true ;
155
- if ( i * table -> block_size >= arr -> length )
156
- break ;
190
+ header = ( BlockHeaderPtr ) & ptr [( start + i ) * _block_size ] ;
191
+ * header = set_free ( header );
192
+ * header = set_length ( header , 1 ) ;
157
193
}
158
194
159
- if (arr -> offset < table -> first_free )
160
- table -> first_free = arr -> offset ;
195
+ if (start < _first_free )
196
+ _first_free = start ;
161
197
162
198
arr -> offset = 0 ;
163
199
arr -> length = 0 ;
@@ -166,5 +202,5 @@ free_dsm_array(DsmArray *arr)
166
202
void *
167
203
dsm_array_get_pointer (const DsmArray * arr )
168
204
{
169
- return (uint8_t * )dsm_segment_address (segment )+ arr -> offset ;
205
+ return (char * )dsm_segment_address (segment )+ arr -> offset + sizeof ( BlockHeader ) ;
170
206
}