Skip to content

Daemons

include/thread/daemon.h View source View on GitHub
struct daemon_thread {
    struct list_head            list_node;
    bool                        background;
    struct thread               *thread;
    struct daemon               *daemon;
    atomic_bool                 executing_work;
    enum daemon_thread_command  command;
};
struct daemon_work {
    daemon_fn         function;
    struct work_args  args;
    struct daemon     *daemon;
    void              *private;
};
struct daemon_attributes {
    size_t             max_timesharing_threads;
    size_t             min_timesharing_threads;
    atomic_size_t      timesharing_threads;
    atomic_size_t      idle_timesharing_threads;
    atomic_bool        background_thread_present;
    struct cpu_mask    thread_cpu_mask;
    enum daemon_flags  flags;
};
struct daemon {
    char                      *name;
    struct semaphore          ts_sem;
    struct semaphore          bg_sem;
    struct list_head          timesharing_threads;
    struct daemon_work        *timesharing_work;
    struct daemon_thread      *background_thread;
    struct daemon_work        *background_work;
    struct workqueue          *workqueue;
    struct daemon_attributes  attrs;
    struct spinlock           lock;
    enum daemon_state         state;
};
enum daemon_thread_command {
    DAEMON_THREAD_COMMAND_NONE,
    DAEMON_THREAD_COMMAND_EXIT,
    DAEMON_THREAD_COMMAND_RESTART,
    DAEMON_THREAD_COMMAND_SLEEP,
    DAEMON_THREAD_COMMAND_DEFAULT = DAEMON_THREAD_COMMAND_SLEEP,
};
enum daemon_flags {
    DAEMON_FLAG_HAS_WORKQUEUE = 1,
    DAEMON_FLAG_HAS_NAME = 1 << 1,
    DAEMON_FLAG_AUTO_SPAWN = 1 << 2,
    DAEMON_FLAG_NO_TS_THREADS = 1 << 3,
    DAEMON_FLAG_NONE = 0,
};
enum daemon_state {
    DAEMON_STATE_ACTIVE,
    DAEMON_STATE_DESTROYING,
    DAEMON_STATE_DEAD,
};
typedef enum daemon_thread_command (*daemon_fn)(void * arg, void * arg2);
char daemon_state_str(enum daemon_state s);
struct daemon * daemon_create(const char *fmt, struct daemon_attributes *attrs, struct daemon_work *timesharing_work, struct daemon_work *background_work, struct workqueue_attributes *wq_attrs);
void daemon_destroy(struct daemon *daemon);
struct daemon_thread * daemon_spawn_worker(struct daemon *daemon);
enum workqueue_error daemon_submit_oneshot_work(struct daemon *daemon, work_function func, struct work_args args);
enum workqueue_error daemon_submit_work(struct daemon *daemon, struct work *work);
void daemon_print(struct daemon *daemon);
void daemon_wake_background_worker(struct daemon *daemon);
void daemon_wake_timesharing_worker(struct daemon *daemon);
void daemon_wake_all_idle_timesharing_workers(struct daemon *daemon);
#define DAEMON_WORK_FROM(fn, a) \
    ((struct daemon_work) {.function = fn, .args = a})
#define daemon_thread_from_list_node(ln) \
    container_of(ln, struct daemon_thread, list_node)
#define DAEMON_FLAG_TEST(daemon, flag) (daemon->attrs.flags & flag)