Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Example of stdatomic incrementing/decrementing a counter and setting a boolean flag when a data value is written, also example of xor on register
- * also shows how to wait for condition variable
- */
- #include <stdio.h>
- #include <stdlib.h>
- // you define NO_LOCK if you do not have std atomic
- // #define NO_LOCK
- #ifndef NO_LOCK
- #include <stdatomic.h>
- #include <threads.h>
- #endif
- #include <atomic>
- #include <cassert>
- #include <iostream>
- //#include <thread>
- #include <bitset>
- // set this data with a boolena lock flag between threads
- int data = 0;
- std::atomic<bool> ready(false);
- // define the number of times the iterating thread operates
- const int loop_iter = 50000;
- #define NR_THREADS 2
- int value = 0b1011;
- std::atomic_ref<int> x{value};
- // define a condition variable which triggers a second thread to then run
- std::mutex mtx;
- // create a function which will increment the count variable
- // it should wait for the condition variable set in the decrement function
- int func_thread(void *arg)
- {
- int i;
- #ifndef NO_LOCK
- atomic_int *count = (atomic_int *) arg;
- for (i = 0; i < loop_iter; i++) {
- atomic_fetch_add_explicit(count, 1, memory_order_seq_cst);
- }
- #else
- int *count = (int *) arg;
- for (i = 0; i < loop_iter; i++) {
- (*count)++;
- }
- #endif
- x.fetch_xor(0b1110);
- std::cout << std::bitset<4>(value).to_string() << std::endl;
- return 0;
- }
- int func_dec_thread(void *arg)
- {
- int i;
- #ifndef NO_LOCK
- atomic_int *count = (atomic_int *) arg;
- for (i = 0; i < loop_iter; i++) {
- atomic_fetch_sub_explicit(count, 1, memory_order_seq_cst);
- }
- #else
- int *count = (int *) arg;
- for (i = 0; i < loop_iter; i++) {
- (*count)--;
- }
- #endif
- return 0;
- }
- // set a value
- int producer(void *arg) {
- int *d_in = (int *) arg;
- data = *d_in;
- ready.store(true, std::memory_order_release); // Set flag
- return 0;
- }
- // check value is set to value expected
- int consumer(void *arg) {
- int *d_in = (int *) arg;
- while (!ready.load(std::memory_order_acquire));
- assert(data == *d_in);
- return 0;
- }
- int main(void)
- {
- thrd_t th;
- int set_val = 230;
- thrd_start_t func_set = producer;
- // start producer consumer tasks
- if (thrd_create(&th, func_set, &set_val) != thrd_success) {
- fprintf(stderr, "Error: thrd_create() on producer\n");
- exit(1);
- }
- thrd_t cons;
- thrd_start_t func_set2 = consumer;
- if (thrd_create(&cons, func_set2, &set_val) != thrd_success) {
- fprintf(stderr, "Error: thrd_create() on consumer\n");
- exit(1);
- }
- // now wait on completion the producer consumer tasks uses an atomic bool as the mutex
- if (thrd_join(th, NULL) != thrd_success) {
- fprintf(stderr, "Error: thrd_join() on producer\n");
- exit(1);
- }
- if (thrd_join(cons, NULL) != thrd_success) {
- fprintf(stderr, "Error: thrd_join() on consumer\n");
- exit(1);
- }
- thrd_t thrs[NR_THREADS];
- int i;
- thrd_start_t func = func_thread;
- #ifndef NO_LOCK
- volatile atomic_int count = 0;
- volatile atomic_int c_down = 990;
- #else
- volatile int count = 0;
- volatile int c_down = 990;
- #endif
- thrd_t thrs_d;
- thrd_start_t func_d = func_dec_thread;
- // start the count-up threads
- for (i = 0; i < NR_THREADS; i++) {
- if (thrd_create(&thrs[i], func, (void*)&count) != thrd_success) {
- fprintf(stderr, "Error: thrd_create() on increment\n");
- exit(1);
- }
- }
- printf("count up = %d\n", (int)count);
- // start the count-down threads
- if (thrd_create(&thrs_d, func_d, (void*)&c_down) != thrd_success) {
- fprintf(stderr, "Error: thrd_create() on decrement\n");
- exit(1);
- }
- printf("count down = %d\n", (int)c_down);
- printf("count up = %d\n", (int)count);
- // now join the threads on completion
- if (thrd_join(thrs_d, NULL) != thrd_success) {
- fprintf(stderr, "Error: thrd_join() on decrement\n");
- exit(1);
- }
- for (i = 0; i < NR_THREADS; i++) {
- if (thrd_join(thrs[i], NULL) != thrd_success) {
- fprintf(stderr, "Error: thrd_join() on increment\n");
- exit(2);
- }
- }
- printf("count up = %d\n", (int)count);
- printf("count down = %d\n", (int)c_down);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement