Lock free MPMC Ring buffer implementation in C I have written a lock free MPMC FIFO in C based on a ring buffer. It uses gcc's atomic built-ins to achieve thread safety. The queue is designed to return -1 if it's full on enqueue or empty on dequeue. 

After some feedback, I've changed by design. I have tested this code to work, but testing multithreaded code is hardly enough to prove it's correct. 

struct queue
{
    void** buf;
    size_t num;
    uint64_t writePos;
    uint64_t readPos;
};

queue_t* createQueue(size_t num)
{
    struct queue* new = xmalloc(sizeof(*new));
    new-&gt;buf = xmalloc(sizeof(void*) * num);
    memset(new-&gt;buf, 0, sizeof(void*)*num);
    new-&gt;readPos = 0;
    new-&gt;writePos = 0;
    new-&gt;num = num;
    return new;
}

void destroyQueue(queue_t* queue)
{
    if(queue)
    {
        xfree(queue-&gt;buf);
        xfree(queue);
    }
}

int enqueue(queue_t* queue, void* item)
{
    for(int i = 0; i &lt; kNumTries; i++)
    {
        if(__sync_bool_compare_and_swap(&amp;queue-&gt;buf[queue-&gt;writePos % queue-&gt;num], NULL, item))
        {
            __sync_fetch_and_add(&amp;queue-&gt;writePos, 1);
            return 0;
        }
    }
    return -1;
}

void* dequeue(queue_t* queue)
{
    for(int i = 0; i &lt; kNumTries; i++)
    {
        void* value = queue-&gt;buf[queue-&gt;readPos % queue-&gt;num];
        if(value &amp;&amp; __sync_bool_compare_and_swap(&amp;queue-&gt;buf[queue-&gt;readPos % queue-&gt;num], value, NULL))
        {
            __sync_fetch_and_add(&amp;queue-&gt;readPos, 1);
            return value;
        }
    }
    return NULL;
}


(link to the previous iteration)
Did you test it?  

I think you have a problem if a thread calls enqueue and is interrupted
just before the memcpy, having calculated pos to be slot-1.  If another
thread now calls enqueue and completes it will write to slot-2 and increment the pendingRead counter, leaving
slot-1 still unwritten.  If a third thread now reads before the first thread
can complete its write, the reader will read from the unwritten slot-1.  This
is becase the second thread correctly set the queue to say there is a pending
read (slot-2) but dequeue assumes the data must be in the next available
slot according to readPos. 

A few other comments:


queue_t is defined (elsewhere) as a pointer type. I prefer pointers to be
explicit.
You have mixed use of struct queue * and queue_t
Return from malloc is not checked.
buf in struct queue should be void* not char **
Why are writePos and readPos of type uint64_t and not size_t?
After all, num is size_t.  Why the difference?
Loss of precision assigning num in createQueue