std1.0.0-beta-7 SafeC docs

Source sync/thread_bare.h

View in the repository

// SafeC Standard Library — Freestanding Cooperative Threads
// Priority-aware wrapper over TaskScheduler.  Freestanding-safe.
//
// Thread functions use the same coroutine protocol as TaskScheduler:
//   int func(?&T arg, int resume_point)
//   Returns > 0 to yield (value = new resume_point), 0 when done.
//
// Threads with higher priority values run before lower-priority ones
// within each scheduling tick.
#pragma once
#include <std/sync/task.h>

#define THREAD_MAX  TASK_MAX
#define THREAD_NONE (-1)

// Thread identifier: index into the ThreadSched table.
namespace std {

newtype Thread = int;

struct ThreadSched {
    struct TaskScheduler inner;             // underlying round-robin scheduler
    int                  priority[THREAD_MAX];  // per-thread priority (higher = first)

    // An empty thread scheduler (all slots empty, no threads running).
    static struct ThreadSched new();

    // Spawn a thread running func(arg, resume_point) (same protocol as
    // TaskScheduler::spawn). priority >= 0; higher values run earlier in
    // each tick. Returns the Thread id (>= 0) or THREAD_NONE if the table
    // is full.
    generic<T> Thread spawn(fn int(?&T, int) func, ?&T arg, int priority);

    // Type-erased spawn behind spawn().
    Thread  spawn_raw_(fn int(?&Erased, int) func, ?&Erased arg, int priority);

    // Run one scheduling pass: threads are served in descending priority order.
    // Returns the number of still-active threads.
    int     tick();

    // Run until all threads complete.
    void    run_all();

    // Return 1 if thread `t` is still active (READY or RUNNING), 0 if DONE.
    int     is_active(Thread t) const;

    // Cooperative join: calls tick() until thread `t` is done.
    void    join_thread(Thread t);

    // Return number of active (non-DONE) threads.
    int     active_count() const;
};

generic<T>
Thread ThreadSched::spawn(fn int(?&T, int) func, ?&T arg, int priority) {
    unsafe { return self.spawn_raw_((fn int(?&Erased, int))func, (?&Erased)arg, priority); }
}

} // namespace std