shm_internal.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
  3. (c) Copyright 2000-2004 Convergence (integrated media) GmbH
  4. All rights reserved.
  5. Written by Denis Oliver Kropp <dok@directfb.org>,
  6. Andreas Hundt <andi@fischlustig.de>,
  7. Sven Neumann <neo@directfb.org>,
  8. Ville Syrjälä <syrjala@sci.fi> and
  9. Claudio Ciccani <klan@users.sf.net>.
  10. This library is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU Lesser General Public
  12. License as published by the Free Software Foundation; either
  13. version 2 of the License, or (at your option) any later version.
  14. This library 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 GNU
  17. Lesser General Public License for more details.
  18. You should have received a copy of the GNU Lesser General Public
  19. License along with this library; if not, write to the
  20. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. Boston, MA 02111-1307, USA.
  22. */
  23. #ifndef __FUSION__SHM__SHM_INTERNAL_H__
  24. #define __FUSION__SHM__SHM_INTERNAL_H__
  25. #include <limits.h>
  26. #include <direct/list.h>
  27. #include <fusion/build.h>
  28. #include <fusion/lock.h>
  29. #define FUSION_SHM_MAX_POOLS 16
  30. #define FUSION_SHM_TMPFS_PATH_NAME_LEN 64
  31. typedef struct __shmalloc_heap shmalloc_heap;
  32. /*
  33. * Local pool data.
  34. */
  35. struct __Fusion_FusionSHMPool {
  36. int magic;
  37. bool attached; /* Indicates usage of this entry in the static pool array. */
  38. FusionSHM *shm; /* Back pointer to local SHM data. */
  39. FusionSHMPoolShared *shared; /* Pointer to shared pool data. */
  40. int pool_id; /* The pool's ID within the world. */
  41. char *filename; /* Name of the shared memory file. */
  42. };
  43. /*
  44. * Shared pool data.
  45. */
  46. struct __Fusion_FusionSHMPoolShared {
  47. int magic;
  48. bool debug; /* Debug allocations in this pool? */
  49. int index; /* Index within the static pool array. */
  50. bool active; /* Indicates usage of this entry in the static pool array. */
  51. FusionSHMShared *shm; /* Back pointer to shared SHM data. */
  52. int max_size; /* Maximum possible size of the shared memory. */
  53. int pool_id; /* The pool's ID within the world. */
  54. void *addr_base; /* Virtual starting address of shared memory. */
  55. FusionSkirmish lock; /* Lock for this pool. */
  56. shmalloc_heap *heap; /* The actual heap information ported from libc5. */
  57. char *name; /* Name of the pool (allocated in the pool). */
  58. DirectLink *allocs; /* Used for debugging. */
  59. };
  60. /*
  61. * Local SHM data.
  62. */
  63. struct __Fusion_FusionSHM {
  64. int magic;
  65. FusionWorld *world; /* Back pointer to local world data. */
  66. FusionSHMShared *shared; /* Pointer to shared SHM data. */
  67. FusionSHMPool pools[FUSION_SHM_MAX_POOLS]; /* Local data of all pools. */
  68. DirectSignalHandler *signal_handler;
  69. };
  70. /*
  71. * Shared SHM data.
  72. */
  73. struct __Fusion_FusionSHMShared {
  74. int magic;
  75. FusionWorldShared *world; /* Back pointer to shared world data. */
  76. FusionSkirmish lock; /* Lock for list of pools. */
  77. int num_pools; /* Number of active pools. */
  78. FusionSHMPoolShared pools[FUSION_SHM_MAX_POOLS]; /* Shared data of all pools. */
  79. char tmpfs[FUSION_SHM_TMPFS_PATH_NAME_LEN];
  80. };
  81. /* The allocator divides the heap into blocks of fixed size; large
  82. requests receive one or more whole blocks, and small requests
  83. receive a fragment of a block. Fragment sizes are powers of two,
  84. and all fragments of a block are the same size. When all the
  85. fragments in a block have been freed, the block itself is freed. */
  86. #define INT_BIT (CHAR_BIT * sizeof(int))
  87. #define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
  88. #define BLOCKSIZE (1 << BLOCKLOG)
  89. #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
  90. #define BLOCKALIGN(SIZE) (((SIZE) + BLOCKSIZE - 1) & ~(BLOCKSIZE - 1))
  91. /* Number of contiguous free blocks allowed to build up at the end of
  92. memory before they will be returned to the system. */
  93. #define FINAL_FREE_BLOCKS 8
  94. /* Address to block number and vice versa. */
  95. #define BLOCK(A) (((char *) (A) - heap->heapbase) / BLOCKSIZE + 1)
  96. #define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + heap->heapbase))
  97. /* Data structure giving per-block information. */
  98. typedef union {
  99. /* Heap information for a busy block. */
  100. struct {
  101. /* Zero for a large block, or positive giving the
  102. logarithm to the base two of the fragment size. */
  103. int type;
  104. union {
  105. struct {
  106. size_t nfree; /* Free fragments in a fragmented block. */
  107. size_t first; /* First free fragment of the block. */
  108. } frag;
  109. /* Size (in blocks) of a large cluster. */
  110. size_t size;
  111. } info;
  112. } busy;
  113. /* Heap information for a free block
  114. (that may be the first of a free cluster). */
  115. struct {
  116. size_t size; /* Size (in blocks) of a free cluster. */
  117. size_t next; /* Index of next free cluster. */
  118. size_t prev; /* Index of previous free cluster. */
  119. } free;
  120. } shmalloc_info;
  121. /* Doubly linked lists of free fragments. */
  122. struct list {
  123. struct list *next;
  124. struct list *prev;
  125. };
  126. #define SHMEMDESC_FUNC_NAME_LENGTH 48
  127. #define SHMEMDESC_FILE_NAME_LENGTH 24
  128. /* Used for debugging. */
  129. typedef struct {
  130. DirectLink link;
  131. const void *mem;
  132. size_t bytes;
  133. char func[SHMEMDESC_FUNC_NAME_LENGTH];
  134. char file[SHMEMDESC_FILE_NAME_LENGTH];
  135. unsigned int line;
  136. FusionID fid;
  137. } SHMemDesc;
  138. struct __shmalloc_heap {
  139. int magic;
  140. /* Pointer to first block of the heap. */
  141. char *heapbase;
  142. /* Block information table indexed by block number giving per-block information. */
  143. shmalloc_info *heapinfo;
  144. /* Number of info entries. */
  145. size_t heapsize;
  146. /* Current search index for the heap table. */
  147. size_t heapindex;
  148. /* Limit of valid info table indices. */
  149. size_t heaplimit;
  150. #if 1 /* Adapted from Mike */
  151. /* Count of large blocks allocated for each fragment size. */
  152. int fragblocks[BLOCKLOG];
  153. #endif
  154. /* Free list headers for each fragment size. */
  155. struct list fraghead[BLOCKLOG];
  156. /* Instrumentation. */
  157. size_t chunks_used;
  158. size_t bytes_used;
  159. size_t chunks_free;
  160. size_t bytes_free;
  161. /* Total size of heap in bytes. */
  162. int size;
  163. /* Back pointer to shared memory pool. */
  164. FusionSHMPoolShared *pool;
  165. char filename[FUSION_SHM_TMPFS_PATH_NAME_LEN+32];
  166. };
  167. void *_fusion_shmalloc (shmalloc_heap *heap, size_t __size);
  168. void *_fusion_shrealloc (shmalloc_heap *heap, void *__ptr, size_t __size);
  169. void _fusion_shfree (shmalloc_heap *heap, void *__ptr);
  170. DirectResult __shmalloc_init_heap( FusionSHM *shm,
  171. const char *filename,
  172. void *addr_base,
  173. int space,
  174. int *ret_size );
  175. DirectResult __shmalloc_join_heap( FusionSHM *shm,
  176. const char *filename,
  177. void *addr_base,
  178. int size,
  179. bool write );
  180. void *__shmalloc_brk ( shmalloc_heap *heap,
  181. int increment );
  182. #endif