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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
/*
(c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
(c) Copyright 2000-2004 Convergence (integrated media) GmbH
All rights reserved.
Written by Denis Oliver Kropp <dok@directfb.org>,
Andreas Hundt <andi@fischlustig.de>,
Sven Neumann <neo@directfb.org>,
Ville Syrjälä <syrjala@sci.fi> and
Claudio Ciccani <klan@users.sf.net>.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef __FUSION__SHM__SHM_INTERNAL_H__
#define __FUSION__SHM__SHM_INTERNAL_H__
#include <limits.h>
#include <direct/list.h>
#include <fusion/build.h>
#include <fusion/lock.h>
#define FUSION_SHM_MAX_POOLS 24
#define FUSION_SHM_TMPFS_PATH_NAME_LEN 64
typedef struct __shmalloc_heap shmalloc_heap;
/*
* Local pool data.
*/
struct __Fusion_FusionSHMPool {
int magic;
bool attached; /* Indicates usage of this entry in the static pool array. */
FusionSHM *shm; /* Back pointer to local SHM data. */
FusionSHMPoolShared *shared; /* Pointer to shared pool data. */
int pool_id; /* The pool's ID within the world. */
int fd; /* File descriptor of shared memory file. */
char *filename; /* Name of the shared memory file. */
};
/*
* Shared pool data.
*/
struct __Fusion_FusionSHMPoolShared {
int magic;
bool debug; /* Debug allocations in this pool? */
int index; /* Index within the static pool array. */
bool active; /* Indicates usage of this entry in the static pool array. */
FusionSHMShared *shm; /* Back pointer to shared SHM data. */
int max_size; /* Maximum possible size of the shared memory. */
int pool_id; /* The pool's ID within the world. */
void *addr_base; /* Virtual starting address of shared memory. */
FusionSkirmish lock; /* Lock for this pool. */
shmalloc_heap *heap; /* The actual heap information ported from libc5. */
char *name; /* Name of the pool (allocated in the pool). */
DirectLink *allocs; /* Used for debugging. */
};
/*
* Local SHM data.
*/
struct __Fusion_FusionSHM {
int magic;
FusionWorld *world; /* Back pointer to local world data. */
FusionSHMShared *shared; /* Pointer to shared SHM data. */
FusionSHMPool pools[FUSION_SHM_MAX_POOLS]; /* Local data of all pools. */
DirectSignalHandler *signal_handler;
};
/*
* Shared SHM data.
*/
struct __Fusion_FusionSHMShared {
int magic;
FusionWorldShared *world; /* Back pointer to shared world data. */
FusionSkirmish lock; /* Lock for list of pools. */
int num_pools; /* Number of active pools. */
FusionSHMPoolShared pools[FUSION_SHM_MAX_POOLS]; /* Shared data of all pools. */
char tmpfs[FUSION_SHM_TMPFS_PATH_NAME_LEN];
};
/* The allocator divides the heap into blocks of fixed size; large
requests receive one or more whole blocks, and small requests
receive a fragment of a block. Fragment sizes are powers of two,
and all fragments of a block are the same size. When all the
fragments in a block have been freed, the block itself is freed. */
#define INT_BIT (CHAR_BIT * sizeof(int))
#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
#define BLOCKSIZE (1 << BLOCKLOG)
#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
#define BLOCKALIGN(SIZE) (((SIZE) + BLOCKSIZE - 1) & ~(BLOCKSIZE - 1))
/* Number of contiguous free blocks allowed to build up at the end of
memory before they will be returned to the system. */
#define FINAL_FREE_BLOCKS 8
/* Address to block number and vice versa. */
#define BLOCK(A) (((char *) (A) - heap->heapbase) / BLOCKSIZE + 1)
#define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + heap->heapbase))
/* Data structure giving per-block information. */
typedef union {
/* Heap information for a busy block. */
struct {
/* Zero for a large block, or positive giving the
logarithm to the base two of the fragment size. */
int type;
union {
struct {
size_t nfree; /* Free fragments in a fragmented block. */
size_t first; /* First free fragment of the block. */
} frag;
/* Size (in blocks) of a large cluster. */
size_t size;
} info;
} busy;
/* Heap information for a free block
(that may be the first of a free cluster). */
struct {
size_t size; /* Size (in blocks) of a free cluster. */
size_t next; /* Index of next free cluster. */
size_t prev; /* Index of previous free cluster. */
} free;
} shmalloc_info;
/* Doubly linked lists of free fragments. */
struct list {
struct list *next;
struct list *prev;
};
#define SHMEMDESC_FUNC_NAME_LENGTH 48
#define SHMEMDESC_FILE_NAME_LENGTH 24
/* Used for debugging. */
typedef struct {
DirectLink link;
const void *mem;
size_t bytes;
char func[SHMEMDESC_FUNC_NAME_LENGTH];
char file[SHMEMDESC_FILE_NAME_LENGTH];
unsigned int line;
FusionID fid;
} SHMemDesc;
struct __shmalloc_heap {
int magic;
/* Pointer to first block of the heap. */
char *heapbase;
/* Block information table indexed by block number giving per-block information. */
shmalloc_info *heapinfo;
/* Number of info entries. */
size_t heapsize;
/* Current search index for the heap table. */
size_t heapindex;
/* Limit of valid info table indices. */
size_t heaplimit;
#if 1 /* Adapted from Mike */
/* Count of large blocks allocated for each fragment size. */
int fragblocks[BLOCKLOG];
#endif
/* Free list headers for each fragment size. */
struct list fraghead[BLOCKLOG];
/* Instrumentation. */
size_t chunks_used;
size_t bytes_used;
size_t chunks_free;
size_t bytes_free;
/* Total size of heap in bytes. */
int size;
/* Back pointer to shared memory pool. */
FusionSHMPoolShared *pool;
};
void *_fusion_shmalloc (shmalloc_heap *heap, size_t __size);
void *_fusion_shrealloc (shmalloc_heap *heap, void *__ptr, size_t __size);
void _fusion_shfree (shmalloc_heap *heap, void *__ptr);
DirectResult __shmalloc_init_heap( FusionSHM *shm,
const char *filename,
void *addr_base,
int space,
int *ret_fd,
int *ret_size );
DirectResult __shmalloc_join_heap( FusionSHM *shm,
const char *filename,
void *addr_base,
int size,
int *ret_fd );
void *__shmalloc_brk ( shmalloc_heap *heap,
int increment );
#endif
|