#include <iostream>
#include <atomic>
#include <memory>
template<typename T>
class LockFreeQueue {
public:
struct CountedNode;
private:
std::atomic<CountedNode> head;
public:
struct Node{
explicit Node(const T& d) : next(CountedNode()), data(std::make_shared<T>(d)), node_counter(0) { }
std::atomic<CountedNode> next;
std::shared_ptr<T> data;
std::atomic<unsigned> node_counter;
};
struct CountedNode {
CountedNode() noexcept : node(nullptr), counter(0) {}
explicit CountedNode( const T& data) noexcept : node(new Node(data) /* $4 */), counter(0) {}
Node* node;
int counter;
};
void push( const T& data)
{
CountedNode new_node(data), curr, incrementedNext, next /*($2) */;
CountedNode empty; /*($3) */
if (head.compare_exchange_strong(empty, new_node)) std::cout << "EQUALS\n"; // $1
else std::cout << "NOT EQUALS\n";
if (head.compare_exchange_strong(next, new_node)) std::cout << "EQUALS\n"; // $1
else std::cout << "NOT EQUALS\n";
}
};
int main() {
LockFreeQueue<int> Q;
Q.push(2);
return 0;
}
int main(){
LockFreeQueue<int> Q;
Q.push(2);
return 0;
}
Ok. It compiled and executed without error. But, there is still problem, which I described below.
http://coliru.stacked-crooked.com/a/1fe71fafc5dde518
On my eye, result it is not expected: NOTEQUALS EQUALS
I have a wild problem with above piece of code.
Especially, the comparison in the line $1 makes me a problem. I mean, this comparison always returns false though it should returns true at the first time.
I was confused so I look into memory for empty and head and actually they are different. head is equal to 0x00000000 0x00000000 0x00000000 0x00000000 ( when it comes to bytes) and it seems to be OK. But empty is equal to:
0x00000000 0x00000000 0x00000000 0x7f7f7f7f7f. What is more interesting next in the $2 is equal to 0x00000000 0x00000000 0x00000000 0x00000000 so in fact, it is equals to head. But, for example, curr, incrementedNext are equal to 0x00000000 0x00000000 0x00000000 0x7f7f7f7f7f.
So the behaviour of that is undeterministic so I suppose any undefined behaviour, but why? What I do not correctly, please explain me this behaviour.
P.S. I know about memory leak in the $4 but now I'm ignoring it.
I compiled it with:
g++ -latomic main.cpp -std=c++14.
My version of gcc is 6.1.0. I tested on gcc 5.1.0 as well. The result is same.
The link to the source created by @PeterCordes: https://godbolt.org/g/X02QV8