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 12 : #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 25 : fd_fseq_align( void ) { 21 25 : return FD_FSEQ_ALIGN; 22 25 : } 23 : 24 : ulong 25 0 : fd_fseq_footprint( void ) { 26 0 : return FD_FSEQ_FOOTPRINT; 27 0 : } 28 : 29 : void * 30 : fd_fseq_new( void * shmem, 31 12 : ulong seq0 ) { 32 : 33 12 : if( FD_UNLIKELY( !shmem ) ) { 34 0 : FD_LOG_WARNING(( "NULL shmem" )); 35 0 : return NULL; 36 0 : } 37 : 38 12 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_fseq_align() ) ) ) { 39 0 : FD_LOG_WARNING(( "misaligned shmem" )); 40 0 : return NULL; 41 0 : } 42 : 43 12 : fd_fseq_shmem_t * fseq = (fd_fseq_shmem_t *)shmem; 44 : 45 12 : memset( fseq, 0, FD_FSEQ_FOOTPRINT ); 46 : 47 12 : fseq->seq0 = seq0; 48 12 : fseq->seq = seq0; 49 : 50 12 : FD_COMPILER_MFENCE(); 51 12 : FD_VOLATILE( fseq->magic ) = FD_FSEQ_MAGIC; 52 12 : FD_COMPILER_MFENCE(); 53 : 54 12 : return shmem; 55 12 : } 56 : 57 : ulong * 58 12 : fd_fseq_join( void * shfseq ) { 59 : 60 12 : if( FD_UNLIKELY( !shfseq ) ) { 61 0 : FD_LOG_WARNING(( "NULL shfseq" )); 62 0 : return NULL; 63 0 : } 64 : 65 12 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfseq, fd_fseq_align() ) ) ) { 66 0 : FD_LOG_WARNING(( "misaligned shfseq" )); 67 0 : return NULL; 68 0 : } 69 : 70 12 : fd_fseq_shmem_t * fseq = (fd_fseq_shmem_t *)shfseq; 71 : 72 12 : if( FD_UNLIKELY( fseq->magic!=FD_FSEQ_MAGIC ) ) { 73 0 : FD_LOG_WARNING(( "bad magic" )); 74 0 : return NULL; 75 0 : } 76 : 77 12 : return &fseq->seq; 78 12 : } 79 : 80 : void * 81 0 : fd_fseq_leave( ulong const * fseq ) { 82 : 83 0 : if( FD_UNLIKELY( !fseq ) ) { 84 0 : FD_LOG_WARNING(( "NULL or bad shfseq" )); 85 0 : return NULL; 86 0 : } 87 : 88 0 : return (void *)(fseq-2); 89 0 : } 90 : 91 : void * 92 0 : fd_fseq_delete( void * shfseq ) { 93 : 94 0 : if( FD_UNLIKELY( !shfseq ) ) { 95 0 : FD_LOG_WARNING(( "NULL shfseq" )); 96 0 : return NULL; 97 0 : } 98 : 99 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shfseq, fd_fseq_align() ) ) ) { 100 0 : FD_LOG_WARNING(( "misaligned shfseq" )); 101 0 : return NULL; 102 0 : } 103 : 104 0 : fd_fseq_shmem_t * fseq = (fd_fseq_shmem_t *)shfseq; 105 : 106 0 : if( FD_UNLIKELY( fseq->magic!=FD_FSEQ_MAGIC ) ) { 107 0 : FD_LOG_WARNING(( "bad magic" )); 108 0 : return NULL; 109 0 : } 110 : 111 0 : FD_COMPILER_MFENCE(); 112 0 : FD_VOLATILE( fseq->magic ) = 0UL; 113 0 : FD_COMPILER_MFENCE(); 114 : 115 0 : return (void *)fseq; 116 0 : } 117 :