brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 38658e3 Raw
126 lines · cpp
1// C includes2#include <stdio.h>3#include <stdint.h>4#include <stdlib.h>5 6// C++ includes7#include <chrono>8#include <mutex>9#include <random>10#include <thread>11 12std::thread g_thread_1;13std::thread g_thread_2;14std::thread g_thread_3;15std::mutex g_mask_mutex;16 17enum MaskAction {18    eGet,19    eAssign,20    eClearBits21};22 23uint32_t mask_access (MaskAction action, uint32_t mask = 0);24 25uint32_t26mask_access (MaskAction action, uint32_t mask)27{28    static uint32_t g_mask = 0;29 30    std::lock_guard<std::mutex> lock(g_mask_mutex);31    switch (action)32    {33    case eGet:34        break;35 36    case eAssign:37        g_mask |= mask;38        break;39 40    case eClearBits:41        g_mask &= ~mask;42        break;43    }44    return g_mask;45}46 47void *48thread_func (void *arg)49{50    uint32_t thread_index = *((uint32_t *)arg);51    uint32_t thread_mask = (1u << (thread_index));52    printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);53 54    std::default_random_engine generator;55    std::uniform_int_distribution<int> distribution(0, 3000000);56 57    while (mask_access(eGet) & thread_mask)58    {59        // random micro second sleep from zero to 3 seconds60        int usec = distribution(generator);61        printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);62 63        std::chrono::microseconds duration(usec);64        std::this_thread::sleep_for(duration);65        printf ("%s (thread = %u) after usleep ...\n", __FUNCTION__, thread_index); // Set break point at this line.66    }67    printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);68    return NULL;69}70 71 72int main (int argc, char const *argv[])73{74    uint32_t thread_index_1 = 1;75    uint32_t thread_index_2 = 2;76    uint32_t thread_index_3 = 3;77    uint32_t thread_mask_1 = (1u << thread_index_1);78    uint32_t thread_mask_2 = (1u << thread_index_2);79    uint32_t thread_mask_3 = (1u << thread_index_3);80 81    // Make a mask that will keep all threads alive82    mask_access (eAssign, thread_mask_1 | thread_mask_2 | thread_mask_3); // And that line.83 84    // Create 3 threads85    g_thread_1 = std::thread(thread_func, (void*)&thread_index_1);86    g_thread_2 = std::thread(thread_func, (void*)&thread_index_2);87    g_thread_3 = std::thread(thread_func, (void*)&thread_index_3);88 89    char line[64];90    while (mask_access(eGet) != 0)91    {92        printf ("Enter thread index to kill or ENTER for all:\n");93        fflush (stdout);94        // Kill threads by index, or ENTER for all threads95 96        if (fgets (line, sizeof(line), stdin))97        {98            if (line[0] == '\n' || line[0] == '\r' || line[0] == '\0')99            {100                printf ("Exiting all threads...\n");101                break;102            }103            int32_t index = strtoul (line, NULL, 0);104            switch (index)105            {106                case 1: mask_access (eClearBits, thread_mask_1); break;107                case 2: mask_access (eClearBits, thread_mask_2); break;108                case 3: mask_access (eClearBits, thread_mask_3); break;109            }110            continue;111        }112 113        break;114    }115 116    // Clear all thread bits to they all exit117    mask_access (eClearBits, UINT32_MAX);118 119    // Join all of our threads120    g_thread_1.join();121    g_thread_2.join();122    g_thread_3.join();123 124    return 0;125}126