c - Increase a pointer's LSB bits but keep the rest (hardcoded ringbuffer size) -


i try code compact ringbuffer. buffer holds 2^x values (x: 1-7) need increase x bits (lsb) keep rest of variables. ive got solution dont know if works (never modified pointer address before) , not compact. idea how improve this?

        // hardcoded ringbuffersize better ram usage         // frees out, start, end, size variables         // 7 == 128, 6 == 64         #define lightweight_ring_buffer_bits 7         #define lightweight_ring_buffer_size (1<<lightweight_ring_buffer_bits)         // thatswhy cant use 256 buffer size          #define lightweight_ring_buffer_disabled lightweight_ring_buffer_size+1         // save new data         *buffer->in = data;          // save lsb bits         uint8_t pointermask = buffer->in;         // discard lsb bits         buffer->in >>= lightweight_ring_buffer_bits;         buffer->in <<= lightweight_ring_buffer_bits;         // save lsb bits + 1         buffer->in |= ++pointermask & (lightweight_ring_buffer_size - 1)          buffer->count++; 

here's simple ring buffer implementation looks like. size of ring buffer determined mask. value mask must 2n-1, n <= 8. 256 byte ring buffer, can eliminate mask altogether.

#include <stdio.h> #include <stdbool.h> #include <stdint.h>  #define mask 7  typedef struct {     uint8_t head;     uint8_t tail;     uint8_t data[mask + 1]; }     stringbuffer;  stringbuffer ringbuffer = { 0, 0 };  // returns true if successful, false if ring buffer full // argument byte stored in buffer bool writetoringbuffer( stringbuffer *buffer, uint8_t data ) {     uint8_t nextheadvalue = (buffer->head + 1) & mask;     if ( nextheadvalue == buffer->tail )         return( false );      buffer->data[buffer->head] = data;     buffer->head = nextheadvalue;     return( true ); }  // returns byte ring buffer, or 0 if buffer empty // caller responsible making sure buffer not empty before calling function uint8_t readfromringbuffer( stringbuffer *buffer ) {     uint8_t data = 0;      if ( buffer->tail != buffer->head )     {         data = buffer->data[buffer->tail];         buffer->tail = (buffer->tail + 1) & mask;     }      return( data ); }  // returns number of items in ring buffer int itemcountinringbuffer( stringbuffer *buffer ) {     return( (buffer->head - buffer->tail) & mask ); }  int main( void ) {     uint8_t data = 31;      // move head , tail non-zero location in buffer testing     // demonstrates proper handling of index wrap-around     ringbuffer.head = 5;     ringbuffer.tail = 5;      // fill buffer     while ( writetoringbuffer( &ringbuffer, data ) )     {         printf( "wrote %u, buffer has %d items\n", data, itemcountinringbuffer( &ringbuffer ) );         data++;     }      // empty buffer out     while ( ringbuffer.tail != ringbuffer.head )     {         data = readfromringbuffer( &ringbuffer );         printf( "read %u, there %d items remaining\n", data, itemcountinringbuffer( &ringbuffer ) );     } } 

note if intend use ring buffer pass data between threads, or interrupt routine background code, either need use appropriate locking mechanisms, or need become expert in lockless multi-threading.


Comments

Popular posts from this blog

java - How to specify maven bin in eclipse maven plugin? -

single sign on - Logging into Plone site with credentials passed through HTTP -

php - Why does AJAX not process login form? -