Skip to content

Zubax/olga_scheduler

Repository files navigation

olga_scheduler

Main Workflow

Generic single-file implementation of an EDF scheduler suitable for deeply embedded systems. "OLGa" is a reference to the fact that it has a logarithmic asymptotic complexity.

Simply copy olga_scheduler.hpp (C++) or olga_scheduler.h (C) into your project tree and you are ready to roll. The only dependency is the CAVL header-only library.

The usage instructions are provided in the comments. The code is fully covered by manual tests with full state space exploration.

For development-related instructions please refer to the CI configuration files. To release a new version, simply create a new tag.

Olga of Kiev

Examples

C

#include "olga_scheduler.h"

#include <inttypes.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>

static int64_t get_microseconds(olga_t* sched)
{
    (void)sched;
    struct timespec ts;
    (void)clock_gettime(CLOCK_MONOTONIC, &ts);
    return ((int64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
}

static void handler(olga_t* sched, olga_event_t* event, int64_t now)
{
    uint64_t* counter = (uint64_t*)event->user;
    ++*counter;
    printf("counter=%" PRIu64 " now=%" PRId64 "\n", *counter, now);
    // Keep events triggering exactly at 1 Hz.
    olga_defer(sched, event->deadline + 1000000, event->user, handler, event);
}

int main(void)
{
    olga_t sched;
    olga_init(&sched, NULL, get_microseconds);

    uint64_t     counter = 0;
    olga_event_t event   = OLGA_EVENT_INIT;
    olga_defer(&sched, sched.now(&sched) + 1000000, &counter, handler, &event);

    for (;;) {
        olga_spin_result_t spin_result = olga_spin(&sched);
        (void)spin_result; // Optional performance information here.
        const struct timespec delay = { .tv_sec = 0, .tv_nsec = 1000 * 1000 };
        (void)nanosleep(&delay, NULL); // Do something else here: IO multiplexing, update scheduler stats, etc.
        if (counter > 10) {
            olga_cancel(&sched, &event);
            puts("Event canceled");
            break;
        }
    }
    return 0;
}

C++

#include "olga_scheduler.hpp"

#include <chrono>
#include <cstdint>
#include <iostream>
#include <thread>

int main()
{
    using namespace std::chrono_literals;

    olga_scheduler::EventLoop<std::chrono::steady_clock> loop;
    std::uint64_t counter = 0;

    auto evt = loop.repeat(1s, [&](const auto& arg) {
        ++counter;
        std::cout << "counter=" << counter
                  << " now=" << arg.approx_now.time_since_epoch().count()
                  << '\n';
        if (counter > 10) {
            arg.event.cancel();
        }
    });

    while (!loop.isEmpty()) {
        (void)loop.spin();
        std::this_thread::sleep_for(1ms); // Do something else here.
    }
    return 0;
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •