Line data Source code
1 : #include "fd_funk.h"
2 : #include "fd_funk_base.h"
3 : #include <stdio.h>
4 :
5 : ulong
6 2340 : fd_funk_align( void ) {
7 2340 : return FD_FUNK_ALIGN;
8 2340 : }
9 :
10 : ulong
11 : fd_funk_shmem_footprint( ulong txn_max,
12 420 : ulong rec_max ) {
13 420 : if( FD_UNLIKELY( rec_max>UINT_MAX ) ) return 0UL;
14 :
15 420 : ulong l = FD_LAYOUT_INIT;
16 :
17 420 : l = FD_LAYOUT_APPEND( l, alignof(fd_funk_shmem_t), sizeof(fd_funk_shmem_t) );
18 :
19 420 : ulong txn_chain_cnt = fd_funk_txn_map_chain_cnt_est( txn_max );
20 420 : l = FD_LAYOUT_APPEND( l, fd_funk_txn_map_align(), fd_funk_txn_map_footprint( txn_chain_cnt ) );
21 420 : l = FD_LAYOUT_APPEND( l, fd_funk_txn_pool_align(), fd_funk_txn_pool_footprint() );
22 420 : l = FD_LAYOUT_APPEND( l, alignof(fd_funk_txn_t), sizeof(fd_funk_txn_t) * txn_max );
23 :
24 420 : ulong rec_chain_cnt = fd_funk_rec_map_chain_cnt_est( rec_max );
25 420 : l = FD_LAYOUT_APPEND( l, fd_funk_rec_map_align(), fd_funk_rec_map_footprint( rec_chain_cnt ) );
26 420 : l = FD_LAYOUT_APPEND( l, fd_funk_rec_pool_align(), fd_funk_rec_pool_footprint() );
27 420 : l = FD_LAYOUT_APPEND( l, alignof(fd_funk_rec_t), sizeof(fd_funk_rec_t) * rec_max );
28 :
29 420 : l = FD_LAYOUT_APPEND( l, fd_alloc_align(), fd_alloc_footprint() );
30 :
31 420 : return l;
32 420 : }
33 :
34 : ulong
35 : fd_funk_locks_footprint( ulong txn_max,
36 210 : ulong rec_max ) {
37 210 : ulong l = FD_LAYOUT_INIT;
38 210 : l = FD_LAYOUT_APPEND( l, alignof(fd_rwlock_t), sizeof(fd_rwlock_t) * txn_max );
39 210 : l = FD_LAYOUT_APPEND( l, alignof(ulong), sizeof(ulong) * rec_max );
40 210 : return FD_LAYOUT_FINI( l, fd_funk_align() );
41 210 : }
42 :
43 : /* TODO: Consider letter user just passing a join of alloc to use,
44 : inferring the backing wksp and cgroup_hint from that and then
45 : allocating exclusively from that? */
46 :
47 : void *
48 : fd_funk_shmem_new( void * shmem,
49 : ulong wksp_tag,
50 : ulong seed,
51 : ulong txn_max,
52 225 : ulong rec_max ) {
53 225 : fd_funk_shmem_t * funk = shmem;
54 225 : fd_wksp_t * wksp = fd_wksp_containing( funk );
55 :
56 225 : if( FD_UNLIKELY( !funk ) ) {
57 3 : FD_LOG_WARNING(( "NULL funk" ));
58 3 : return NULL;
59 3 : }
60 :
61 222 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)funk, fd_funk_align() ) ) ) {
62 3 : FD_LOG_WARNING(( "misaligned funk" ));
63 3 : return NULL;
64 3 : }
65 :
66 219 : if( FD_UNLIKELY( !wksp_tag ) ) {
67 3 : FD_LOG_WARNING(( "bad wksp_tag" ));
68 3 : return NULL;
69 3 : }
70 :
71 216 : if( FD_UNLIKELY( !wksp ) ) {
72 3 : FD_LOG_WARNING(( "shmem must be part of a workspace" ));
73 3 : return NULL;
74 3 : }
75 :
76 213 : if( FD_UNLIKELY( !txn_max || txn_max>FD_FUNK_TXN_IDX_NULL ) ) { /* See note in fd_funk.h about this limit */
77 3 : FD_LOG_WARNING(( "txn_max too large for index compression" ));
78 3 : return NULL;
79 3 : }
80 :
81 210 : if( FD_UNLIKELY( !rec_max || rec_max>UINT_MAX ) ) {
82 0 : FD_LOG_WARNING(( "invalid rec_max" ));
83 0 : return NULL;
84 0 : }
85 :
86 210 : FD_SCRATCH_ALLOC_INIT( l, funk+1 );
87 :
88 210 : ulong txn_chain_cnt = fd_funk_txn_map_chain_cnt_est( txn_max );
89 210 : void * txn_map = FD_SCRATCH_ALLOC_APPEND( l, fd_funk_txn_map_align(), fd_funk_txn_map_footprint( txn_chain_cnt ) );
90 210 : void * txn_pool = FD_SCRATCH_ALLOC_APPEND( l, fd_funk_txn_pool_align(), fd_funk_txn_pool_footprint() );
91 210 : fd_funk_txn_t * txn_ele = (fd_funk_txn_t *)FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_funk_txn_t), sizeof(fd_funk_txn_t) * txn_max );
92 :
93 0 : ulong rec_chain_cnt = fd_funk_rec_map_chain_cnt_est( rec_max );
94 210 : void * rec_map = FD_SCRATCH_ALLOC_APPEND( l, fd_funk_rec_map_align(), fd_funk_rec_map_footprint( rec_chain_cnt ) );
95 210 : void * rec_pool = FD_SCRATCH_ALLOC_APPEND( l, fd_funk_rec_pool_align(), fd_funk_rec_pool_footprint() );
96 210 : fd_funk_rec_t * rec_ele = (fd_funk_rec_t *)FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_funk_rec_t), sizeof(fd_funk_rec_t) * rec_max );
97 :
98 210 : void * alloc = FD_SCRATCH_ALLOC_APPEND( l, fd_alloc_align(), fd_alloc_footprint() );
99 :
100 210 : FD_TEST( _l == (ulong)funk + fd_funk_shmem_footprint( txn_max, rec_max ) );
101 :
102 210 : fd_memset( funk, 0, sizeof(fd_funk_shmem_t) );
103 :
104 210 : funk->funk_gaddr = fd_wksp_gaddr_fast( wksp, funk );
105 210 : funk->wksp_tag = wksp_tag;
106 210 : funk->seed = seed;
107 210 : funk->cycle_tag = 3UL; /* various verify functions use tags 0-2 */
108 :
109 210 : funk->txn_map_gaddr = fd_wksp_gaddr_fast( wksp, fd_funk_txn_map_new( txn_map, txn_chain_cnt, seed ) );
110 210 : void * txn_pool2 = fd_funk_txn_pool_new( txn_pool );
111 210 : funk->txn_pool_gaddr = fd_wksp_gaddr_fast( wksp, txn_pool2 );
112 210 : fd_funk_txn_pool_t txn_join[1];
113 210 : fd_funk_txn_pool_join( txn_join, txn_pool2, txn_ele, txn_max );
114 210 : fd_funk_txn_pool_reset( txn_join, 0UL );
115 210 : funk->txn_ele_gaddr = fd_wksp_gaddr_fast( wksp, txn_ele );
116 210 : funk->txn_max = txn_max;
117 210 : funk->child_head_cidx = fd_funk_txn_cidx( FD_FUNK_TXN_IDX_NULL );
118 210 : funk->child_tail_cidx = fd_funk_txn_cidx( FD_FUNK_TXN_IDX_NULL );
119 :
120 789756 : for( ulong i=0UL; i<txn_max; i++ ) {
121 789546 : txn_join->ele[ i ].state = FD_FUNK_TXN_STATE_FREE;
122 789546 : }
123 :
124 210 : fd_funk_txn_xid_set_root( funk->root );
125 210 : fd_funk_txn_xid_set_root( funk->last_publish );
126 :
127 210 : funk->rec_map_gaddr = fd_wksp_gaddr_fast( wksp, fd_funk_rec_map_new( rec_map, rec_chain_cnt, seed ) );
128 210 : void * rec_pool2 = fd_funk_rec_pool_new( rec_pool );
129 210 : funk->rec_pool_gaddr = fd_wksp_gaddr_fast( wksp, rec_pool2 );
130 210 : fd_funk_rec_pool_t rec_join[1];
131 210 : fd_funk_rec_pool_join( rec_join, rec_pool2, rec_ele, rec_max );
132 210 : fd_funk_rec_pool_reset( rec_join, 0UL );
133 210 : funk->rec_ele_gaddr = fd_wksp_gaddr_fast( wksp, rec_ele );
134 210 : funk->rec_max = (uint)rec_max;
135 :
136 210 : funk->alloc_gaddr = fd_wksp_gaddr_fast( wksp, fd_alloc_join( fd_alloc_new( alloc, wksp_tag ), 0UL ) );
137 :
138 210 : FD_COMPILER_MFENCE();
139 210 : FD_VOLATILE( funk->magic ) = FD_FUNK_MAGIC;
140 210 : FD_COMPILER_MFENCE();
141 :
142 210 : return (void *)funk;
143 210 : }
144 :
145 : fd_funk_t *
146 : fd_funk_join( fd_funk_t * ljoin,
147 : void * shfunk,
148 435 : void * shlocks ) {
149 435 : if( FD_UNLIKELY( !shfunk ) ) {
150 3 : FD_LOG_WARNING(( "NULL shfunk" ));
151 3 : return NULL;
152 3 : }
153 432 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfunk, fd_funk_align() ) ) ) {
154 3 : FD_LOG_WARNING(( "misaligned shfunk" ));
155 3 : return NULL;
156 3 : }
157 429 : fd_wksp_t * wksp = fd_wksp_containing( shfunk );
158 429 : if( FD_UNLIKELY( !wksp ) ) {
159 3 : FD_LOG_WARNING(( "shfunk must be part of a workspace" ));
160 3 : return NULL;
161 3 : }
162 :
163 426 : if( FD_UNLIKELY( !shlocks ) ) {
164 0 : FD_LOG_WARNING(( "NULL shlocks" ));
165 0 : return NULL;
166 0 : }
167 426 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shlocks, fd_funk_align() ) ) ) {
168 0 : FD_LOG_WARNING(( "misaligned shlocks" ));
169 0 : return NULL;
170 0 : }
171 :
172 426 : fd_funk_shmem_t * shmem = shfunk;
173 426 : if( FD_UNLIKELY( shmem->magic!=FD_FUNK_MAGIC ) ) {
174 3 : if (shmem->magic == FD_FUNK_MAGIC+1) {
175 0 : FD_LOG_WARNING(( "attempted to join a funk that crashed in a critical section" ));
176 3 : } else {
177 3 : FD_LOG_WARNING(( "bad magic" ));
178 3 : }
179 3 : return NULL;
180 3 : }
181 :
182 423 : if( FD_UNLIKELY( !ljoin ) ) {
183 0 : FD_LOG_WARNING(( "NULL ljoin" ));
184 0 : return NULL;
185 0 : }
186 :
187 : #ifdef FD_FUNK_WKSP_PROTECT
188 : fd_wksp_mprotect( wksp, 1 );
189 : #endif
190 :
191 423 : fd_funk_t * funk = ljoin;
192 423 : memset( funk, 0, sizeof(fd_funk_t) );
193 :
194 423 : funk->shmem = shfunk;
195 423 : funk->wksp = wksp;
196 :
197 423 : if( FD_UNLIKELY( !fd_funk_txn_pool_join( funk->txn_pool, fd_wksp_laddr( wksp, shmem->txn_pool_gaddr ), fd_wksp_laddr( wksp, shmem->txn_ele_gaddr ), shmem->txn_max ) ) ) {
198 0 : FD_LOG_WARNING(( "failed to join txn_pool" ));
199 0 : return NULL;
200 0 : }
201 423 : if( FD_UNLIKELY( !fd_funk_txn_map_join( funk->txn_map, fd_wksp_laddr( wksp, shmem->txn_map_gaddr ), fd_wksp_laddr_fast( wksp, shmem->txn_ele_gaddr ), shmem->txn_max ) ) ) {
202 0 : FD_LOG_WARNING(( "failed to join txn_map" ));
203 0 : return NULL;
204 0 : }
205 423 : if( FD_UNLIKELY( !fd_funk_rec_map_join( funk->rec_map, fd_wksp_laddr( wksp, shmem->rec_map_gaddr ), fd_wksp_laddr( wksp, shmem->rec_ele_gaddr ), shmem->rec_max ) ) ) {
206 0 : FD_LOG_WARNING(( "failed to join rec_map" ));
207 0 : return NULL;
208 0 : }
209 423 : if( FD_UNLIKELY( !fd_funk_rec_pool_join( funk->rec_pool, fd_wksp_laddr( wksp, shmem->rec_pool_gaddr ), fd_wksp_laddr_fast( wksp, shmem->rec_ele_gaddr ), shmem->rec_max ) ) ) {
210 0 : FD_LOG_WARNING(( "failed to join rec_pool" ));
211 0 : return NULL;
212 0 : }
213 423 : FD_SCRATCH_ALLOC_INIT( l2, shlocks );
214 423 : funk->txn_lock = FD_SCRATCH_ALLOC_APPEND( l2, alignof(fd_rwlock_t), sizeof(fd_rwlock_t) * shmem->txn_max );
215 423 : funk->rec_lock = FD_SCRATCH_ALLOC_APPEND( l2, alignof(ulong), sizeof(ulong) * shmem->rec_max );
216 0 : funk->alloc = fd_wksp_laddr( wksp, shmem->alloc_gaddr );
217 423 : if( FD_UNLIKELY( !fd_alloc_join( funk->alloc, fd_tile_idx() ) ) ) {
218 0 : FD_LOG_WARNING(( "failed to join funk alloc" ));
219 0 : return NULL;
220 0 : }
221 :
222 423 : return funk;
223 423 : }
224 :
225 : void *
226 : fd_funk_locks_new( void * shlocks,
227 : ulong txn_max,
228 210 : ulong rec_max ) {
229 210 : if( FD_UNLIKELY( !shlocks ) ) {
230 0 : FD_LOG_WARNING(( "NULL shlocks" ));
231 0 : return NULL;
232 0 : }
233 210 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shlocks, fd_funk_align() ) ) ) {
234 0 : FD_LOG_WARNING(( "misaligned shlocks" ));
235 0 : return NULL;
236 0 : }
237 210 : FD_SCRATCH_ALLOC_INIT( l, shlocks );
238 210 : fd_rwlock_t * txn_lock = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_rwlock_t), sizeof(fd_rwlock_t) * txn_max );
239 210 : void * rec_lock = FD_SCRATCH_ALLOC_APPEND( l, alignof(ulong), sizeof(ulong) * rec_max );
240 0 : memset( txn_lock, 0, sizeof(fd_rwlock_t) * txn_max );
241 210 : memset( rec_lock, 0, sizeof(ulong) * rec_max );
242 210 : return shlocks;
243 210 : }
244 :
245 : void *
246 : fd_funk_leave( fd_funk_t * funk,
247 : void ** opt_shfunk,
248 408 : void ** opt_shlocks ) {
249 :
250 408 : if( FD_UNLIKELY( !funk ) ) {
251 3 : FD_LOG_WARNING(( "NULL funk" ));
252 3 : if( opt_shfunk ) *opt_shfunk = NULL;
253 3 : if( opt_shlocks ) *opt_shlocks = NULL;
254 3 : return NULL;
255 3 : }
256 405 : void * shfunk = funk->shmem;
257 405 : void * shlocks = (void *)funk->txn_lock;
258 :
259 405 : memset( funk, 0, sizeof(fd_funk_t) );
260 :
261 405 : if( opt_shfunk ) *opt_shfunk = shfunk;
262 405 : if( opt_shlocks ) *opt_shlocks = shlocks;
263 405 : return (void *)funk;
264 408 : }
265 :
266 : void *
267 207 : fd_funk_delete( void * shfunk ) {
268 :
269 207 : if( FD_UNLIKELY( !shfunk ) ) {
270 3 : FD_LOG_WARNING(( "NULL shfunk" ));
271 3 : return NULL;
272 3 : }
273 :
274 204 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfunk, fd_funk_align() ) ) ) {
275 3 : FD_LOG_WARNING(( "misaligned shfunk" ));
276 3 : return NULL;
277 3 : }
278 :
279 201 : fd_wksp_t * wksp = fd_wksp_containing( shfunk );
280 201 : if( FD_UNLIKELY( !wksp ) ) {
281 3 : FD_LOG_WARNING(( "shfunk must be part of a workspace" ));
282 3 : return NULL;
283 3 : }
284 :
285 198 : fd_funk_shmem_t * shmem = shfunk;
286 198 : if( FD_UNLIKELY( shmem->magic!=FD_FUNK_MAGIC ) ) {
287 6 : FD_LOG_WARNING(( "bad magic" ));
288 6 : return NULL;
289 6 : }
290 :
291 : /* Free all fd_alloc allocations made, individually
292 : (FIXME consider walking the element pool instead of the map?) */
293 :
294 192 : fd_alloc_t * alloc = fd_alloc_join( fd_wksp_laddr_fast( wksp, shmem->alloc_gaddr ), fd_tile_idx() );
295 :
296 192 : void * shmap = fd_wksp_laddr_fast( wksp, shmem->rec_map_gaddr );
297 192 : void * shele = fd_wksp_laddr_fast( wksp, shmem->rec_ele_gaddr );
298 192 : fd_funk_rec_map_t rec_map[1];
299 192 : if( FD_UNLIKELY( !fd_funk_rec_map_join( rec_map, shmap, shele, 0UL ) ) ) {
300 0 : FD_LOG_ERR(( "failed to join rec_map (corrupt funk?)" ));
301 0 : return NULL;
302 0 : }
303 192 : ulong chain_cnt = fd_funk_rec_map_chain_cnt( rec_map );
304 444744 : for( ulong chain_idx=0UL; chain_idx<chain_cnt; chain_idx++ ) {
305 444552 : for(
306 444552 : fd_funk_rec_map_iter_t iter = fd_funk_rec_map_iter( rec_map, chain_idx );
307 445146 : !fd_funk_rec_map_iter_done( iter );
308 444552 : iter = fd_funk_rec_map_iter_next( iter )
309 444552 : ) {
310 594 : fd_funk_val_flush( fd_funk_rec_map_iter_ele( iter ), alloc, wksp );
311 594 : }
312 444552 : }
313 :
314 192 : fd_funk_rec_map_leave( rec_map );
315 :
316 192 : FD_COMPILER_MFENCE();
317 192 : FD_VOLATILE( shmem->magic ) = 0UL;
318 192 : FD_COMPILER_MFENCE();
319 :
320 : /* Free the fd_alloc instance */
321 :
322 192 : fd_wksp_free_laddr( fd_alloc_delete( fd_alloc_leave( alloc ) ) );
323 :
324 192 : return shmem;
325 192 : }
326 :
327 : void
328 9 : fd_funk_delete_fast( void * shfunk ) {
329 :
330 9 : if( FD_UNLIKELY( !shfunk ) ) {
331 0 : FD_LOG_WARNING(( "NULL shfunk" ));
332 0 : }
333 :
334 9 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfunk, fd_funk_align() ) ) ) {
335 0 : FD_LOG_WARNING(( "misaligned shfunk" ));
336 0 : }
337 :
338 9 : fd_funk_shmem_t * shmem = shfunk;
339 9 : if( FD_UNLIKELY( shmem->magic!=FD_FUNK_MAGIC ) ) {
340 0 : FD_LOG_WARNING(( "bad magic" ));
341 0 : }
342 :
343 9 : fd_wksp_t * wksp = fd_wksp_containing( shmem );
344 9 : if( FD_UNLIKELY( !wksp ) ) {
345 0 : FD_LOG_WARNING(( "shfunk must be part of a workspace" ));
346 0 : }
347 :
348 9 : ulong const tags[1] = { shmem->wksp_tag };
349 9 : fd_wksp_tag_free( wksp, tags, 1UL );
350 :
351 9 : }
352 :
353 : int
354 243 : fd_funk_verify( fd_funk_t * join ) {
355 243 : fd_funk_shmem_t * funk = join->shmem;
356 :
357 6318 : # define TEST(c) do { \
358 6318 : if( FD_UNLIKELY( !(c) ) ) { FD_LOG_WARNING(( "FAIL: %s", #c )); return FD_FUNK_ERR_INVAL; } \
359 6318 : } while(0)
360 :
361 243 : TEST( funk );
362 :
363 : /* Test metadata */
364 :
365 243 : TEST( funk->magic==FD_FUNK_MAGIC );
366 :
367 243 : ulong funk_gaddr = funk->funk_gaddr;
368 243 : TEST( funk_gaddr );
369 243 : fd_wksp_t * wksp = fd_funk_wksp( join );
370 243 : TEST( wksp );
371 243 : TEST( fd_wksp_laddr_fast( wksp, funk_gaddr )==(void *)funk );
372 243 : TEST( fd_wksp_gaddr_fast( wksp, funk )==funk_gaddr );
373 :
374 243 : ulong wksp_tag = fd_funk_wksp_tag( join );
375 243 : TEST( !!wksp_tag );
376 :
377 243 : ulong seed = funk->seed; /* seed can be anything */
378 :
379 243 : TEST( funk->cycle_tag>2UL );
380 :
381 : /* Test transaction map */
382 :
383 243 : ulong txn_max = fd_funk_txn_pool_ele_max( join->txn_pool );
384 243 : TEST( txn_max<=FD_FUNK_TXN_IDX_NULL );
385 :
386 243 : ulong txn_map_gaddr = funk->txn_map_gaddr;
387 243 : TEST( txn_map_gaddr );
388 243 : fd_funk_txn_map_t * txn_map = fd_funk_txn_map( join );
389 243 : ulong txn_chain_cnt = fd_funk_txn_map_chain_cnt_est( txn_max );
390 243 : TEST( txn_chain_cnt==fd_funk_txn_map_chain_cnt( txn_map ) );
391 243 : TEST( seed==fd_funk_txn_map_seed( txn_map ) );
392 :
393 243 : ulong child_head_idx = fd_funk_txn_idx( funk->child_head_cidx );
394 243 : ulong child_tail_idx = fd_funk_txn_idx( funk->child_tail_cidx );
395 :
396 243 : int null_child_head = fd_funk_txn_idx_is_null( child_head_idx );
397 243 : int null_child_tail = fd_funk_txn_idx_is_null( child_tail_idx );
398 :
399 243 : if( !txn_max ) TEST( null_child_head & null_child_tail );
400 243 : else {
401 243 : if( null_child_head ) TEST( null_child_tail );
402 168 : else TEST( child_head_idx<txn_max );
403 :
404 243 : if( null_child_tail ) TEST( null_child_head );
405 168 : else TEST( child_tail_idx<txn_max );
406 243 : }
407 :
408 243 : if( !txn_max ) TEST( fd_funk_txn_idx_is_null( child_tail_idx ) );
409 :
410 243 : fd_funk_txn_xid_t const * root = fd_funk_root( join );
411 243 : TEST( root ); /* Practically guaranteed */
412 243 : TEST( fd_funk_txn_xid_eq_root( root ) );
413 :
414 243 : fd_funk_txn_xid_t * last_publish = funk->last_publish;
415 243 : TEST( last_publish ); /* Practically guaranteed */
416 : /* (*last_publish) only be root at creation and anything but root post
417 : creation. But we don't know which situation applies here so this
418 : could be anything. */
419 :
420 243 : TEST( !fd_funk_txn_verify( join ) );
421 :
422 : /* Test record map */
423 :
424 243 : ulong rec_max = fd_funk_rec_pool_ele_max( join->rec_pool );
425 243 : TEST( rec_max<=FD_FUNK_TXN_IDX_NULL );
426 :
427 243 : ulong rec_map_gaddr = funk->rec_map_gaddr;
428 243 : TEST( rec_map_gaddr );
429 243 : fd_funk_rec_map_t * rec_map = fd_funk_rec_map( join );
430 243 : ulong rec_chain_cnt = fd_funk_rec_map_chain_cnt_est( rec_max );
431 243 : TEST( rec_chain_cnt==fd_funk_rec_map_chain_cnt( rec_map ) );
432 243 : TEST( seed==fd_funk_rec_map_seed( rec_map ) );
433 :
434 243 : TEST( !fd_funk_rec_verify( join ) );
435 :
436 : /* Test values */
437 :
438 243 : ulong alloc_gaddr = funk->alloc_gaddr;
439 243 : TEST( alloc_gaddr );
440 243 : fd_alloc_t * alloc = fd_funk_alloc( join );
441 243 : TEST( alloc );
442 :
443 243 : TEST( !fd_funk_val_verify( join ) );
444 :
445 243 : # undef TEST
446 :
447 243 : return FD_FUNK_SUCCESS;
448 243 : }
|