PatchworkOS
Loading...
Searching...
No Matches
note.c
Go to the documentation of this file.
1#include <kernel/ipc/note.h>
2
3#include <kernel/cpu/smp.h>
4#include <kernel/log/log.h>
6
7#include <assert.h>
8#include <errno.h>
9#include <stdlib.h>
10#include <string.h>
11
12static bool note_queue_compare_buffers(const void* a, uint64_t aLength, const void* b, uint64_t bLength)
13{
14 if (aLength != bLength)
15 {
16 return false;
17 }
18
19 return memcmp(a, b, aLength) == 0;
20}
21
23{
24 queue->readIndex = 0;
25 queue->writeIndex = 0;
26 queue->length = 0;
27 queue->flags = NOTE_QUEUE_NONE;
28 lock_init(&queue->lock);
29}
30
32{
33 LOCK_SCOPE(&queue->lock);
34 return queue->length + ((queue->flags & NOTE_QUEUE_RECIEVED_KILL) ? 1 : 0);
35}
36
38{
39 if (queue == NULL || buffer == NULL || count == 0 || count >= NOTE_MAX_BUFFER)
40 {
41 errno = EINVAL;
42 return ERR;
43 }
44
45 process_t* sender = sched_process();
46
47 LOCK_SCOPE(&queue->lock);
48
50 {
52 return 0;
53 }
54
55 note_t* note = NULL;
56 if (queue->length == CONFIG_MAX_NOTES)
57 {
58 note = &queue->notes[queue->readIndex];
59 queue->readIndex = (queue->readIndex + 1) % CONFIG_MAX_NOTES;
60 }
61 else
62 {
63 note = &queue->notes[queue->writeIndex];
64 queue->writeIndex = (queue->writeIndex + 1) % CONFIG_MAX_NOTES;
65 queue->length++;
66 }
67
68 assert(note != NULL);
69
70 memcpy(note->buffer, buffer, count);
71 note->buffer[count] = '\0';
72 note->length = count;
73 note->sender = sender->id;
74 return 0;
75}
76
78{
79 thread_t* thread = sched_thread_unsafe();
80 process_t* process = thread->process;
81 note_queue_t* queue = &thread->notes;
82
83 lock_acquire(&queue->lock);
84
86 {
87 lock_release(&queue->lock);
88 process_kill(process, EXIT_FAILURE);
89 sched_invoke(frame, self, SCHED_DIE);
90 return;
91 }
92
93 while (true)
94 {
95 if (queue->length == 0)
96 {
97 lock_release(&queue->lock);
98 return;
99 }
100
101 note_t* note = &queue->notes[queue->readIndex];
102 queue->readIndex = (queue->readIndex + 1) % CONFIG_MAX_NOTES;
103 queue->length--;
104
105 LOG_WARN("unknown note '%.*s' received in thread tid=%d\n", note->length, note->buffer, thread->id);
106 // TODO: Software interrupts.
107 }
108}
#define assert(expression)
Definition assert.h:29
uint64_t note_queue_length(note_queue_t *queue)
Get the length of a note queue.
Definition note.c:31
uint64_t note_queue_write(note_queue_t *queue, const void *buffer, uint64_t count)
Write a note to a note queue.
Definition note.c:37
#define NOTE_MAX_BUFFER
Maximum size of a notes buffer.
Definition note.h:46
void note_queue_init(note_queue_t *queue)
Initialize a note queue.
Definition note.c:22
void note_interrupt_handler(interrupt_frame_t *frame, cpu_t *self)
Note interrupt handler.
Definition note.c:77
@ NOTE_QUEUE_RECIEVED_KILL
Definition note.h:62
@ NOTE_QUEUE_NONE
Definition note.h:54
#define LOG_WARN(format,...)
Definition log.h:88
void process_kill(process_t *process, uint64_t status)
Kills a process.
Definition process.c:483
process_t * sched_process(void)
Retrieves the process of the currently running thread.
Definition sched.c:164
thread_t * sched_thread_unsafe(void)
Retrieves the currently running thread without disabling interrupts.
Definition sched.c:175
void sched_invoke(interrupt_frame_t *frame, cpu_t *self, schedule_flags_t flags)
The main scheduling function.
Definition sched.c:480
@ SCHED_DIE
Kill and free the currently running thread.
Definition sched.h:277
static void lock_init(lock_t *lock)
Initializes a lock.
Definition lock.h:80
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
Definition lock.h:57
static void lock_release(lock_t *lock)
Releases a lock.
Definition lock.h:140
static void lock_acquire(lock_t *lock)
Acquires a lock, blocking until it is available.
Definition lock.h:97
#define CONFIG_MAX_NOTES
Maximum note queue configuration.
Definition config.h:68
#define EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
EFI_PHYSICAL_ADDRESS buffer
Definition mem.c:15
static bool note_queue_compare_buffers(const void *a, uint64_t aLength, const void *b, uint64_t bLength)
Definition note.c:12
static atomic_long count
Definition main.c:9
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
#define EXIT_FAILURE
Definition stdlib.h:47
_PUBLIC int memcmp(const void *s1, const void *s2, size_t n)
Definition memcmp.c:3
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:4
CPU structure.
Definition cpu.h:42
Trap Frame Structure.
Definition interrupt.h:42
Per-thread note queue.
Definition note.h:81
note_queue_flag_t flags
Definition note.h:86
note_t notes[CONFIG_MAX_NOTES]
Definition note.h:82
uint64_t readIndex
Definition note.h:83
lock_t lock
Definition note.h:87
uint64_t writeIndex
Definition note.h:84
uint64_t length
Definition note.h:85
Note structure.
Definition note.h:70
uint8_t buffer[NOTE_MAX_BUFFER]
Definition note.h:71
pid_t sender
Definition note.h:73
uint16_t length
Definition note.h:72
Process structure.
Definition process.h:53
pid_t id
Definition process.h:55
Thread of execution structure.
Definition thread.h:55
process_t * process
The parent process that the thread executes within.
Definition thread.h:57
note_queue_t notes
Definition thread.h:73
tid_t id
The thread id, unique within a process_t.
Definition thread.h:59