PatchworkOS
19e446b
A non-POSIX operating system.
Theme:
Default
Round
Robot
Loading...
Searching...
No Matches
note.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <
kernel/config.h
>
4
#include <
kernel/cpu/interrupt.h
>
5
#include <
kernel/sync/lock.h
>
6
7
#include <
kernel/utils/map.h
>
8
#include <
sys/fs.h
>
9
#include <
sys/proc.h
>
10
11
typedef
struct
cpu
cpu_t
;
12
13
/**
14
* @brief Signal style inter-process communication.
15
* @defgroup kernel_ipc_note Notes
16
* @ingroup kernel_ipc
17
*
18
* Notes are exposed in the `/proc/[pid]/note` file and are used for inter-process communication (IPC) similarly to
19
* signals in Unix-like operating systems. However, instead of being limited to a predefined set of integer values,
20
* notes can send arbitrary strings.
21
*
22
* ## Using Notes
23
*
24
* To send or receive notes, each process exposes a set of files in its `/proc/[pid]` directory.
25
*
26
* @see kernel_proc_process
27
*
28
* ## Receiving Notes
29
*
30
* In the kernel, notes are received and handled in the `note_handle_pending()` function, which is called from an
31
* interrupt context.
32
*
33
* From the perspective of user space, a thread will be interrupted the next time a kernel to user boundary is crossed,
34
* asuming there is a note pending.
35
*
36
* The interruption works by having the kernel save the current interrupt frame of the thread and replacing it with a
37
* new frame that calls the note handler function registered using `notify()`. During the handling of the note, no
38
* further notes will be delivered to the thread.
39
*
40
* Later, when the note handler function calls `noted()`, the kernel will restore the saved interrupt frame and continue
41
* execution from where it left off as if nothing happened. Alternatively, the note handler can choose to exit the
42
* thread. If no handler is registered, the thread is killed.
43
*
44
* ## System Notes
45
*
46
* Certain notes will cause the kernel to take special actions and for the sake of consistency, we define
47
* some notes that all user processes are expected to handle in a standardized way.
48
*
49
* Any such notes are written as a word optionally followed by additional data. For example, a "terminate" note could be
50
* send as is or with a reason string like "terminate due to low memory".
51
*
52
* ### "kill" (SIGKILL)
53
*
54
* When a thread receives this note, it will immediately transition to the `THREAD_DYING` state, causing the scheduler
55
* to kill and free the thread. User space will never see this note.
56
*
57
* ### "divbyzero" (SIGFPE)
58
*
59
* The thread attempted to divide by zero.
60
*
61
* ### "illegal" (SIGILL)
62
*
63
* The thread attempted to execute an illegal instruction.
64
*
65
* ### "interrupt" (SIGINT)
66
*
67
* Indicates an interrupt from the user, typically initiated by pressing `Ctrl+C` in a terminal.
68
*
69
* ### "pagefault" (SIGSEGV)
70
*
71
* Indicates that the thread made an invalid memory access, such as dereferencing a null or invalid pointer.
72
*
73
* ### "segfault" (SIGSEGV)
74
*
75
* Indicates that the thread made an invalid memory access, that dident cause a page fault, such as executing a invalid
76
* instruction.
77
*
78
* ### "terminate" (SIGTERM)
79
*
80
* Indicates that the process should perform any necessary cleanup and exit gracefully.
81
*
82
* ## User-defined Notes
83
*
84
* All system notes will always start with a single word consisting of only lowercase letters.
85
*
86
* If a program wishes to define its own notes, it is best practice to avoid using such words to prevent conflicts with
87
* future system notes. For example, here are some safe to use user-defined notes:
88
* - "user_note ..."
89
* - "UserNote ..."
90
* - "USER-NOTE ..."
91
* - "1usernote ..."
92
*
93
* @{
94
*/
95
96
/**
97
* @brief Maximum size of a notes buffer.
98
*/
99
#define NOTE_MAX 256
100
101
/**
102
* @brief Note queue flags.
103
* @enum note_queue_flag_t
104
*
105
* Its vital that a certain special notes get handled, even if we run out of memory. Since these notes have a predefined
106
* value and we dont care if they get sent multiple times, we can simplify the system such that when the note queue
107
* receives a special note instead of pushing it to the queue we just set the corresponding flag.
108
*/
109
typedef
enum
110
{
111
NOTE_QUEUE_NONE
= 0,
112
NOTE_QUEUE_RECEIVED_KILL
= 1 << 0,
113
NOTE_QUEUE_HANDLING
= 1 << 1,
///< User space is currently handling a note.
114
}
note_queue_flag_t
;
115
116
/**
117
* @brief Note structure.
118
* @struct note_t
119
*/
120
typedef
struct
note
121
{
122
char
buffer
[
NOTE_MAX
];
123
pid_t
sender
;
124
}
note_t
;
125
126
/**
127
* @brief Per-process note handler.
128
* @struct note_handler_t
129
*/
130
typedef
struct
131
{
132
note_func_t
func
;
133
lock_t
lock
;
134
}
note_handler_t
;
135
136
/**
137
* @brief Per-thread note queue.
138
* @struct note_queue_t
139
*/
140
typedef
struct
141
{
142
note_t
notes[
CONFIG_MAX_NOTES
];
143
size_t
readIndex
;
144
size_t
writeIndex
;
145
uint64_t
length
;
146
note_queue_flag_t
flags
;
147
interrupt_frame_t
noteFrame
;
///< The interrupt frame to return to after handling a note.
148
lock_t
lock
;
149
}
note_queue_t
;
150
151
/**
152
* @brief Initialize a note handler.
153
*
154
* @param handler The handler to initialize.
155
*/
156
void
note_handler_init
(
note_handler_t
* handler);
157
158
/**
159
* @brief Initialize a note queue.
160
*
161
* @param queue The queue to initialize.
162
*/
163
void
note_queue_init
(
note_queue_t
* queue);
164
165
/**
166
* @brief The amount of pending notes in a note queue, including special notes.
167
*
168
* @param queue The queue to query.
169
* @return The amount of pending notes.
170
*/
171
uint64_t
note_amount
(
note_queue_t
* queue);
172
173
/**
174
* @brief Write a note to a note queue.
175
*
176
* @param queue The destination queue.
177
* @param string The string to write, should be a null-terminated string.
178
* @return On success, `0`. On failure, `ERR` and `errno` is set.
179
*/
180
uint64_t
note_send
(
note_queue_t
* queue,
const
char
*
string
);
181
182
/**
183
* @brief Handle pending notes for the current thread.
184
*
185
* Should only be called from an interrupt context.
186
*
187
* If the frame is not from user space, this function will return immediately.
188
*
189
* @param frame The interrupt frame.
190
* @return `true` if a note was handled, `false` otherwise.
191
*/
192
bool
note_handle_pending
(
interrupt_frame_t
* frame);
193
194
/** @} */
buffer
EFI_PHYSICAL_ADDRESS buffer
Definition
main.c:237
CONFIG_MAX_NOTES
#define CONFIG_MAX_NOTES
Maximum note queue configuration.
Definition
config.h:69
NOTE_MAX
#define NOTE_MAX
Maximum size of a notes buffer.
Definition
note.h:99
note_handle_pending
bool note_handle_pending(interrupt_frame_t *frame)
Handle pending notes for the current thread.
Definition
note.c:87
note_queue_flag_t
note_queue_flag_t
Note queue flags.
Definition
note.h:110
note_send
uint64_t note_send(note_queue_t *queue, const char *string)
Write a note to a note queue.
Definition
note.c:46
note_amount
uint64_t note_amount(note_queue_t *queue)
The amount of pending notes in a note queue, including special notes.
Definition
note.c:35
note_handler_init
void note_handler_init(note_handler_t *handler)
Initialize a note handler.
Definition
note.c:19
note_queue_init
void note_queue_init(note_queue_t *queue)
Initialize a note queue.
Definition
note.c:25
NOTE_QUEUE_RECEIVED_KILL
@ NOTE_QUEUE_RECEIVED_KILL
Definition
note.h:112
NOTE_QUEUE_NONE
@ NOTE_QUEUE_NONE
Definition
note.h:111
NOTE_QUEUE_HANDLING
@ NOTE_QUEUE_HANDLING
User space is currently handling a note.
Definition
note.h:113
note_func_t
void(* note_func_t)(char *note)
Note handler function type.
Definition
proc.h:255
pid_t
__UINT64_TYPE__ pid_t
Process Identifier.
Definition
pid_t.h:11
fs.h
interrupt.h
config.h
lock.h
map.h
proc.h
uint64_t
__UINT64_TYPE__ uint64_t
Definition
stdint.h:17
cpu_t
CPU structure.
Definition
cpu.h:84
interrupt_frame_t
Trap Frame Structure.
Definition
interrupt.h:195
lock_t
A simple ticket lock implementation.
Definition
lock.h:44
note_handler_t
Per-process note handler.
Definition
note.h:131
note_handler_t::lock
lock_t lock
Definition
note.h:133
note_handler_t::func
note_func_t func
Definition
note.h:132
note_queue_t
Per-thread note queue.
Definition
note.h:141
note_queue_t::flags
note_queue_flag_t flags
Definition
note.h:146
note_queue_t::lock
lock_t lock
Definition
note.h:148
note_queue_t::length
uint64_t length
Definition
note.h:145
note_queue_t::writeIndex
size_t writeIndex
Definition
note.h:144
note_queue_t::readIndex
size_t readIndex
Definition
note.h:143
note_queue_t::noteFrame
interrupt_frame_t noteFrame
The interrupt frame to return to after handling a note.
Definition
note.h:147
note_t
Note structure.
Definition
note.h:121
note_t::sender
pid_t sender
Definition
note.h:123
include
kernel
ipc
note.h
Generated on Sat Jan 24 2026 10:59:24 for PatchworkOS by
1.9.8