PatchworkOS  966e257
A non-POSIX operating system.
Loading...
Searching...
No Matches
note.c
Go to the documentation of this file.
1#include <sys/proc.h>
2#include <user/common/note.h>
4
5#include <signal.h>
6#include <stdatomic.h>
7#include <stdlib.h>
8#include <string.h>
9
11static _Atomic(sighandler_t) signalHandlers[SIGMAX] = {ATOMIC_VAR_INIT(SIG_DFL)};
12
13static void _signal_invoke(int sig, const char* note)
14{
15 sighandler_t handler = atomic_load(&signalHandlers[sig]);
16 if (handler == SIG_IGN)
17 {
18 return;
19 }
20
21 if (handler == SIG_DFL)
22 {
23 _exit(note);
24 }
25
26 handler(sig);
27}
28
29_NORETURN static void _note_kernel_handler(char* note)
30{
31 for (uint64_t i = 0; i < _NOTE_MAX_HANDLERS; i++)
32 {
33 atnotify_func_t func = atomic_load(&noteHandlers[i]);
34 if (func != NULL)
35 {
36 uint64_t result = func(note);
37 if (result == ERR)
38 {
39 _exit(note);
40 }
41 }
42 }
43
44 if (notecmp(note, "divbyzero") == 0)
45 {
47 }
48 else if (notecmp(note, "illegal") == 0)
49 {
51 }
52 else if (notecmp(note, "interrupt") == 0)
53 {
55 }
56 else if (notecmp(note, "pagefault") == 0)
57 {
59 }
60 else if (notecmp(note, "terminate") == 0)
61 {
63 }
64
65 noted();
66}
67
68void _note_init(void)
69{
71 {
72 _exit("notify failed");
73 }
74}
75
77{
78 for (uint64_t i = 0; i < _NOTE_MAX_HANDLERS; i++)
79 {
80 atnotify_func_t expected = NULL;
81 if (atomic_compare_exchange_strong(&noteHandlers[i], &expected, func))
82 {
83 return 0;
84 }
85 }
86
87 return ERR;
88}
89
91{
92 for (uint64_t i = 0; i < _NOTE_MAX_HANDLERS; i++)
93 {
94 atnotify_func_t expected = func;
95 if (atomic_compare_exchange_strong(&noteHandlers[i], &expected, NULL))
96 {
97 return;
98 }
99 }
100}
101
102int _signal_raise(int sig)
103{
104 if (sig <= 0 || sig >= SIGMAX)
105 {
106 return -1;
107 }
108
109 _signal_invoke(sig, F("signal %d raised", sig));
110 return 0;
111}
112
114{
115 if (sig <= 0 || sig >= SIGMAX)
116 {
117 return SIG_ERR;
118 }
119
120 sighandler_t previous = atomic_exchange(&signalHandlers[sig], func);
121 return previous;
122}
123
125{
126 if (sig <= 0 || sig >= SIGMAX)
127 {
128 return;
129 }
130
131 sighandler_t expected = func;
132 atomic_compare_exchange_strong(&signalHandlers[sig], &expected, SIG_DFL);
133}
#define SIG_DFL
Definition signal.h:32
#define SIG_ERR
Definition signal.h:33
#define SIGINT
Definition signal.h:27
#define SIGILL
Definition signal.h:26
#define SIGTERM
Definition signal.h:29
void(* sighandler_t)(int)
Definition signal.h:38
#define SIGFPE
Definition signal.h:25
#define SIGMAX
Definition signal.h:30
#define SIG_IGN
Definition signal.h:34
#define SIGSEGV
Definition signal.h:28
#define F(format,...)
Format string macro.
Definition io.h:83
uint64_t(* atnotify_func_t)(char *note)
User space atnotify() handler function type.
Definition proc.h:318
int64_t notecmp(const char *note, const char *word)
Helper for comparing note strings.
Definition notecmp.c:5
uint64_t notify(note_func_t handler)
System call that sets the handler to be called when a note is received.
Definition notify.c:5
_NORETURN void _exit(const char *status)
System call that handles pending notes for the current thread.
Definition _exit.c:7
_NORETURN void noted(void)
System call that notifies the kernel that the current note has been handled.
Definition noted.c:5
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
#define _NORETURN
Definition config.h:28
uint64_t _note_handler_add(atnotify_func_t func)
Definition note.c:76
void _note_handler_remove(atnotify_func_t func)
Definition note.c:90
static _NORETURN void _note_kernel_handler(char *note)
Definition note.c:29
sighandler_t _signal_handler_add(int sig, sighandler_t func)
Definition note.c:113
void _signal_handler_remove(int sig, sighandler_t func)
Definition note.c:124
void _note_init(void)
Definition note.c:68
static void _signal_invoke(int sig, const char *note)
Definition note.c:13
int _signal_raise(int sig)
Definition note.c:102
#define _NOTE_MAX_HANDLERS
Definition note.h:7
#define atomic_compare_exchange_strong(object, expected, desired)
Definition stdatomic.h:278
#define atomic_exchange(object, desired)
Definition stdatomic.h:282
#define _Atomic(T)
Definition stdatomic.h:59
#define atomic_load(object)
Definition stdatomic.h:288
#define ATOMIC_VAR_INIT(value)
Definition stdatomic.h:74
__UINT64_TYPE__ uint64_t
Definition stdint.h:17