brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.3 KiB · 02499ef Raw
96 lines · cpp
1#include <chrono>2#include <condition_variable>3#include <cstdio>4#include <random>5#include <thread>6 7std::default_random_engine g_random_engine{std::random_device{}()};8std::uniform_int_distribution<> g_distribution{0, 3000000};9std::condition_variable g_condition_variable;10std::mutex g_mutex;11int g_count;12 13char *g_char_ptr = nullptr;14 15void16barrier_wait()17{18    std::unique_lock<std::mutex> lock{g_mutex};19    if (--g_count > 0)20        g_condition_variable.wait(lock);21    else22        g_condition_variable.notify_all();23}24 25void26do_bad_thing_with_location(char *char_ptr, char new_val)27{28    unsigned what = new_val;29    printf("new value written to location(%p) = %u\n", char_ptr, what);30    *char_ptr = new_val;31}32 33uint32_t34access_pool (bool flag = false)35{36    static std::mutex g_access_mutex;37    g_access_mutex.lock();38 39    char old_val = *g_char_ptr;40    if (flag)41        do_bad_thing_with_location(g_char_ptr, old_val + 1);42 43    g_access_mutex.unlock();44    return *g_char_ptr;45}46 47void48thread_func (uint32_t thread_index)49{50    printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);51 52    barrier_wait();53 54    uint32_t count = 0;55    uint32_t val;56    while (count++ < 15)57    {58        // random micro second sleep from zero to 3 seconds59        int usec = g_distribution(g_random_engine);60        printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);61        std::this_thread::sleep_for(std::chrono::microseconds{usec});62 63        if (count < 7)64            val = access_pool ();65        else66            val = access_pool (true);67 68        printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);69    }70    printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);71}72 73 74int main (int argc, char const *argv[])75{76    g_count = 4;77    std::thread threads[3];78 79    g_char_ptr = new char{};80 81    // Create 3 threads82    for (auto &thread : threads)83        thread = std::thread{thread_func, std::distance(threads, &thread)};84 85    printf ("Before turning all three threads loose...\n"); // Set break point at this line.86    barrier_wait();87 88    // Join all of our threads89    for (auto &thread : threads)90        thread.join();91 92    delete g_char_ptr;93 94    return 0;95}96