Line data Source code
1 : #include "fd_vinyl_cq.h" 2 : 3 : ulong 4 30 : fd_vinyl_cq_align( void ) { 5 30 : return alignof(fd_vinyl_cq_t); 6 30 : } 7 : 8 : ulong 9 18 : fd_vinyl_cq_footprint( ulong comp_cnt ) { 10 18 : if( FD_UNLIKELY( !((4UL<=comp_cnt) & (comp_cnt<(1UL<<63)/sizeof(fd_vinyl_comp_t)) & fd_ulong_is_pow2( comp_cnt )) ) ) return 0UL; 11 6 : return fd_ulong_align_up( sizeof(fd_vinyl_cq_t) + comp_cnt*sizeof(fd_vinyl_comp_t), alignof(fd_vinyl_cq_t) ); /* no overflow */ 12 18 : } 13 : 14 : void * 15 : fd_vinyl_cq_new( void * shmem, 16 12 : ulong comp_cnt ) { 17 12 : fd_vinyl_cq_t * cq = (fd_vinyl_cq_t *)shmem; 18 : 19 12 : if( FD_UNLIKELY( !cq ) ) { 20 3 : FD_LOG_WARNING(( "NULL shmem")); 21 3 : return NULL; 22 3 : } 23 : 24 9 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)cq, fd_vinyl_cq_align() ) ) ) { 25 3 : FD_LOG_WARNING(( "bad align")); 26 3 : return NULL; 27 3 : } 28 : 29 6 : ulong footprint = fd_vinyl_cq_footprint( comp_cnt ); 30 6 : if( FD_UNLIKELY( !footprint) ) { 31 3 : FD_LOG_WARNING(( "bad comp_cnt")); 32 3 : return NULL; 33 3 : } 34 : 35 3 : memset( cq, 0, footprint ); 36 : 37 3 : cq->comp_cnt = comp_cnt; 38 3 : cq->seq = 0UL; 39 : 40 3 : fd_vinyl_comp_t * comp = fd_vinyl_cq_comp( cq ); 41 : 42 24579 : for( ulong seq=0UL; seq<comp_cnt; seq++ ) comp[ seq ].seq = seq - 1UL; /* Just before the next seq to be written to this entry */ 43 : 44 3 : FD_COMPILER_MFENCE(); 45 3 : cq->magic = FD_VINYL_CQ_MAGIC; 46 3 : FD_COMPILER_MFENCE(); 47 : 48 3 : return cq; 49 6 : } 50 : 51 : fd_vinyl_cq_t * 52 12 : fd_vinyl_cq_join ( void * shcq ) { 53 12 : fd_vinyl_cq_t * cq = (fd_vinyl_cq_t *)shcq; 54 : 55 12 : if( FD_UNLIKELY( !cq ) ) { 56 3 : FD_LOG_WARNING(( "NULL shcq")); 57 3 : return NULL; 58 3 : } 59 : 60 9 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)cq, fd_vinyl_cq_align() ) ) ) { 61 3 : FD_LOG_WARNING(( "bad align")); 62 3 : return NULL; 63 3 : } 64 : 65 6 : if( FD_UNLIKELY( cq->magic!=FD_VINYL_CQ_MAGIC ) ) { 66 3 : FD_LOG_WARNING(( "bad magic")); 67 3 : return NULL; 68 3 : } 69 : 70 3 : return (fd_vinyl_cq_t *)shcq; 71 6 : } 72 : 73 : void * 74 6 : fd_vinyl_cq_leave( fd_vinyl_cq_t * cq ) { 75 : 76 6 : if( FD_UNLIKELY( !cq ) ) { 77 3 : FD_LOG_WARNING(( "NULL cq")); 78 3 : return NULL; 79 3 : } 80 : 81 3 : return cq; 82 6 : } 83 : 84 : void * 85 12 : fd_vinyl_cq_delete( void * shcq ) { 86 12 : fd_vinyl_cq_t * cq = (fd_vinyl_cq_t *)shcq; 87 : 88 12 : if( FD_UNLIKELY( !cq ) ) { 89 3 : FD_LOG_WARNING(( "NULL shcq")); 90 3 : return NULL; 91 3 : } 92 : 93 9 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)cq, fd_vinyl_cq_align() ) ) ) { 94 3 : FD_LOG_WARNING(( "bad align")); 95 3 : return NULL; 96 3 : } 97 : 98 6 : if( FD_UNLIKELY( cq->magic!=FD_VINYL_CQ_MAGIC ) ) { 99 3 : FD_LOG_WARNING(( "bad magic")); 100 3 : return NULL; 101 3 : } 102 : 103 3 : FD_COMPILER_MFENCE(); 104 3 : cq->magic = 0UL; 105 3 : FD_COMPILER_MFENCE(); 106 : 107 3 : return cq; 108 6 : }