Line data Source code
1 : #include "fd_fseq.h" 2 : 3 : /* fd_fseq_shmem_t specifies the layout of a shared memory region 4 : containing an fseq */ 5 : 6 54 : #define FD_FSEQ_MAGIC (0xf17eda2c37f5ec00UL) /* firedancer fseq ver 0 */ 7 : 8 : struct __attribute__((aligned(FD_FSEQ_ALIGN))) fd_fseq_shmem { 9 : ulong magic; /* == FD_FSEQ_MAGIC */ 10 : ulong seq0; /* Initial sequence number */ 11 : ulong seq; /* Current sequence number */ 12 : /* Padding to FD_FSEQ_APP_ALIGN here */ 13 : /* FD_FSEQ_APP_FOOTPRINT for app region here */ 14 : /* Padding to FD_FSEQ_ALIGN here */ 15 : }; 16 : 17 : typedef struct fd_fseq_shmem fd_fseq_shmem_t; 18 : 19 : ulong 20 156 : fd_fseq_align( void ) { 21 156 : return FD_FSEQ_ALIGN; 22 156 : } 23 : 24 : ulong 25 156 : fd_fseq_footprint( void ) { 26 156 : return FD_FSEQ_FOOTPRINT; 27 156 : } 28 : 29 : void * 30 : fd_fseq_new( void * shmem, 31 60 : ulong seq0 ) { 32 : 33 60 : if( FD_UNLIKELY( !shmem ) ) { 34 3 : FD_LOG_WARNING(( "NULL shmem" )); 35 3 : return NULL; 36 3 : } 37 : 38 57 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_fseq_align() ) ) ) { 39 3 : FD_LOG_WARNING(( "misaligned shmem" )); 40 3 : return NULL; 41 3 : } 42 : 43 54 : fd_fseq_shmem_t * fseq = (fd_fseq_shmem_t *)shmem; 44 : 45 54 : memset( fseq, 0, FD_FSEQ_FOOTPRINT ); 46 : 47 54 : fseq->seq0 = seq0; 48 54 : fseq->seq = seq0; 49 : 50 54 : FD_COMPILER_MFENCE(); 51 54 : FD_VOLATILE( fseq->magic ) = FD_FSEQ_MAGIC; 52 54 : FD_COMPILER_MFENCE(); 53 : 54 54 : return shmem; 55 57 : } 56 : 57 : ulong * 58 210 : fd_fseq_join( void * shfseq ) { 59 : 60 210 : if( FD_UNLIKELY( !shfseq ) ) { 61 3 : FD_LOG_WARNING(( "NULL shfseq" )); 62 3 : return NULL; 63 3 : } 64 : 65 207 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfseq, fd_fseq_align() ) ) ) { 66 3 : FD_LOG_WARNING(( "misaligned shfseq" )); 67 3 : return NULL; 68 3 : } 69 : 70 204 : fd_fseq_shmem_t * fseq = (fd_fseq_shmem_t *)shfseq; 71 : 72 204 : if( FD_UNLIKELY( fseq->magic!=FD_FSEQ_MAGIC ) ) { 73 3 : FD_LOG_WARNING(( "bad magic" )); 74 3 : return NULL; 75 3 : } 76 : 77 201 : return &fseq->seq; 78 204 : } 79 : 80 : void * 81 108 : fd_fseq_leave( ulong const * fseq ) { 82 : 83 108 : if( FD_UNLIKELY( !fseq ) ) { 84 3 : FD_LOG_WARNING(( "NULL or bad shfseq" )); 85 3 : return NULL; 86 3 : } 87 : 88 105 : return (void *)(fseq-2); 89 108 : } 90 : 91 : void * 92 15 : fd_fseq_delete( void * shfseq ) { 93 : 94 15 : if( FD_UNLIKELY( !shfseq ) ) { 95 3 : FD_LOG_WARNING(( "NULL shfseq" )); 96 3 : return NULL; 97 3 : } 98 : 99 12 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfseq, fd_fseq_align() ) ) ) { 100 3 : FD_LOG_WARNING(( "misaligned shfseq" )); 101 3 : return NULL; 102 3 : } 103 : 104 9 : fd_fseq_shmem_t * fseq = (fd_fseq_shmem_t *)shfseq; 105 : 106 9 : if( FD_UNLIKELY( fseq->magic!=FD_FSEQ_MAGIC ) ) { 107 3 : FD_LOG_WARNING(( "bad magic" )); 108 3 : return NULL; 109 3 : } 110 : 111 6 : FD_COMPILER_MFENCE(); 112 6 : FD_VOLATILE( fseq->magic ) = 0UL; 113 6 : FD_COMPILER_MFENCE(); 114 : 115 6 : return (void *)fseq; 116 9 : } 117 :