I am implementing single-producer,single-consumer ptr_ring buffers. Are there really data races within this linux driver code ?
I asked this because ThreadSanitizer gives me error and my system crashes after I started the ptr_ring code implementation.
Code:
inline int push_circ_queue(struct ptr_ring * buffer, unsigned int val1, unsigned int val2)
{
int push_status;
if (!ptr_ring_full_any(buffer)) // if (not full)
{
// assigns the two values in each item
item_push[buffer->producer].val1 = val1;
item_push[buffer->producer].val2 = val2;
DEBUG_MSG(KERN_INFO "buffer->producer = %u , item_push[buffer->producer].val1 = %u , item_push[buffer->producer].val2 = %u\n", buffer->producer, item_push[buffer->producer].val1, item_push[buffer->producer].val2);
/* insert one item into the buffer */
push_status = ptr_ring_produce_any(buffer, &item_push[buffer->producer]);
DEBUG_MSG(KERN_INFO "push_status = %u\n", push_status);
return 0;
}
else return 1; // full, not enough buffer space
}
inline int pop_circ_queue(struct ptr_ring * buffer, unsigned int * val1, unsigned int * val2)
{
unsigned int head;
unsigned int tail;
/* Read index before reading contents at that index. */
head = buffer->consumer_head;
tail = buffer->consumer_tail;
if (!ptr_ring_empty_any(buffer)) // if (not empty)
{
DEBUG_MSG(KERN_INFO "Before pop, head = %u , tail = %u\n", head, tail);
/* extract one item from the buffer */
item_pop[tail] = *((struct item *)ptr_ring_consume_any(buffer));
// reassigns the two values in each item
*val1 = item_pop[tail].val1;
*val2 = item_pop[tail].val2;
DEBUG_MSG(KERN_INFO "val1 = %u , val2 = %u\n", *val1, *val2);
DEBUG_MSG(KERN_INFO "After pop, head = %u , tail = %u\n", buffer->consumer_head, buffer->consumer_tail);
return 0;
}
else return 1; // empty, nothing to pop from the ring
}