1/* @title: DPCs */
2#pragma once
3#include <stdatomic.h>
4#include <stdbool.h>
5#include <stddef.h>
6#include <stdint.h>
7
8enum dpc_event {
9 DPC_NONE, /* No event */
10 DPC_CPU_IDLE, /* CPU went idle */
11 DPC_CPU_WOKE, /* CPU went un-idle */
12 DPC_EVENT_MAX,
13};
14
15struct dpc;
16typedef void (*dpc_func_t)(struct dpc *, void *ctx);
17
18struct dpc {
19 dpc_func_t func;
20 void *ctx;
21 _Atomic(struct dpc *) next; /* for MPSC push */
22 _Atomic(bool) enqueued; /* prevents double-enqueue */
23};
24
25struct dpc_queue {
26 _Atomic(struct dpc *) head;
27 _Atomic size_t count;
28};
29
30/* Per-cpu DPC data */
31struct dpc_cpu {
32 _Atomic(bool) ipi_queued;
33 struct dpc_queue queues[DPC_EVENT_MAX];
34};
35
36void dpc_run_local(void);
37struct dpc *dpc_create(dpc_func_t fn, void *ctx);
38struct dpc *dpc_init(struct dpc *d, dpc_func_t fn, void *ctx);
39void dpc_init_percpu(void);
40bool dpc_enqueue_local(struct dpc *d, enum dpc_event e);
41bool dpc_enqueue_on_cpu(size_t cpu, struct dpc *d, enum dpc_event e);
42