CeDOS - Commit 0830bec4

files: Make devices non-blocking Instead of yielding from the kernel, we yield from the user process, where we know better whether we want to block or not.
Celina Sophie Kalus
Sun, 26 Nov 2023 22:22:12 +0100
5 files changed, 65 insertions(+), 29 deletions(-)
M include/cedos/drivers/keyboard.hinclude/cedos/drivers/keyboard.h

@@ -25,7 +25,7 @@ /*!

* Reads a single character from the keyboard * \return A single char corresponding to a key press. */ - uint8_t (*read)(void); + int (*read)(void); } KB_DRIVER; //! PS/2 keyboard driver (default driver)
M src/kernel/drivers/ps2_keyboard.csrc/kernel/drivers/ps2_keyboard.c

@@ -39,13 +39,13 @@ /*!

* Reads a single character from the PS/2 keyboard * \return A single char corresponding to a key press. */ -uint8_t ps2_kb_read(void); +int ps2_kb_readc(void); //! PS/2 keyboard driver (default driver) KB_DRIVER ps2_kb = { "PS/2 keyboard driver", ps2_kb_init, - ps2_kb_read + ps2_kb_readc }; uint8_t *buffer;

@@ -108,11 +108,21 @@

return 1; } -uint8_t ps2_kb_read(void) { - while (buffer_empty()) { - //PRINT_DBG("yield.\n"); - sched_yield(); +int ps2_kb_readc(void) { + if (buffer_empty()) { + return -1; + } else { + return (int)(buffer_dequeue()); } +} - return buffer_dequeue(); +int ps2_kb_read(int fd, char *buffer, uint32_t size) { + int res = 0; + for (int i = 0; i < size; i++) { + if (buffer_empty()) { break; } + + buffer[i] = buffer_dequeue(); + res++; + } + return res; }
M src/kernel/drivers/tty.csrc/kernel/drivers/tty.c

@@ -23,18 +23,36 @@ }

int tty_read(int fd, char *buffer, uint32_t size) { uint32_t i = 0; + static int state = 0; + static char next[2]; while (i < size) { + if (state > 0) { + buffer[i++] = next[--state]; + continue; + } char table[] = { '^', 0x1B, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\\', '`', 0x08, '\t', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', '?', '+', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '?', '?', '#', - 0, '<', 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, ' ' }; - uint32_t scancode = std_kb->read(); - char c = scancode <= 60 ? table[scancode] : 0; - if (c == 0) { continue; } - buffer[i++] = c; + 0, '<', 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, ' ', + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'A' }; + int scancode = std_kb->read(); + if (scancode < 0) { + break; + } else if (scancode <= 60) { + char c = scancode <= 60 ? table[scancode] : 0; + if (c == 0) { continue; } + buffer[i++] = c; + } else if (scancode == 0xE0) { + scancode = std_kb->read(); + if (scancode > 0x48 || table[scancode] == 0) { continue; } + buffer[i++] = '^'; + next[1] = '['; + next[0] = table[scancode]; + state = 2; + } } - return size; + return i; } int tty_write(int fd, char *buffer, uint32_t size) {
M src/kernel/pipe.csrc/kernel/pipe.c

@@ -17,9 +17,9 @@ uint8_t pipe_buffer[PIPE_BUFFER_SIZE];

int read_head = 0; int write_head = 0; -uint8_t pipe_readc() { - while (write_head == read_head) { - sched_yield(); +int pipe_readc() { + if (write_head == read_head) { + return -1; } int rh_next = (read_head + 1) % PIPE_BUFFER_SIZE;

@@ -28,23 +28,31 @@ read_head = rh_next;

return res; } -void pipe_writec(uint8_t c) { +int pipe_writec(uint8_t c) { int wh_next = (write_head + 1) % PIPE_BUFFER_SIZE; - while (wh_next == read_head) { - sched_yield(); + if ((wh_next + 1) % PIPE_BUFFER_SIZE == read_head) { + return -1; } pipe_buffer[write_head] = c; write_head = wh_next; + return c; } int pipe_read(int fd, char *buffer, uint32_t size) { - for (int i = 0; i < size; i++) { - buffer[i] = pipe_readc(); + int i = 0; + while (i < size) { + int res = pipe_readc(); + if (res == -1) { break; } + buffer[i++] = (char)(res); } + return i; } int pipe_write(int fd, char *buffer, uint32_t size) { - for (int i = 0; i < size; i++) { - pipe_writec(buffer[i]); + int i = 0; + while (i < size) { + int res = pipe_writec(buffer[i++]); + if (res == -1) { break; } } + return i; }
M src/libcedos/stdio.csrc/libcedos/stdio.c

@@ -35,12 +35,12 @@ int fgetc ( FILE * stream ) {

int retval; char c = 0; retval = fread(&c, 1, 1, stream); - - if (retval == 1) { - return (int)(c); - } else { - return EOF; + while (retval == 0) { + yield(); + retval = fread(&c, 1, 1, stream); } + + return (int)(c); } int fputs ( const char * str, FILE * stream ) {