I am trying to implement a concurrent non-blocking queue where the tag is in the 16 most significant bits of the pointer. It follows this algorithm here: http://www.cs.rochester.edu/research/synchronization/pseudocode/queues.html
However, this algorithm assumes a pointer struct with a separate count variable for the tag (structure pointer_t {ptr: pointer to node_t, count: unsigned integer}). However, I have to do it with just the pointer like so:
template<class P>
struct pointer_t {
P* ptr;
//no uint to store the tag
P* address(){
return (P*)(ptr & 0x0000FFFFFFFFFFFF);
}
uint count(){
return ptr & 0xFFFF000000000000;
}
};
I have a couple of questions:
- How do I extract the count (16 most significant bits) of the pointer address and turn it into an
uintto return? Currently my count function just returns the MSBs and not theuint. - Is my address function correctly returning the 48 Least significant bits of the pointer?
- The compare and swap operation from the algorithm is given like so:
CAS(&tail.ptr->next, next, <node, next.count+1>)
How do I update both the address of tail and increment the count in one operation? I am required to use a CAS function already provided and is not visible to me. So I have to replace<node, next.count+1>with an operation that does both. I am assuming this also involves some bitwise operations.
I'd probably go the pointer route myself. you could even use this pointer to get the current count value and replace my #1 answer with
disclaimer: none of this is optimized, if you need to optimize for performance. there are definitely ways to make this better, but this is off the top of my head how i'd at least start to work out this problem