Skip to content

Commit a4589f3

Browse files
riptlripatel-fd
authored andcommitted
funk: move global iter API to private header
Discourage use of global iterator, which is inherently incompatible with concurrent usage.
1 parent e467a08 commit a4589f3

File tree

11 files changed

+152
-151
lines changed

11 files changed

+152
-151
lines changed

src/flamenco/runtime/program/test_program_cache_concur.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "../../../funk/fd_funk_rec.h"
22
#include "../../../funk/fd_funk_txn.h"
3-
#include "../../../funk/test_funk_common.hpp"
3+
#include "../../../funk/test_funk_common.hxx"
44
#include "fd_program_cache.h"
55
#include <cstdio>
66
#include <pthread.h>

src/flamenco/runtime/tests/fd_solfuzz.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ fd_solfuzz_runner_leak_check( fd_solfuzz_runner_t * runner ) {
140140
FD_LOG_CRIT(( "solfuzz leaked a spad frame (bump allocator)" ));
141141
}
142142

143-
fd_funk_txn_all_iter_t iter[1];
144-
for( fd_funk_txn_all_iter_new( runner->funk, iter ); !fd_funk_txn_all_iter_done( iter ); fd_funk_txn_all_iter_next( iter ) ) {
143+
if( FD_UNLIKELY( !fd_funk_txn_idx_is_null( fd_funk_txn_idx( runner->funk->shmem->child_head_cidx ) ) ) ) {
145144
FD_LOG_CRIT(( "solfuzz leaked a funk txn" ));
146145
}
147146
}

src/funk/fd_funk_private.h

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#ifndef HEADER_fd_src_funk_fd_funk_private_h
2+
#define HEADER_fd_src_funk_fd_funk_private_h
3+
4+
/* fd_funk_private.h contains internal APIs deemed unsafe for public
5+
consumption. */
6+
7+
#include "fd_funk.h"
8+
9+
/* fd_funk_all_iter_t iterators over all funk record objects in all funk
10+
transactions. This API is not optimized for performance and has a
11+
high fixed cost (slow even for empty DBs).
12+
13+
Assumes no concurrent write accesses to the entire funk instance
14+
during the lifetime of this iterator.
15+
16+
Usage is:
17+
18+
fd_funk_all_iter_t iter[1];
19+
for( fd_funk_all_iter_new( funk, iter ); !fd_funk_all_iter_done( iter ); fd_funk_all_iter_next( iter ) ) {
20+
fd_funk_rec_t const * rec = fd_funk_all_iter_ele_const( iter );
21+
...
22+
} */
23+
24+
struct fd_funk_all_iter {
25+
fd_funk_rec_map_t rec_map;
26+
ulong chain_cnt;
27+
ulong chain_idx;
28+
fd_funk_rec_map_iter_t rec_map_iter;
29+
};
30+
31+
typedef struct fd_funk_all_iter fd_funk_all_iter_t;
32+
33+
FD_PROTOTYPES_BEGIN
34+
35+
FD_FN_UNUSED static void
36+
fd_funk_all_iter_skip_nulls( fd_funk_all_iter_t * iter ) {
37+
if( iter->chain_idx == iter->chain_cnt ) return;
38+
while( fd_funk_rec_map_iter_done( iter->rec_map_iter ) ) {
39+
if( ++(iter->chain_idx) == iter->chain_cnt ) break;
40+
iter->rec_map_iter = fd_funk_rec_map_iter( &iter->rec_map, iter->chain_idx );
41+
}
42+
}
43+
44+
FD_FN_UNUSED static void
45+
fd_funk_all_iter_new( fd_funk_t const * funk,
46+
fd_funk_all_iter_t * iter ) {
47+
iter->rec_map = *funk->rec_map;
48+
iter->chain_cnt = fd_funk_rec_map_chain_cnt( &iter->rec_map );
49+
iter->chain_idx = 0;
50+
iter->rec_map_iter = fd_funk_rec_map_iter( &iter->rec_map, 0 );
51+
fd_funk_all_iter_skip_nulls( iter );
52+
}
53+
54+
static inline int
55+
fd_funk_all_iter_done( fd_funk_all_iter_t const * iter ) {
56+
return ( iter->chain_idx == iter->chain_cnt );
57+
}
58+
59+
FD_FN_UNUSED static void
60+
fd_funk_all_iter_next( fd_funk_all_iter_t * iter ) {
61+
iter->rec_map_iter = fd_funk_rec_map_iter_next( iter->rec_map_iter );
62+
fd_funk_all_iter_skip_nulls( iter );
63+
}
64+
65+
static inline fd_funk_rec_t const *
66+
fd_funk_all_iter_ele_const( fd_funk_all_iter_t * iter ) {
67+
return fd_funk_rec_map_iter_ele_const( iter->rec_map_iter );
68+
}
69+
70+
static inline fd_funk_rec_t *
71+
fd_funk_all_iter_ele( fd_funk_all_iter_t * iter ) {
72+
return fd_funk_rec_map_iter_ele( iter->rec_map_iter );
73+
}
74+
75+
FD_PROTOTYPES_END
76+
77+
/* fd_funk_txn_all_iter_t iterators over all funk transaction objects.
78+
79+
Assumes no concurrent write accesses to the entire funk instance
80+
during the lifetime of this iterator.
81+
82+
Usage is:
83+
84+
fd_funk_txn_all_iter_t txn_iter[1];
85+
for( fd_funk_txn_all_iter_new( funk, txn_iter ); !fd_funk_txn_all_iter_done( txn_iter ); fd_funk_txn_all_iter_next( txn_iter ) ) {
86+
fd_funk_txn_t const * txn = fd_funk_txn_all_iter_ele_const( txn_iter );
87+
...
88+
}
89+
90+
FIXME depth-first search transaction tree instead */
91+
92+
struct fd_funk_txn_all_iter {
93+
fd_funk_txn_map_t txn_map;
94+
ulong chain_cnt;
95+
ulong chain_idx;
96+
fd_funk_txn_map_iter_t txn_map_iter;
97+
};
98+
99+
typedef struct fd_funk_txn_all_iter fd_funk_txn_all_iter_t;
100+
101+
FD_PROTOTYPES_BEGIN
102+
103+
FD_FN_UNUSED static void
104+
fd_funk_txn_all_iter_skip_nulls( fd_funk_txn_all_iter_t * iter ) {
105+
if( iter->chain_idx == iter->chain_cnt ) return;
106+
while( fd_funk_txn_map_iter_done( iter->txn_map_iter ) ) {
107+
if( ++(iter->chain_idx) == iter->chain_cnt ) break;
108+
iter->txn_map_iter = fd_funk_txn_map_iter( &iter->txn_map, iter->chain_idx );
109+
}
110+
}
111+
112+
FD_FN_UNUSED static void
113+
fd_funk_txn_all_iter_new( fd_funk_t const * funk,
114+
fd_funk_txn_all_iter_t * iter ) {
115+
iter->txn_map = *funk->txn_map;
116+
iter->chain_cnt = fd_funk_txn_map_chain_cnt( funk->txn_map );
117+
iter->chain_idx = 0;
118+
iter->txn_map_iter = fd_funk_txn_map_iter( funk->txn_map, 0 );
119+
fd_funk_txn_all_iter_skip_nulls( iter );
120+
}
121+
122+
static inline int
123+
fd_funk_txn_all_iter_done( fd_funk_txn_all_iter_t const * iter ) {
124+
return iter->chain_idx == iter->chain_cnt;
125+
}
126+
127+
FD_FN_UNUSED static void
128+
fd_funk_txn_all_iter_next( fd_funk_txn_all_iter_t * iter ) {
129+
iter->txn_map_iter = fd_funk_txn_map_iter_next( iter->txn_map_iter );
130+
fd_funk_txn_all_iter_skip_nulls( iter );
131+
}
132+
133+
static inline fd_funk_txn_t const *
134+
fd_funk_txn_all_iter_ele_const( fd_funk_txn_all_iter_t * iter ) {
135+
return fd_funk_txn_map_iter_ele_const( iter->txn_map_iter );
136+
}
137+
138+
static inline fd_funk_txn_t *
139+
fd_funk_txn_all_iter_ele( fd_funk_txn_all_iter_t * iter ) {
140+
return fd_funk_txn_map_iter_ele( iter->txn_map_iter );
141+
}
142+
143+
FD_PROTOTYPES_END
144+
145+
#endif /* HEADER_fd_src_funk_fd_funk_private_h */

src/funk/fd_funk_rec.c

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
#include "fd_funk.h"
2-
#include "fd_funk_base.h"
3-
#include "fd_funk_txn.h"
1+
#include "fd_funk_private.h"
42
#include "../util/racesan/fd_racesan_target.h"
53

64
/* Provide the actual record map implementation */
@@ -500,45 +498,6 @@ fd_funk_rec_remove( fd_funk_t * funk,
500498
return FD_FUNK_SUCCESS;
501499
}
502500

503-
static void
504-
fd_funk_all_iter_skip_nulls( fd_funk_all_iter_t * iter ) {
505-
if( iter->chain_idx == iter->chain_cnt ) return;
506-
while( fd_funk_rec_map_iter_done( iter->rec_map_iter ) ) {
507-
if( ++(iter->chain_idx) == iter->chain_cnt ) break;
508-
iter->rec_map_iter = fd_funk_rec_map_iter( &iter->rec_map, iter->chain_idx );
509-
}
510-
}
511-
512-
void
513-
fd_funk_all_iter_new( fd_funk_t * funk, fd_funk_all_iter_t * iter ) {
514-
iter->rec_map = *funk->rec_map;
515-
iter->chain_cnt = fd_funk_rec_map_chain_cnt( &iter->rec_map );
516-
iter->chain_idx = 0;
517-
iter->rec_map_iter = fd_funk_rec_map_iter( &iter->rec_map, 0 );
518-
fd_funk_all_iter_skip_nulls( iter );
519-
}
520-
521-
int
522-
fd_funk_all_iter_done( fd_funk_all_iter_t * iter ) {
523-
return ( iter->chain_idx == iter->chain_cnt );
524-
}
525-
526-
void
527-
fd_funk_all_iter_next( fd_funk_all_iter_t * iter ) {
528-
iter->rec_map_iter = fd_funk_rec_map_iter_next( iter->rec_map_iter );
529-
fd_funk_all_iter_skip_nulls( iter );
530-
}
531-
532-
fd_funk_rec_t const *
533-
fd_funk_all_iter_ele_const( fd_funk_all_iter_t * iter ) {
534-
return fd_funk_rec_map_iter_ele_const( iter->rec_map_iter );
535-
}
536-
537-
fd_funk_rec_t *
538-
fd_funk_all_iter_ele( fd_funk_all_iter_t * iter ) {
539-
return fd_funk_rec_map_iter_ele( iter->rec_map_iter );
540-
}
541-
542501
int
543502
fd_funk_rec_verify( fd_funk_t * funk ) {
544503
fd_funk_rec_map_t * rec_map = funk->rec_map;

src/funk/fd_funk_rec.h

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -333,40 +333,6 @@ fd_funk_rec_remove( fd_funk_t * funk,
333333
fd_funk_rec_key_t const * key,
334334
fd_funk_rec_t ** rec_out );
335335

336-
/* fd_funk_all_iter_t iterators over all funk record objects in all funk
337-
transactions.
338-
339-
Assumes that no other join is doing funk write accesses during the
340-
lifetime of the iterator object. This API is not optimized for
341-
performance and has a high fixed cost (slow even for empty DBs).
342-
343-
Usage is:
344-
345-
fd_funk_all_iter_t iter[1];
346-
for( fd_funk_all_iter_new( funk, iter ); !fd_funk_all_iter_done( iter ); fd_funk_all_iter_next( iter ) ) {
347-
fd_funk_rec_t const * rec = fd_funk_all_iter_ele_const( iter );
348-
...
349-
} */
350-
351-
struct fd_funk_all_iter {
352-
fd_funk_rec_map_t rec_map;
353-
ulong chain_cnt;
354-
ulong chain_idx;
355-
fd_funk_rec_map_iter_t rec_map_iter;
356-
};
357-
358-
typedef struct fd_funk_all_iter fd_funk_all_iter_t;
359-
360-
void fd_funk_all_iter_new( fd_funk_t * funk, fd_funk_all_iter_t * iter );
361-
362-
int fd_funk_all_iter_done( fd_funk_all_iter_t * iter );
363-
364-
void fd_funk_all_iter_next( fd_funk_all_iter_t * iter );
365-
366-
fd_funk_rec_t const * fd_funk_all_iter_ele_const( fd_funk_all_iter_t * iter );
367-
368-
fd_funk_rec_t * fd_funk_all_iter_ele( fd_funk_all_iter_t * iter );
369-
370336
/* Misc */
371337

372338
/* fd_funk_rec_verify verifies the record map. Returns FD_FUNK_SUCCESS

src/funk/fd_funk_txn.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -798,46 +798,6 @@ fd_funk_generate_xid(void) {
798798
return xid;
799799
}
800800

801-
static void
802-
fd_funk_txn_all_iter_skip_nulls( fd_funk_txn_all_iter_t * iter ) {
803-
if( iter->chain_idx == iter->chain_cnt ) return;
804-
while( fd_funk_txn_map_iter_done( iter->txn_map_iter ) ) {
805-
if( ++(iter->chain_idx) == iter->chain_cnt ) break;
806-
iter->txn_map_iter = fd_funk_txn_map_iter( &iter->txn_map, iter->chain_idx );
807-
}
808-
}
809-
810-
void
811-
fd_funk_txn_all_iter_new( fd_funk_t * funk,
812-
fd_funk_txn_all_iter_t * iter ) {
813-
iter->txn_map = *funk->txn_map;
814-
iter->chain_cnt = fd_funk_txn_map_chain_cnt( funk->txn_map );
815-
iter->chain_idx = 0;
816-
iter->txn_map_iter = fd_funk_txn_map_iter( funk->txn_map, 0 );
817-
fd_funk_txn_all_iter_skip_nulls( iter );
818-
}
819-
820-
int
821-
fd_funk_txn_all_iter_done( fd_funk_txn_all_iter_t * iter ) {
822-
return ( iter->chain_idx == iter->chain_cnt );
823-
}
824-
825-
void
826-
fd_funk_txn_all_iter_next( fd_funk_txn_all_iter_t * iter ) {
827-
iter->txn_map_iter = fd_funk_txn_map_iter_next( iter->txn_map_iter );
828-
fd_funk_txn_all_iter_skip_nulls( iter );
829-
}
830-
831-
fd_funk_txn_t const *
832-
fd_funk_txn_all_iter_ele_const( fd_funk_txn_all_iter_t * iter ) {
833-
return fd_funk_txn_map_iter_ele_const( iter->txn_map_iter );
834-
}
835-
836-
fd_funk_txn_t *
837-
fd_funk_txn_all_iter_ele( fd_funk_txn_all_iter_t * iter ) {
838-
return fd_funk_txn_map_iter_ele( iter->txn_map_iter );
839-
}
840-
841801
int
842802
fd_funk_txn_verify( fd_funk_t * funk ) {
843803
fd_funk_txn_map_t * txn_map = funk->txn_map;

src/funk/fd_funk_txn.h

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -401,34 +401,6 @@ fd_funk_txn_publish_into_parent( fd_funk_t * funk,
401401
void
402402
fd_funk_txn_remove_published( fd_funk_t * funk );
403403

404-
/* fd_funk_txn_all_iter_t iterators over all funk transaction objects.
405-
Usage is:
406-
407-
fd_funk_txn_all_iter_t txn_iter[1];
408-
for( fd_funk_txn_all_iter_new( funk, txn_iter ); !fd_funk_txn_all_iter_done( txn_iter ); fd_funk_txn_all_iter_next( txn_iter ) ) {
409-
fd_funk_txn_t const * txn = fd_funk_txn_all_iter_ele_const( txn_iter );
410-
...
411-
}
412-
*/
413-
414-
struct fd_funk_txn_all_iter {
415-
fd_funk_txn_map_t txn_map;
416-
ulong chain_cnt;
417-
ulong chain_idx;
418-
fd_funk_txn_map_iter_t txn_map_iter;
419-
};
420-
421-
typedef struct fd_funk_txn_all_iter fd_funk_txn_all_iter_t;
422-
423-
void fd_funk_txn_all_iter_new( fd_funk_t * funk, fd_funk_txn_all_iter_t * iter );
424-
425-
int fd_funk_txn_all_iter_done( fd_funk_txn_all_iter_t * iter );
426-
427-
void fd_funk_txn_all_iter_next( fd_funk_txn_all_iter_t * iter );
428-
429-
fd_funk_txn_t const * fd_funk_txn_all_iter_ele_const( fd_funk_txn_all_iter_t * iter );
430-
fd_funk_txn_t * fd_funk_txn_all_iter_ele( fd_funk_txn_all_iter_t * iter );
431-
432404
/* Misc */
433405

434406
/* fd_funk_txn_verify verifies a transaction map. Returns

src/funk/fd_funk_val.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "fd_funk.h"
1+
#include "fd_funk_private.h"
22

33
void *
44
fd_funk_val_truncate( fd_funk_rec_t * rec,

src/funk/test_funk_common.hpp renamed to src/funk/test_funk_common.hxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "fd_funk.h"
1+
#include "fd_funk_private.h"
22
#include <map>
33
#include <vector>
44
#include <set>

src/funk/test_funk_concur.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "test_funk_common.hpp"
1+
#include "test_funk_common.hxx"
22
#include <cstdio>
33
#include <pthread.h>
44

0 commit comments

Comments
 (0)