summaryrefslogtreecommitdiff
path: root/Source/DirectFB/lib/fusion/shm/shm_internal.h
blob: 3e282a598cea6c76ef48f3750138455f94e69d58 (plain)
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