Skip to content

Instantly share code, notes, and snippets.

@leon123858
Created September 4, 2021 08:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leon123858/6950c18bc812546aedfdb17022054256 to your computer and use it in GitHub Desktop.
Save leon123858/6950c18bc812546aedfdb17022054256 to your computer and use it in GitHub Desktop.
atomic stack
#include <iostream>
#include <atomic>
#include <thread>
#define THREAD_N 100
#define ELEMENT_N 1000
using namespace std;
static atomic_int inserts = 0;
static atomic_int deletes = 0;
class node {
public:
node* next;
int value;
node(int value) {
this->value = value;
next = nullptr;
inserts.fetch_add(1);
}
};
class stack {
public:
atomic<node*> head;
stack() {
head = NULL;
}
node* getHead() {
return head.load();
}
void pushNode(int value) {
node* n = new node(value);
do {
n->next = head.load();
} while (!head.compare_exchange_weak(n->next, n));
/*
* 比較 head == n -> next 就令 head = n
* 若 head != n , 改令 n -> next = head 然後在做下一輪, 做到一樣為止
*/
}
void popNode() {
start:
node* curHead = head.load();
do {
if (curHead == nullptr)
goto start; //一定要刪到, 不放棄
} while (!head.compare_exchange_weak(curHead, curHead->next));
deletes.fetch_add(1);
}
~stack() {
node* delPtr;
for (node* ptr = this->getHead(); ptr;)
{
delPtr = ptr;
ptr = ptr->next;
delete delPtr;
}
}
};
static atomic <int> insertCount = 0;
void insertNode(stack* stack) {
for (int i = 0; i < ELEMENT_N; i++) {
stack->pushNode(insertCount.fetch_add(1));
}
}
void deleteNode(stack* stack) {
for (int i = 0; i < ELEMENT_N; i++) {
stack->popNode();
}
}
int main()
{
std::cout << "Start!\n";
stack* testStack = new stack();
thread threads_insert[THREAD_N];
thread threads_delete[THREAD_N];
for (int i = 0; i < THREAD_N; i++) {
threads_insert[i] = thread(insertNode, testStack);
}
for (int i = 0; i < THREAD_N; i++) {
threads_delete[i] = thread(deleteNode, testStack);
}
for (int i = 0; i < THREAD_N; i++) {
threads_insert[i].join();
threads_delete[i].join();
}
int count = 0;
cout << "finally" << endl;
for (node* ptr = testStack->getHead(); ptr; ptr = ptr->next)
count++;
delete testStack;
cout << "inserts:" << atomic_load(&inserts) << " count" << count << endl;
cout << "delete: " << atomic_load(&deletes) << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment