gpt4 book ai didi

c - 增加指针的 LSB 位但保留其余部分(硬编码环形缓冲区大小)

转载 作者:行者123 更新时间:2023-11-30 17:29:59 25 4
gpt4 key购买 nike

我尝试编写一个非常紧凑的环形缓冲区。缓冲区保存 2^X 个值(X:1-7)我需要的是增加 X 位(LSB)但保留其余变量。我有一个解决方案,但我不知道这是否有效(之前从未修改过指针地址)并且它不是那么紧凑。知道如何改进吗?

        // hardcoded ringbuffersize for better ram usage
// this frees us 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 we 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 all LSB bits
Buffer->In >>= LIGHTWEIGHT_RING_BUFFER_BITS;
Buffer->In <<= LIGHTWEIGHT_RING_BUFFER_BITS;
// save the LSB bits + 1
Buffer->In |= ++pointermask & (LIGHTWEIGHT_RING_BUFFER_SIZE - 1)

Buffer->Count++;

最佳答案

这是一个简单的环形缓冲区实现的样子。环形缓冲区的大小由 MASK 确定。 MASK 的值必须为 2n-1,其中 n <= 8 。对于 256 字节环形缓冲区,您可以完全消除掩码。

#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 the ring buffer is full
// the argument is the byte that is to be stored in the 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 a byte from the ring buffer, or 0 if the buffer is empty
// the caller is responsible for making sure the buffer is not empty before calling this 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 the number of items currently in the ring buffer
int itemCountInRingBuffer( stRingBuffer *buffer )
{
return( (buffer->head - buffer->tail) & MASK );
}

int main( void )
{
uint8_t data = 31;

// move the head and tail to a non-zero location in the buffer for testing
// this demonstrates proper handling of index wrap-around
ringBuffer.head = 5;
ringBuffer.tail = 5;

// fill the buffer up
while ( WriteToRingBuffer( &ringBuffer, data ) )
{
printf( "Wrote %u, buffer now has %d items\n", data, itemCountInRingBuffer( &ringBuffer ) );
data++;
}

// empty the buffer out
while ( ringBuffer.tail != ringBuffer.head )
{
data = ReadFromRingBuffer( &ringBuffer );
printf( "Read %u, there are %d items remaining\n", data, itemCountInRingBuffer( &ringBuffer ) );
}
}

请注意,如果您打算使用环形缓冲区在线程之间传递数据,或者从中断例程到后台代码传递数据,那么您要么需要使用适当的锁定机制,要么需要成为无锁多线程方面的专家- 线程。

关于c - 增加指针的 LSB 位但保留其余部分(硬编码环形缓冲区大小),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25371105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com