Line data Source code
1 : #include "fd_dbl_buf.h"
2 : #include "../../util/log/fd_log.h"
3 : #include "../../tango/fd_tango_base.h"
4 :
5 : #if FD_HAS_SSE
6 : #include "../../util/simd/fd_sse.h"
7 : #endif
8 :
9 : ulong
10 3 : fd_dbl_buf_align( void ) {
11 3 : return FD_DBL_BUF_ALIGN;
12 3 : }
13 :
14 : ulong
15 3 : fd_dbl_buf_footprint( ulong mtu ) {
16 3 : return FD_DBL_BUF_FOOTPRINT( mtu );
17 3 : }
18 :
19 : void *
20 : fd_dbl_buf_new( void * shmem,
21 : ulong mtu,
22 0 : ulong seq0 ) {
23 :
24 0 : if( FD_UNLIKELY( !shmem ) ) {
25 0 : FD_LOG_WARNING(( "NULL shmem" ));
26 0 : return NULL;
27 0 : }
28 :
29 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, FD_DBL_BUF_ALIGN ) ) ) {
30 0 : FD_LOG_WARNING(( "misaligned shmem" ));
31 0 : return NULL;
32 0 : }
33 :
34 0 : ulong mtu_align = fd_ulong_align_up( mtu, FD_DBL_BUF_ALIGN );
35 0 : FD_SCRATCH_ALLOC_INIT( l, shmem );
36 0 : fd_dbl_buf_t * dbl_buf = FD_SCRATCH_ALLOC_APPEND( l, FD_DBL_BUF_ALIGN, sizeof(fd_dbl_buf_t) );
37 0 : void * buf0 = FD_SCRATCH_ALLOC_APPEND( l, FD_DBL_BUF_ALIGN, mtu_align );
38 0 : void * buf1 = FD_SCRATCH_ALLOC_APPEND( l, FD_DBL_BUF_ALIGN, mtu_align );
39 0 : FD_SCRATCH_ALLOC_FINI( l, FD_DBL_BUF_ALIGN );
40 :
41 0 : *dbl_buf = (fd_dbl_buf_t) {
42 0 : .magic = 0UL,
43 0 : .seq = seq0,
44 0 : .sz = 0UL,
45 0 : .mtu = mtu,
46 0 : .buf0 = (ulong)buf0 - (ulong)dbl_buf,
47 0 : .buf1 = (ulong)buf1 - (ulong)dbl_buf
48 0 : };
49 :
50 0 : FD_COMPILER_MFENCE();
51 0 : FD_VOLATILE( dbl_buf->magic ) = FD_DBL_BUF_MAGIC;
52 0 : FD_COMPILER_MFENCE();
53 :
54 0 : return dbl_buf;
55 0 : }
56 :
57 : fd_dbl_buf_t *
58 0 : fd_dbl_buf_join( void * shbuf ) {
59 :
60 0 : if( FD_UNLIKELY( !shbuf ) ) {
61 0 : FD_LOG_WARNING(( "NULL shbuf" ));
62 0 : return NULL;
63 0 : }
64 :
65 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shbuf, FD_DBL_BUF_ALIGN ) ) ) {
66 0 : FD_LOG_WARNING(( "misaligned shbuf" ));
67 0 : return NULL;
68 0 : }
69 :
70 0 : fd_dbl_buf_t * dbl_buf = shbuf;
71 0 : if( FD_UNLIKELY( dbl_buf->magic!=FD_DBL_BUF_MAGIC ) ) {
72 0 : FD_LOG_WARNING(( "bad magic" ));
73 0 : return NULL;
74 0 : }
75 :
76 0 : return dbl_buf;
77 0 : }
78 :
79 : void *
80 0 : fd_dbl_buf_leave( fd_dbl_buf_t * buf ) {
81 0 : return buf;
82 0 : }
83 :
84 : void *
85 0 : fd_dbl_buf_delete( void * shbuf ) {
86 :
87 0 : if( FD_UNLIKELY( !shbuf ) ) {
88 0 : FD_LOG_WARNING(( "NULL shbuf" ));
89 0 : return NULL;
90 0 : }
91 :
92 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shbuf, FD_DBL_BUF_ALIGN ) ) ) {
93 0 : FD_LOG_WARNING(( "misaligned shbuf" ));
94 0 : return NULL;
95 0 : }
96 :
97 0 : fd_dbl_buf_t * dbl_buf = shbuf;
98 0 : FD_COMPILER_MFENCE();
99 0 : FD_VOLATILE( dbl_buf->magic ) = 0UL;
100 0 : FD_COMPILER_MFENCE();
101 0 : return dbl_buf;
102 0 : }
103 :
104 : void
105 : fd_dbl_buf_insert( fd_dbl_buf_t * buf,
106 : void const * msg,
107 0 : ulong sz ) {
108 0 : /* */ sz = fd_ulong_min( sz, buf->mtu );
109 0 : ulong seq = fd_seq_inc( buf->seq, 1UL );
110 0 : void * dst = fd_dbl_buf_slot( buf, seq );
111 :
112 0 : fd_memcpy( dst, msg, sz );
113 :
114 0 : # if FD_HAS_SSE
115 0 : FD_COMPILER_MFENCE();
116 0 : vv_t seq_sz = vv( seq, sz );
117 0 : _mm_store_si128( &buf->seq_sz, seq_sz );
118 0 : FD_COMPILER_MFENCE();
119 : # else
120 : buf->sz = sz;
121 : FD_COMPILER_MFENCE();
122 : buf->seq = seq;
123 : FD_COMPILER_MFENCE();
124 : # endif
125 0 : }
126 :
127 : ulong
128 : fd_dbl_buf_read( fd_dbl_buf_t * buf,
129 : void * obj,
130 0 : ulong * opt_seqp ) {
131 0 : ulong _seq[1];
132 0 : ulong * seqp = opt_seqp ? opt_seqp : _seq;
133 0 : ulong sz;
134 0 : do {
135 0 : sz = fd_dbl_buf_try_read( buf, obj, seqp );
136 0 : } while( FD_UNLIKELY( sz==ULONG_MAX ) );
137 0 : return sz;
138 0 : }
|