1/* @title: APCs */
2#pragma once
3#include <irq/irq.h>
4#include <sch/sched.h>
5#include <smp/core.h>
6#include <stdatomic.h>
7#include <stdbool.h>
8#include <stddef.h>
9#include <stdint.h>
10#include <structures/list.h>
11#include <thread/apc_types.h>
12#include <thread/thread.h>
13
14struct apc {
15 apc_func_t func;
16 void *ctx;
17 struct thread *owner;
18 struct apc *next;
19};
20
21struct event_apc {
22 struct apc apc;
23 struct apc_event_desc *desc;
24 size_t execute_times;
25};
26
27struct apc_event_desc {
28 const char *name; /* TODO: add fields to this structure */
29};
30
31#define APC_EVENT_EXTERN(n) extern struct apc_event_desc __apc_event_##n
32
33#define APC_EVENT_CREATE(n, strname) \
34 struct apc_event_desc __apc_event_##n = {.name = strname}
35#define APC_EVENT(n) &(__apc_event_##n)
36
37struct apc *apc_create(void);
38struct event_apc *apc_event_apc_create(void);
39void apc_init(struct apc *a, apc_func_t fn, void *arg1);
40void apc_event_apc_init(struct event_apc *a, apc_func_t fn, void *arg1);
41void apc_event_signal(struct apc_event_desc *desc);
42void apc_enqueue(struct thread *t, struct apc *a, enum apc_type type);
43void apc_enqueue_event_apc(struct event_apc *a, struct apc_event_desc *d);
44
45bool apc_cancel(struct apc *a);
46
47void apc_check_and_deliver(struct thread *t);
48
49void apc_enable_special();
50void apc_disable_special();
51
52void apc_enable_kernel();
53void apc_disable_kernel();
54
55void apc_free_on_thread(struct thread *t);
56
57static inline const char *apc_event_str(struct apc_event_desc *evt) {
58 return evt->name;
59}
60
61static inline void apc_enqueue_on_curr(struct apc *a, enum apc_type type) {
62 apc_enqueue(t: thread_get_current(), a, type);
63}
64
65static inline void apc_queue_init(struct apc_queue *q) {
66 q->head = q->tail = NULL;
67}
68