19 #include <my_atomic.h>
28 #define lock_wrap(f, t, proto_args, args, lock) \
29 t _ ## f proto_args; \
30 static inline t f proto_args \
33 my_atomic_rwlock_wrlock(lock); \
35 my_atomic_rwlock_wrunlock(lock); \
39 #define lock_wrap_void(f, proto_args, args, lock) \
40 void _ ## f proto_args; \
41 static inline void f proto_args \
43 my_atomic_rwlock_wrlock(lock); \
45 my_atomic_rwlock_wrunlock(lock); \
48 #define nolock_wrap(f, t, proto_args, args) \
49 t _ ## f proto_args; \
50 static inline t f proto_args \
55 #define nolock_wrap_void(f, proto_args, args) \
56 void _ ## f proto_args; \
57 static inline void f proto_args \
68 #define LF_DYNARRAY_LEVEL_LENGTH 256
69 #define LF_DYNARRAY_LEVELS 4
72 void *
volatile level[LF_DYNARRAY_LEVELS];
77 typedef int (*lf_dynarray_func)(
void *,
void *);
79 void lf_dynarray_init(
LF_DYNARRAY *array, uint element_size);
82 nolock_wrap(lf_dynarray_value,
void *,
85 lock_wrap(lf_dynarray_lvalue,
void *,
89 nolock_wrap(lf_dynarray_iterate,
int,
90 (
LF_DYNARRAY *array, lf_dynarray_func func,
void *arg),
97 #define LF_PINBOX_PINS 4
98 #define LF_PURGATORY_SIZE 10
100 typedef void lf_pinbox_free_func(
void *,
void *,
void*);
104 lf_pinbox_free_func *free_func;
106 uint free_ptr_offset;
107 uint32
volatile pinstack_top_ver;
108 uint32
volatile pins_in_array;
112 void *
volatile pin[LF_PINBOX_PINS];
114 void **stack_ends_here;
116 uint32 purgatory_count;
117 uint32
volatile link;
119 #if SIZEOF_INT*2+SIZEOF_CHARP*(LF_PINBOX_PINS+3) != 64
120 char pad[64-
sizeof(uint32)*2-
sizeof(
void*)*(LF_PINBOX_PINS+3)];
128 #define lf_rwlock_by_pins(PINS) \
129 my_atomic_rwlock_wrlock(&(PINS)->pinbox->pinarray.lock)
130 #define lf_rwunlock_by_pins(PINS) \
131 my_atomic_rwlock_wrunlock(&(PINS)->pinbox->pinarray.lock)
138 #if defined(__GNUC__) && defined(MY_LF_EXTRA_DEBUG)
139 #define LF_REQUIRE_PINS(N) \
140 static const char require_pins[LF_PINBOX_PINS-N] \
141 __attribute__ ((unused)); \
142 static const int LF_NUM_PINS_IN_THIS_FILE= N;
143 #define _lf_pin(PINS, PIN, ADDR) \
145 assert(PIN < LF_NUM_PINS_IN_THIS_FILE), \
146 my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR)) \
149 #define LF_REQUIRE_PINS(N)
150 #define _lf_pin(PINS, PIN, ADDR) my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR))
153 #define _lf_unpin(PINS, PIN) _lf_pin(PINS, PIN, NULL)
154 #define lf_pin(PINS, PIN, ADDR) \
156 lf_rwlock_by_pins(PINS); \
157 _lf_pin(PINS, PIN, ADDR); \
158 lf_rwunlock_by_pins(PINS); \
160 #define lf_unpin(PINS, PIN) lf_pin(PINS, PIN, NULL)
161 #define _lf_assert_pin(PINS, PIN) assert((PINS)->pin[PIN] != 0)
162 #define _lf_assert_unpin(PINS, PIN) assert((PINS)->pin[PIN] == 0)
164 void lf_pinbox_init(
LF_PINBOX *pinbox, uint free_ptr_offset,
165 lf_pinbox_free_func *free_func,
void * free_func_arg);
166 void lf_pinbox_destroy(
LF_PINBOX *pinbox);
168 lock_wrap(lf_pinbox_get_pins,
LF_PINS *,
171 &pinbox->pinarray.lock)
172 lock_wrap_void(lf_pinbox_put_pins,
175 &pins->pinbox->pinarray.lock)
176 lock_wrap_void(lf_pinbox_free,
179 &pins->pinbox->pinarray.lock)
185 typedef struct st_lf_allocator {
187 uchar *
volatile top;
189 uint32
volatile mallocs;
190 void (*constructor)(uchar *);
191 void (*destructor)(uchar *);
194 void lf_alloc_init(LF_ALLOCATOR *allocator, uint
size, uint free_ptr_offset);
195 void lf_alloc_destroy(LF_ALLOCATOR *allocator);
196 uint lf_alloc_pool_count(LF_ALLOCATOR *allocator);
201 #define _lf_alloc_free(PINS, PTR) _lf_pinbox_free((PINS), (PTR))
202 #define lf_alloc_free(PINS, PTR) lf_pinbox_free((PINS), (PTR))
203 #define _lf_alloc_get_pins(A) _lf_pinbox_get_pins(&(A)->pinbox)
204 #define lf_alloc_get_pins(A) lf_pinbox_get_pins(&(A)->pinbox)
205 #define _lf_alloc_put_pins(PINS) _lf_pinbox_put_pins(PINS)
206 #define lf_alloc_put_pins(PINS) lf_pinbox_put_pins(PINS)
207 #define lf_alloc_direct_free(ALLOC, ADDR) my_free((ADDR))
209 lock_wrap(lf_alloc_new,
void *,
212 &pins->pinbox->pinarray.lock)
223 #define LF_HASH_UNIQUE 1
226 extern const int LF_HASH_OVERHEAD;
231 my_hash_get_key get_key;
233 uint key_offset, key_length;
237 int32
volatile count;
240 void lf_hash_init(
LF_HASH *hash, uint element_size, uint
flags,
241 uint key_offset, uint key_length, my_hash_get_key get_key,
243 void lf_hash_destroy(
LF_HASH *hash);
244 int lf_hash_insert(
LF_HASH *hash,
LF_PINS *pins,
const void *data);
245 void *lf_hash_search(
LF_HASH *hash,
LF_PINS *pins,
const void *key, uint keylen);
246 int lf_hash_delete(
LF_HASH *hash,
LF_PINS *pins,
const void *key, uint keylen);
251 #define _lf_hash_get_pins(HASH) _lf_alloc_get_pins(&(HASH)->alloc)
252 #define lf_hash_get_pins(HASH) lf_alloc_get_pins(&(HASH)->alloc)
253 #define _lf_hash_put_pins(PINS) _lf_pinbox_put_pins(PINS)
254 #define lf_hash_put_pins(PINS) lf_pinbox_put_pins(PINS)
255 #define lf_hash_search_unpin(PINS) lf_unpin((PINS), 2)
260 #undef lock_wrap_void
262 #undef nolock_wrap_void