From caa22ded0f08137c2f00de957a9dd55c2161006a Mon Sep 17 00:00:00 2001 From: Freywar Ulvnaudgari Date: Fri, 19 Jun 2026 17:49:18 +0300 Subject: [PATCH] Make pipes blocking --- src/kernel/keyboard.c | 7 ++-- src/kernel/pipe.c | 62 ++++++++++++++++++-------------- src/kernel/process.c | 2 ++ src/kernel/syscall.c | 1 - src/user/app/shell/shell.c | 18 +++++----- src/user/app/terminal/terminal.c | 8 ++--- 6 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/kernel/keyboard.c b/src/kernel/keyboard.c index a28ae2d..5a20671 100644 --- a/src/kernel/keyboard.c +++ b/src/kernel/keyboard.c @@ -1,5 +1,6 @@ #include "src/kernel/keyboard.h" #include "src/kernel/idt.h" +#include "src/kernel/process.h" #include "src/kernel/stream.h" #include "src/kernel/util.h" #include "src/lib/memory.h" @@ -56,8 +57,10 @@ static uint64_t stream_write(__attribute__((unused)) const stream_t *self, __att } static uint64_t stream_read(__attribute__((unused)) const stream_t *self, uint64_t max, char *to) { - if (max == 0 || buffer_length == 0) { - return 0; + while (!buffer_length) { + __asm__ volatile("sti"); + process_next(); + __asm__ volatile("cli"); } uint64_t size = buffer_length > max ? max : buffer_length; diff --git a/src/kernel/pipe.c b/src/kernel/pipe.c index 11f1294..2dd7a7e 100644 --- a/src/kernel/pipe.c +++ b/src/kernel/pipe.c @@ -1,4 +1,5 @@ #include "src/kernel/pipe.h" +#include "src/kernel/process.h" #include "src/kernel/stream.h" #include "src/lib/memory.h" @@ -35,16 +36,17 @@ static uint64_t null_write(__attribute__((unused)) const stream_t *self, __attri static uint64_t pipe_read(const stream_t *self, uint64_t max, char *to) { pipe_t *pipe = ((pipe_read_stream_t *)self)->pipe; - uint64_t available = (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE; - uint64_t to_read = available < max ? available : max; - - if (pipe->write_closed && !to_read) { - return (uint64_t)-1; + while (pipe->begin == pipe->end) { + if (pipe->write_closed) { + return 0; + } + __asm__ volatile("sti"); + process_next(); + __asm__ volatile("cli"); } - if (!to_read) { - return 0; - } + uint64_t available = (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE; + uint64_t to_read = available < max ? available : max; if (pipe->begin + to_read <= PIPE_BUFFER_SIZE) { memory_copy(pipe->buffer + pipe->begin, to_read, to); @@ -61,27 +63,33 @@ static uint64_t pipe_read(const stream_t *self, uint64_t max, char *to) { static uint64_t pipe_write(const stream_t *self, const char *from, uint64_t bytes) { pipe_t *pipe = ((pipe_read_stream_t *)self)->pipe; - if (pipe->read_closed) { - return (uint64_t)-1; - } - - uint64_t available = PIPE_BUFFER_SIZE - (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE; - uint64_t to_write = available < bytes ? available : bytes; - - if (to_write == 0) { - return 0; - } - - if (pipe->end + to_write <= PIPE_BUFFER_SIZE) { - memory_copy(from, to_write, pipe->buffer + pipe->end); - } else { - uint64_t chunk = PIPE_BUFFER_SIZE - pipe->end; - memory_copy(from, chunk, pipe->buffer + pipe->end); - memory_copy(from + chunk, to_write - chunk, pipe->buffer); + uint64_t written = 0; + while (written < bytes) { + while (((pipe->end + 1) % PIPE_BUFFER_SIZE) == pipe->begin) { + if (pipe->read_closed) { + return written; + } + __asm__ volatile("sti"); + process_next(); + __asm__ volatile("cli"); + } + + uint64_t available = PIPE_BUFFER_SIZE - (pipe->end + PIPE_BUFFER_SIZE - pipe->begin) % PIPE_BUFFER_SIZE - 1; + uint64_t to_write = available < bytes - written ? available : bytes - written; + + if (pipe->end + to_write <= PIPE_BUFFER_SIZE) { + memory_copy(from, to_write, pipe->buffer + pipe->end); + } else { + uint64_t chunk = PIPE_BUFFER_SIZE - pipe->end; + memory_copy(from, chunk, pipe->buffer + pipe->end); + memory_copy(from + chunk, to_write - chunk, pipe->buffer); + } + + pipe->end = (pipe->end + to_write) % PIPE_BUFFER_SIZE; + written += to_write; } - pipe->end = (pipe->end + to_write) % PIPE_BUFFER_SIZE; - return to_write; + return written; } static void read_close(stream_t *self) { diff --git a/src/kernel/process.c b/src/kernel/process.c index c2dbf28..0191c20 100644 --- a/src/kernel/process.c +++ b/src/kernel/process.c @@ -126,7 +126,9 @@ void process_next() { process_t *prev = current_process; tss.rsp0 = (uint64_t)next->kernel_stack; current_process = next; + __asm__ volatile("cli"); process_switch_to(&prev->kernel_rsp, next->kernel_rsp, VIRT_TO_PHYS(next->pml4)); + __asm__ volatile("sti"); } void process_destroy(process_t *proc) { diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 1ec065c..c1d35e8 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -4,7 +4,6 @@ #include "src/kernel/path.h" #include "src/kernel/process.h" #include "src/kernel/stream.h" -#include "src/kernel/tss.h" #include "src/lib/layout.h" #include "src/lib/memory.h" #include "src/lib/string.h" diff --git a/src/user/app/shell/shell.c b/src/user/app/shell/shell.c index f16ebd8..37c4932 100644 --- a/src/user/app/shell/shell.c +++ b/src/user/app/shell/shell.c @@ -108,16 +108,14 @@ uint64_t main() { char chunk[64]; uint64_t received; - while (1) { - if ((received = read(0, sizeof(chunk), chunk))) { - for (uint64_t i = 0; i < received; i++) { - if (chunk[i] == '\n') { - line[offset] = '\0'; - execute(line); - offset = 0; - } else if (offset < 255) { - line[offset++] = chunk[i]; - } + while ((received = read(0, sizeof(chunk), chunk))) { + for (uint64_t i = 0; i < received; i++) { + if (chunk[i] == '\n') { + line[offset] = '\0'; + execute(line); + offset = 0; + } else if (offset < 255) { + line[offset++] = chunk[i]; } } } diff --git a/src/user/app/terminal/terminal.c b/src/user/app/terminal/terminal.c index 4054e29..b4d101b 100644 --- a/src/user/app/terminal/terminal.c +++ b/src/user/app/terminal/terminal.c @@ -196,11 +196,9 @@ uint64_t main() { memory_set('\b', PROMPT_LENGTH, (char *)bs); memory_set(' ', PROMPT_LENGTH, (char *)ws); - while (1) { - char c; - if (read(0, 1, &c)) { - on_char_received(c); - } + char c; + while (read(0, 1, &c)) { + on_char_received(c); } return 0;