Skip to content

Instantly share code, notes, and snippets.

@anhldbk
Created July 5, 2017 03:53
Show Gist options
  • Save anhldbk/1aafdfc086e8f718202a0f5f1159b39c to your computer and use it in GitHub Desktop.
Save anhldbk/1aafdfc086e8f718202a0f5f1159b39c to your computer and use it in GitHub Desktop.
Atomic references
#include <atomic>
#include <iostream>
#include <thread>
#include <stdint.h>
using namespace std;
void run_in_pool(std::function<void() > routine, uint8_t max_thread = 4) {
std::thread modifiers[max_thread];
uint8_t i;
for (i = 0; i < max_thread; i++) {
modifiers[i] = std::thread(routine);
}
for (i = 0; i < max_thread; i++) {
modifiers[i].join();
}
}
struct List {
uint32_t capacity;
static List* create_ptr(uint32_t capacity) {
uint32_t* buffer = new uint32_t[List::guess_size(capacity)];
List* raw_ptr = (List*) buffer;
raw_ptr->capacity = capacity;
return raw_ptr;
}
uint32_t* get_data() {
return (uint32_t*) (this +sizeof (List));
}
uint32_t get_size() {
return this->capacity + sizeof (List);
}
static uint32_t guess_size(uint32_t capacity) {
return capacity + sizeof (List);
}
void release() {
delete[] this;
}
atomic<uint32_t>& get(uint32_t index) throw (invalid_argument) {
if (index >= this->capacity) {
throw invalid_argument("Invalid index");
}
atomic<uint32_t>* data_ptr = (atomic<uint32_t>*)this->get_data();
return data_ptr[index];
}
};
int main() {
List* list_ptr = List::create_ptr(3);
const uint32_t loop = 50, threads = 5;
auto routine = [&]() {
atomic<uint32_t>& ref = list_ptr->get(0);
uint32_t expected, desired;
bool exchanged;
for (uint32_t i = 0; i < loop; i++) {
do {
expected = ref;
desired = expected + 1;
} while (!ref.compare_exchange_strong(expected, desired));
}
};
run_in_pool(routine, threads);
cout << "Value is: " << unsigned(list_ptr->get(0)) << " = " << loop * threads << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment