From 51def2fc45d98b59be0413fcb9c25cbb0bbca211 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sat, 14 Mar 2015 15:01:46 +0100 Subject: Fix blocking channel && channel write on circular-overflow. (see ipc.c) --- README.md | 2 +- make_cdrom.sh | 2 +- src/kernel/core/thread.c | 2 +- src/kernel/include/ipc.h | 2 +- src/kernel/user/ipc.c | 55 +++++++++++++++++++++++++++++++++++------------ src/lib/libkogata/stdio.c | 9 ++------ src/sysbin/shell/main.c | 32 +++++++++++++++++++++++++-- 7 files changed, 77 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 6fbcf90..270dfd9 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ running the tests): src/common/ code shared between kernel and userspace libs src/common/include/proto datastructures & constants used for system calls src/lib/ code for userspace libraries - src/lib/include/proto definition of IPC protocols used in the system + src/lib/include/proto definition of IPC protocols used in the system src/sysbin/ userspace system binaries src/tests/ test suite diff --git a/make_cdrom.sh b/make_cdrom.sh index fc51638..f803017 100755 --- a/make_cdrom.sh +++ b/make_cdrom.sh @@ -21,7 +21,7 @@ for BIN in cdrom/sys/bin/*.bin; do strip $BIN; done mkdir -p cdrom/sys/fonts cp res/fonts/*.bf cdrom/sys/fonts -cp res/fonts/muazzam.bf cdrom/sys/fonts/default.bf +cp res/fonts/pcvga.bf cdrom/sys/fonts/default.bf mkdir -p cdrom/sys/keymaps cp res/keymaps/*.km cdrom/sys/keymaps diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c index 4a3722d..fab4eef 100644 --- a/src/kernel/core/thread.c +++ b/src/kernel/core/thread.c @@ -421,7 +421,7 @@ void kill_thread(thread_t *thread) { enqueue_thread(thread, false); } yield(); - if (i++ > 100) dbg_printf("Thread 0x%p must be killed but will not exit.\n", thread); + if (i++ == 100) dbg_printf("Thread 0x%p must be killed but will not exit.\n", thread); } exit_critical(st); diff --git a/src/kernel/include/ipc.h b/src/kernel/include/ipc.h index 4f8573c..5be6d48 100644 --- a/src/kernel/include/ipc.h +++ b/src/kernel/include/ipc.h @@ -6,7 +6,7 @@ // ---- Communication channels -#define CHANNEL_BUFFER_SIZE 1000 // 1000 + other channel_t fields = 1024 - epsilon +#define CHANNEL_BUFFER_SIZE 200 // 1000 + other channel_t fields = 1024 - epsilon typedef struct { fs_handle_t *a, *b; diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c index 0287793..3643eb2 100644 --- a/src/kernel/user/ipc.c +++ b/src/kernel/user/ipc.c @@ -128,11 +128,23 @@ size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_bu c->buf_used -= len; if (c->buf_used == 0) c->buf_use_begin = 0; - } - ret += len; + resume_on(c); + + mutex_unlock(&c->lock); + + ret += len; + } else if (h->mode & FM_BLOCKING) { + int st = enter_critical(CL_NOINT); + + mutex_unlock(&c->lock); - mutex_unlock(&c->lock); + wait_on(c); + + exit_critical(st); + } else { + mutex_unlock(&c->lock); + } } while ((h->mode & FM_BLOCKING) && ret < req_len); return ret; @@ -158,22 +170,37 @@ size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char* if (c->buf_used + len > CHANNEL_BUFFER_SIZE) len = CHANNEL_BUFFER_SIZE - c->buf_used; if (len) { - size_t len0 = len, len1 = 0; - - if (c->buf_use_begin + c->buf_used + len > CHANNEL_BUFFER_SIZE) { - len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin - c->buf_used; - len1 = len - len0; + if (c->buf_use_begin + c->buf_used >= CHANNEL_BUFFER_SIZE) { + memcpy(c->buf + c->buf_use_begin + c->buf_used - CHANNEL_BUFFER_SIZE, buf, len); + } else { + size_t len0 = len, len1 = 0; + + if (c->buf_use_begin + c->buf_used + len > CHANNEL_BUFFER_SIZE) { + len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin - c->buf_used; + len1 = len - len0; + } + memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0); + if (len1) memcpy(c->buf, buf + len0, len1); } - memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0); - if (len1) memcpy(c->buf, buf + len0, len1); c->buf_used += len; - } - mutex_unlock(&c->lock); + resume_on(c); // notify other side + + mutex_unlock(&c->lock); + + ret += len; + } else if (h->mode & FM_BLOCKING) { + int st = enter_critical(CL_NOINT); - if (len) resume_on(c); // notify processes that may be waiting for data - ret += len; + mutex_unlock(&c->lock); + + wait_on(c); + + exit_critical(st); + } else { + mutex_unlock(&c->lock); + } } while ((h->mode & FM_BLOCKING) && ret < req_len); return ret; diff --git a/src/lib/libkogata/stdio.c b/src/lib/libkogata/stdio.c index 1c298ad..e62aa30 100644 --- a/src/lib/libkogata/stdio.c +++ b/src/lib/libkogata/stdio.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -7,12 +8,6 @@ fd_t stdio = 1; int getc() { - sel_fd_t fd; - fd.fd = stdio; - fd.req_flags = SEL_READ; - ASSERT(select(&fd, 1, -1)); - ASSERT(fd.got_flags & SEL_READ); - char chr; size_t sz = read(stdio, 0, 1, &chr); ASSERT(sz == 1); @@ -26,7 +21,7 @@ void putc(int c) { } void puts(char* s) { - while (*s) putc(*(s++)); + write(stdio, 0, strlen(s), s); } void getline(char* buf, size_t l) { diff --git a/src/sysbin/shell/main.c b/src/sysbin/shell/main.c index 1929025..2eb2c6c 100644 --- a/src/sysbin/shell/main.c +++ b/src/sysbin/shell/main.c @@ -14,7 +14,10 @@ void ls(char* dir) { dirent_t i; int ent_no = 0; while (readdir(f, ent_no++, &i)) { - printf("%s\n", i.name); + if (i.st.type & FT_DIR) + printf("%s/\n", i.name); + else + printf("%s\n", i.name); } close(f); } else { @@ -22,10 +25,28 @@ void ls(char* dir) { } } +void cat(char* file) { + fd_t f = open(file, FM_READ); + if (f) { + char buf[129]; + size_t p = 0; + while (true) { + size_t r = read(f, p, 128, buf); + p += r; + buf[r] = 0; + puts(buf); + if (r < 128) break; + } + close(f); + } else { + printf("Could not open file '%s'\n", file); + } +} + int main(int argc, char **argv) { dbg_printf("[shell] Starting\n"); - /*fctl(stdio, FC_SET_BLOCKING, 0);*/ + fctl(1, FC_SET_BLOCKING, 0); puts("Kogata shell.\n"); @@ -49,6 +70,13 @@ int main(int argc, char **argv) { ls(buf2); } } + } else if (!strncmp(buf, "cat ", 4)) { + char buf2[256]; + if (getcwd(buf2, 256)) { + if (pathncat(buf2, buf+4, 256)) { + cat(buf2); + } + } } else if (!strcmp(buf, "exit")) { break; } else { -- cgit v1.2.3