Timers in Cilk

#include <iostream>
#include <chrono>
#include <thread>
#include <cilk/cilk.h>

int main() {
    // Timers represent a single event in the future. You
    // tell the timer how long you want to wait, and it
    // will notify you when that time has elapsed. This
    // timer will wait 2 seconds.
    auto start = std::chrono::steady_clock::now();
    std::this_thread::sleep_for(std::chrono::seconds(2));
    auto end = std::chrono::steady_clock::now();
    std::cout << "Timer 1 fired" << std::endl;

    // If you just wanted to wait, you could have used
    // std::this_thread::sleep_for. One reason a timer may be useful is
    // that you can cancel the timer before it fires.
    // Here's an example of that.
    bool timer_cancelled = false;
    cilk_spawn [&]() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        if (!timer_cancelled) {
            std::cout << "Timer 2 fired" << std::endl;
        }
    }();

    // Simulate cancelling the timer
    timer_cancelled = true;
    std::cout << "Timer 2 stopped" << std::endl;

    // Give the timer2 enough time to fire, if it ever
    // was going to, to show it is in fact stopped.
    std::this_thread::sleep_for(std::chrono::seconds(2));

    return 0;
}

This Cilk code demonstrates the concept of timers using C++ standard library’s chrono and thread facilities, along with Cilk’s concurrency features. Here’s a breakdown of the translation:

  1. We use std::chrono::steady_clock and std::this_thread::sleep_for to simulate timers.

  2. The first timer is straightforward - we sleep for 2 seconds and then print a message.

  3. For the second timer, we use Cilk’s cilk_spawn to create a new task that sleeps for 1 second before potentially firing.

  4. We simulate cancelling the timer by setting a boolean flag.

  5. We use std::this_thread::sleep_for at the end to give enough time for the second timer to potentially fire.

To compile and run this program, you would typically use:

$ clang++ -fcilkplus timer_example.cpp -o timer_example
$ ./timer_example
Timer 1 fired
Timer 2 stopped

The first timer will fire after approximately 2 seconds, but the second timer should be stopped before it has a chance to fire.

Note that Cilk doesn’t have built-in timer facilities like Go does, so we’ve simulated them using C++ standard library features. The cilk_spawn keyword is used to create concurrent tasks, which is somewhat analogous to Go’s goroutines.