I’ve been working on making the tests pass.
Everything went fine until I came to the penultimate test, ringbuffer writes.
This fails. It’s a peculiar failure; when we come to get a write element, we find both the freelist and the queue are empty. This is in this test impossible – there are 100,000 elements per thread, each thread can at most have one element taken out of the ringbuffer, the balance of the elements will either be in the freelist or the queue. So what gives?
Turns out I had forgotten how the queue works.
The queue has a dummy element. It’s not a static dummy element, though; what it is, is that the element pointed to by the dequeue pointer has been emptied already of its user data – when you perform a dequeue, you get the user data from dequeue->next, not from dequeue itself.
element1 – element2
element1 is the dummy – his user data has already been returned to the user; when we dequeue, we’ll get the user data from element2.
Now, the problem is that for the ringbuffer, I have in each ringbuffer element a queue_element; and when I init the queue, I pass in an extra element, to be the initial dummy.
So I assume when I dequeued, the queue element I obtained in the ringbuffer would be the queue element used for that ringbuffer element. Problem is, it isn’t! it’s the queue element *prior* in the queue!