1/* @title: Thread Enumerations and Types */
2#pragma once
3#include <mem/page.h>
4#include <stdarg.h>
5#include <stdint.h>
6
7struct thread;
8struct cpu_context;
9
10/* Both ASAN and the lock validator are very eager to consume
11 * stack memory, so we'll give threads four times as many pages
12 * if either of those happen to be on, and this should
13 * give enough headroom for when both are on too */
14#if defined(DEBUG_ASAN) || defined(DEBUG_LOCK_CHK)
15#define THREAD_STACK_SIZE (PAGE_SIZE * 16)
16#else
17#define THREAD_STACK_SIZE (PAGE_SIZE * 4)
18#endif
19
20enum thread_state : uint8_t {
21 THREAD_STATE_IDLE_THREAD, /* Specifically the idle thread */
22 THREAD_STATE_READY, /* Thread is ready to run but not currently running */
23 THREAD_STATE_RUNNING, /* Thread is currently executing */
24 THREAD_STATE_BLOCKED, /* Waiting on I/O, lock, or condition */
25 THREAD_STATE_SLEEPING, /* Temporarily not runnable */
26 THREAD_STATE_ZOMBIE, /* Finished executing but hasn't been reaped it yet */
27 THREAD_STATE_TERMINATED, /* Fully done, can be cleaned up */
28 THREAD_STATE_HALTED, /* Thread manually suspended */
29};
30
31enum thread_wait_type : uint8_t {
32 THREAD_WAIT_NONE,
33 THREAD_WAIT_UNINTERRUPTIBLE, /* Cannot be interrupted by anything
34 besides the wake source */
35
36 THREAD_WAIT_INTERRUPTIBLE, /* Can be interrupted */
37};
38
39enum thread_wait_status : uint8_t {
40 THREAD_WAIT_MATCHED = 0, /* Woken and expected_wake_src matched */
41 THREAD_WAIT_INTERRUPTED, /* Interrupted by APC, signal, or non matching wake
42 */
43 THREAD_WAIT_SPURIOUS, /* TODO: Start using this */
44};
45
46#define THREAD_WAIT_ANY_SRC ((void *) 0)
47
48/* thread_flags: 32 bit bitflags:
49 *
50 * ┌───────────────────────────────────────────────────────────┐
51 * Bits │ 31..28 27..24 23..20 19..16 15..12 11..8 7..4 3..0 │
52 * Use │ AAAA **** **** **** **** ***J jRWY DEFP │
53 * └───────────────────────────────────────────────────────────┘
54 * P - Pinned - Thread is pinned to current CPU
55 * F - Flexible RT - realtime scheduler related stuff
56 * E - Executing APC
57 * D - Dying
58 * Y - Yielded after a wait (block, sleep)
59 * W - Wake matched
60 * r - Realtime fault tolerance
61 * j - Joinable - someone holds a join reference on this thread
62 * J - Joined - a join is in progress or consumed the join reference
63 * A - Unused (Available)
64 * * - Unused (Unavailable)
65 *
66 */
67enum thread_flags : uint32_t {
68 THREAD_FLAG_PINNED = 1,
69 THREAD_FLAG_FLEXIBLE_RT = 1 << 1,
70 THREAD_FLAG_EXECUTING_APC = 1 << 2,
71 THREAD_FLAG_DYING = 1 << 3,
72 THREAD_FLAG_YIELDED = 1 << 4,
73 THREAD_FLAG_WAKE_MATCHED = 1 << 5,
74 THREAD_FLAG_RT_FAULT_TOLERANCE = 1 << 6,
75 THREAD_FLAG_JOINABLE = 1 << 7,
76 THREAD_FLAG_JOINED = 1 << 8,
77};
78
79enum thread_prio_class : uint8_t {
80 THREAD_PRIO_CLASS_BACKGROUND = 0, /* Background thread */
81 THREAD_PRIO_CLASS_TIMESHARE = 1, /* Timesharing thread */
82 THREAD_PRIO_CLASS_RT = 2, /* Realtime thread */
83 THREAD_PRIO_CLASS_URGENT = 3, /* Urgent thread - ran before RT */
84};
85#define THREAD_PRIO_CLASS_COUNT (4)
86
87/* Different enums are used for the little
88 * bit of type safety since different ringbuffers
89 * are used to keep track of different reasons */
90enum thread_wake_reason : uint8_t {
91 THREAD_WAKE_REASON_BLOCKING_IO = 1,
92 THREAD_WAKE_REASON_BLOCKING_MANUAL = 2,
93 THREAD_WAKE_REASON_SLEEP_TIMEOUT = 3,
94 THREAD_WAKE_REASON_SLEEP_MANUAL = 4,
95};
96
97enum thread_block_reason : uint8_t {
98 THREAD_BLOCK_REASON_IO = 5,
99 THREAD_BLOCK_REASON_MANUAL = 6,
100};
101
102enum thread_sleep_reason : uint8_t {
103 THREAD_SLEEP_REASON_MANUAL = 7,
104};
105
106/* Used in condvars, totally separate from thread_wake_reason */
107enum wake_reason {
108 WAKE_REASON_NONE = 0, /* No reason specified */
109 WAKE_REASON_SIGNAL = 1, /* Signal from something */
110 WAKE_REASON_TIMEOUT = 2, /* Timeout */
111};
112
113/* headers that #include this header should be allowed to execute this function
114 */
115struct thread *thread_create_internal(char *name, void (*entry_point)(void *),
116 void *arg, size_t stack_size,
117 va_list args);
118