Concurrency

The standard library module ‘std.concurrency’ contains functionality to support concurrent execution of code.

Condition Variable

Condition variables are used for signalling concurrent execution tasks.

Here is an example:

class ThreadSafeObject(std::mutex mutex, std::condition_variable condition, int value) {
        static create = default;

        void increment() {
                // (Need to mark unused.)
                unused auto lock = std::unique_lock(@mutex);
                @value++;
                @condition.notify_all();
        }

        void wait_for(const int value) {
                // (Need to mark unused.)
                unused auto lock = std::unique_lock(@mutex);
                while (@value != value) {
                        @condition.wait(lock)
                }
        }
}

Message Queue

Message queues are a safe mechanism for passing messages between two concurrent execution tasks, one of which is a ‘reader’ and one which is a ‘writer’.

Here is an example:

class ThreadSafeObject(std::message_queue<int> message_queue) {
        static create = default;

        void send_some(const int value) {
                @message_queue.send(value);
                @message_queue.send(value + 1);
                @message_queue.send(value * 2);
        }

        void wait_for(const int value) {
                auto wait_set = std::wait_set::edge_triggered();
                wait_set.insert(@message_queue.event_source());
                while (true) {
                        if (@message_queue.empty()) {
                                @wait_set.wait();
                        } else {
                                const int received_value = @message_queue.receive();
                                if (received_value == value) {
                                        return;
                                }
                        }
                }
        }
}

Mutex

Mutexes ensure exclusive access by concurrent execution tasks to a sequence of code instructions.

Here is an example:

class ThreadSafeObject(std::mutex mutex, int value) {
        static create = default;

        void modify(const int add) {
                // (Need to mark unused.)
                unused auto lock = std::unique_lock(@mutex);
                @value = @value * 2 + add;
        }
}

Thread

Threads are pre-emptively scheduled concurrent (and potential parallel) execution tasks.

These can be managed with the std::concurrency::thread class; a support function called std::new_thread is available to facilitate creating threads.

Here is an example:

class Task(int context) {
        static create = default;

        void run() {
                sleep(@context);
                printf(C"Done %d!\n", @context);
        }
}

void test() {
        // Template argument deduction will eliminate this redundancy
        // (to be implemented very soon).
        auto task2 = std::new_thread<Task>(Task(2));
        auto task4 = std::new_thread<Task>(Task(4));
        auto task6 = std::new_thread<Task>(Task(6));

        // Etc.

        task2.join();
        task4.join();
        // Thread destructor (for task6) automatically joins.
}