Line data Source code
1 : #include "fd_quic_stream.h" 2 : 3 : /* buffer helper functions */ 4 : /* fd_quic_buffer_store 5 : store data into circular buffer */ 6 : void 7 : fd_quic_buffer_store( fd_quic_buffer_t * buf, 8 : uchar const * data, 9 8552527 : ulong data_sz ) { 10 : /* do we have space to buffer data? */ 11 : /* see fd_quic_stream.h for invariants */ 12 8552527 : uchar * raw = buf->buf; 13 8552527 : ulong cap = buf->cap; 14 8552527 : ulong mask = cap - 1ul; 15 8552527 : ulong head = buf->head; 16 8552527 : ulong tail = buf->tail; 17 8552527 : ulong used = head - tail; 18 8552527 : ulong free = cap - used; 19 8552527 : ulong mtail = tail & mask; 20 8552527 : ulong mhead = head & mask; 21 : 22 : /* not enough room - caller responsible for checking available space */ 23 8552527 : if( data_sz > free ) { 24 0 : return; 25 0 : } 26 : 27 : /* two cases: 28 : 1. data fits within free contiguous space at m_head 29 : 2. data must be split 30 : 31 : used is in [tail,head) */ 32 : 33 8552527 : if( mhead >= mtail ) { 34 : /* free space split */ 35 8552527 : ulong end_sz = cap - mhead; 36 8552527 : if( data_sz <= end_sz ) { 37 : /* fits entirely into space at end of buffer */ 38 8552527 : fd_memcpy( raw + mhead, data, data_sz ); 39 8552527 : } else { 40 : /* must split between front and end of buffer */ 41 0 : fd_memcpy( raw + mhead, data, end_sz ); 42 0 : fd_memcpy( raw, data + end_sz, data_sz - end_sz ); 43 0 : } 44 8552527 : } else { 45 : /* contiguous space */ 46 0 : fd_memcpy( raw + mhead, data, data_sz ); 47 0 : } 48 : 49 8552527 : } 50 : 51 : /* fd_quic_buffer_load 52 : load data from circular buffer */ 53 : void 54 : fd_quic_buffer_load( fd_quic_buffer_t * buf, 55 : ulong offs, 56 : uchar * data, 57 17090693 : ulong data_sz ) { 58 17090693 : uchar * raw = buf->buf; 59 17090693 : ulong cap = buf->cap; 60 17090693 : ulong mask = cap - 1ul; 61 17090693 : ulong head = buf->head; 62 17090693 : ulong tail = offs; 63 17090693 : ulong mtail = tail & mask; 64 17090693 : ulong mhead = head & mask; 65 : 66 : /* caller responsible for checking operation valid */ 67 17090693 : if( FD_UNLIKELY( tail > head || offs < buf->tail ) ) return; 68 : 69 : /* two cases: 70 : 1. data fits within free contiguous space at m_tail 71 : 2. data is split 72 : 73 : used is in [tail,head) */ 74 : 75 17090693 : if( mtail >= mhead ) { 76 : /* free space split */ 77 6 : ulong end_sz = cap - mhead; 78 6 : if( data_sz <= end_sz ) { 79 : /* consists entirely of space at end of buffer */ 80 6 : fd_memcpy( data, raw + mtail, data_sz ); 81 6 : } else { 82 : /* split between front and end of buffer */ 83 0 : fd_memcpy( data, raw + mtail, end_sz ); 84 0 : fd_memcpy( data + end_sz, raw, data_sz - end_sz ); 85 0 : } 86 17090687 : } else { 87 : /* contiguous data */ 88 17090687 : fd_memcpy( data, raw + mtail, data_sz ); 89 17090687 : } 90 17090693 : } 91 : 92 : 93 : extern 94 : ulong 95 : fd_quic_stream_align( void ); 96 : 97 : ulong 98 1409241 : fd_quic_stream_footprint( ulong tx_buf_sz ) { 99 1409241 : ulong align = fd_quic_stream_align(); 100 1409241 : ulong offs = 0ul; 101 : 102 1409241 : ulong tx_ack_sz = tx_buf_sz >> 3ul; 103 1409241 : ulong align_stream_sz = fd_ulong_align_up( sizeof( fd_quic_stream_t ), align ); 104 1409241 : ulong align_tx_ack_sz = fd_ulong_align_up( tx_ack_sz, align ); 105 1409241 : ulong align_tx_buf_sz = fd_ulong_align_up( tx_buf_sz, align ); 106 : 107 1409241 : offs += align_stream_sz; /* space for stream instance */ 108 1409241 : offs += align_tx_buf_sz; /* space for tx_buf */ 109 1409241 : offs += align_tx_ack_sz; /* space for tx_ack */ 110 : 111 1409241 : return offs; 112 1409241 : } 113 : 114 : /* returns a newly initialized stream 115 : 116 : args 117 : mem the memory aligned to fd_quic_stream_align, and at least fd_quic_stream_footprint 118 : bytes 119 : tx_buf_sz the size of the tx buffer */ 120 : fd_quic_stream_t * 121 1395003 : fd_quic_stream_new( void * mem, fd_quic_conn_t * conn, ulong tx_buf_sz ) { 122 1395003 : ulong align = fd_quic_stream_align(); 123 : 124 1395003 : ulong tx_ack_sz = tx_buf_sz >> 3ul; 125 1395003 : ulong align_stream_sz = fd_ulong_align_up( sizeof( fd_quic_stream_t ), align ); 126 1395003 : ulong align_tx_buf_sz = fd_ulong_align_up( tx_buf_sz, align ); 127 1395003 : ulong align_tx_ack_sz = fd_ulong_align_up( tx_ack_sz, align ); 128 : 129 1395003 : ulong offs = 0; 130 1395003 : ulong base = (ulong)mem; 131 : 132 : /* allocate memory for the stream */ 133 1395003 : fd_quic_stream_t * stream = (fd_quic_stream_t*)mem; 134 : 135 1395003 : offs += align_stream_sz; 136 : 137 : /* allocate memory for the tx buffer */ 138 1395003 : stream->tx_buf.buf = (uchar*)( base + offs ); 139 1395003 : stream->tx_buf.cap = tx_buf_sz; 140 : 141 1395003 : offs += align_tx_buf_sz; 142 : 143 : /* allocate memory for the tx ack buffer */ 144 1395003 : stream->tx_ack = (uchar*)( base + offs ); 145 : 146 1395003 : offs += align_tx_ack_sz; 147 : 148 1395003 : if( offs != fd_quic_stream_footprint( tx_buf_sz ) ) { 149 0 : FD_LOG_ERR(( "fd_quic_stream_new : allocated size of stream does not match footprint" )); 150 0 : } 151 : 152 1395003 : stream->conn = conn; 153 1395003 : stream->stream_id = FD_QUIC_STREAM_ID_UNUSED; 154 : 155 : /* stream pointing to itself is not a member of any list */ 156 1395003 : stream->next = stream->prev = stream; 157 : 158 1395003 : return stream; 159 1395003 : } 160 : 161 : /* delete a stream 162 : 163 : args 164 : stream the stream to free */ 165 : void 166 0 : fd_quic_stream_delete( fd_quic_stream_t * stream ) { 167 : /* stream pointing to itself is not a member of any list */ 168 0 : stream->next = stream->prev = stream; 169 0 : stream->list_memb = FD_QUIC_STREAM_LIST_MEMB_NONE; 170 0 : } 171 : 172 : 173 : /* set stream context 174 : 175 : args 176 : stream the stream with which to associate the context 177 : context the user-defined context associated with the stream */ 178 : void 179 60000 : fd_quic_stream_set_context( fd_quic_stream_t * stream, void * context ) { 180 60000 : stream->context = context; 181 60000 : } 182 : 183 : 184 : /* get stream context 185 : 186 : args 187 : stream the stream from which to obtain the context 188 : 189 : returns 190 : context the user defined context associated with the stream */ 191 : void * 192 0 : fd_quic_stream_get_context( fd_quic_stream_t * stream ) { 193 0 : return stream->context; 194 0 : }