From 9ca89b1d521e590ede72e9f5f035ee5c8284435d Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Mon, 6 May 2019 16:40:41 -0400 Subject: [PATCH 1/7] Added monitor object, which allows for clean wait/notify against both processes and interrupts. --- kernel/Makefile | 2 +- kernel/monitor.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/monitor.h | 31 ++++++++++++++++++++++++++++++ kernel/mutex.c | 13 +++++++++++-- kernel/mutex.h | 7 ++++--- 5 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 kernel/monitor.c create mode 100644 kernel/monitor.h diff --git a/kernel/Makefile b/kernel/Makefile index b6c7e565..b227285a 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,6 +1,6 @@ include ../Makefile.config -KERNEL_OBJECTS=kernelcore.o main.o console.o page.o keyboard.o mouse.o clock.o interrupt.o kmalloc.o pic.o ata.o cdromfs.o string.o bitmap.o graphics.o font.o syscall_handler.o process.o mutex.o list.o pagetable.o rtc.o kshell.o fs.o hash_set.o diskfs.o serial.o elf.o device.o kobject.o pipe.o bcache.o printf.o is_valid.o +KERNEL_OBJECTS=kernelcore.o main.o console.o page.o keyboard.o mouse.o clock.o interrupt.o kmalloc.o pic.o ata.o cdromfs.o string.o bitmap.o graphics.o font.o syscall_handler.o process.o mutex.o monitor.o list.o pagetable.o rtc.o kshell.o fs.o hash_set.o diskfs.o serial.o elf.o device.o kobject.o pipe.o bcache.o printf.o is_valid.o basekernel.img: bootblock kernel cat bootblock kernel /dev/zero | head -c 1474560 > basekernel.img diff --git a/kernel/monitor.c b/kernel/monitor.c new file mode 100644 index 00000000..079c60fd --- /dev/null +++ b/kernel/monitor.c @@ -0,0 +1,49 @@ +/* +Copyright (C) 2015-2019 The University of Notre Dame +This software is distributed under the GNU General Public License. +See the file LICENSE for details. +*/ + +#include "monitor.h" +#include "process.h" +#include "interrupt.h" + +void monitor_lock(struct monitor *m) +{ + if(m->type==MONITOR_TYPE_INTERRUPT_SAFE) { + interrupt_block(); + } else { + mutex_lock(&m->mutex); + } +} + +void monitor_unlock(struct monitor *m) +{ + if(m->type==MONITOR_TYPE_INTERRUPT_SAFE) { + interrupt_unblock(); + } else { + mutex_unlock(&m->mutex); + } +} + +void monitor_wait(struct monitor *m) +{ + if(m->type==MONITOR_TYPE_INTERRUPT_SAFE) { + process_wait(&m->queue); + } else { + mutex_unlock_and_wait(&m->mutex,&m->queue); + } + monitor_lock(m); +} + +void monitor_notify(struct monitor *m) +{ + process_wakeup(&m->queue); +} + +void monitor_notify_all(struct monitor *m) +{ + while(m->queue.head) { + process_wakeup(&m->queue); + } +} diff --git a/kernel/monitor.h b/kernel/monitor.h new file mode 100644 index 00000000..c95dadca --- /dev/null +++ b/kernel/monitor.h @@ -0,0 +1,31 @@ +/* +Copyright (C) 2015-2019 The University of Notre Dame +This software is distributed under the GNU General Public License. +See the file LICENSE for details. +*/ + +#ifndef MONITOR_H +#define MONITOR_H + +#include "mutex.h" +#include "list.h" + +struct monitor { + int type; + struct mutex mutex; + struct list queue; +}; + +#define MONITOR_TYPE_INTERRUPT_SAFE 1 +#define MONITOR_TYPE_PROCESS_SAFE 2 + +#define MONITOR_INIT_INTERRUPT_SAFE {MONITOR_TYPE_INTERRUPT_SAFE,MUTEX_INIT,LIST_INIT} +#define MONITOR_INIT_PROCESS_SAFE {MONITOR_TYPE_PROCESS_SAFE,MUTEX_INIT,LIST_INIT} + +void monitor_lock( struct monitor *m ); +void monitor_wait( struct monitor *m ); +void monitor_notify( struct monitor *m ); +void monitor_notify_all( struct monitor *m ); +void monitor_unlock( struct monitor *m ); + +#endif diff --git a/kernel/mutex.c b/kernel/mutex.c index 87cc73df..3acf39e6 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -12,7 +12,7 @@ void mutex_lock(struct mutex *m) { interrupt_block(); while(m->locked) { - process_wait(&m->waitqueue); + process_wait(&m->queue); interrupt_block(); } m->locked = 1; @@ -23,6 +23,15 @@ void mutex_unlock(struct mutex *m) { interrupt_block(); m->locked = 0; - process_wakeup(&m->waitqueue); + process_wakeup(&m->queue); interrupt_unblock(); } + +void mutex_unlock_and_wait( struct mutex *m, struct list *queue ) +{ + interrupt_block(); + m->locked = 0; + process_wakeup(&m->queue); + process_wait(queue); + /* process wait unblocks interrupts on process switch */ +} diff --git a/kernel/mutex.h b/kernel/mutex.h index 7c6a1f74..b6b001e2 100644 --- a/kernel/mutex.h +++ b/kernel/mutex.h @@ -11,12 +11,13 @@ See the file LICENSE for details. struct mutex { int locked; - struct list waitqueue; + struct list queue; }; #define MUTEX_INIT {0,LIST_INIT} -void mutex_lock(struct mutex *m); -void mutex_unlock(struct mutex *m); +void mutex_lock( struct mutex *m ); +void mutex_unlock( struct mutex *m ); +void mutex_unlock_and_wait( struct mutex *m, struct list *queue ); #endif From 709b4d9580442125e80c63dc0ceb47a856205fa4 Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Mon, 6 May 2019 17:05:17 -0400 Subject: [PATCH 2/7] Switch keyboard to use interrupt-safe monitor instead of plain sleep/wakeup. --- kernel/keyboard.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/kernel/keyboard.c b/kernel/keyboard.c index 72a97471..67ab48d8 100644 --- a/kernel/keyboard.c +++ b/kernel/keyboard.c @@ -8,7 +8,7 @@ See the file LICENSE for details. #include "ioports.h" #include "interrupt.h" #include "kernel/ascii.h" -#include "process.h" +#include "monitor.h" #include "device.h" #include "kernelcore.h" @@ -46,7 +46,7 @@ static uint8_t buffer[BUFFER_SIZE]; static int keyboard_buffer_read = 0; static int keyboard_buffer_write = 0; -static struct list queue = { 0, 0 }; +static struct monitor monitor = MONITOR_INIT_INTERRUPT_SAFE; static int shift_mode = 0; static int alt_mode = 0; @@ -143,17 +143,22 @@ static void keyboard_interrupt(int i, int intr_code) return; buffer[keyboard_buffer_write] = c; keyboard_buffer_write = (keyboard_buffer_write + 1) % BUFFER_SIZE; - process_wakeup(&queue); + monitor_notify(&monitor); } char keyboard_read( int non_blocking ) { + monitor_lock(&monitor); while(keyboard_buffer_read == keyboard_buffer_write) { - if(non_blocking) return -1; - process_wait(&queue); + if(non_blocking) { + monitor_unlock(&monitor); + return -1; + } + monitor_wait(&monitor); } char c = buffer[keyboard_buffer_read]; keyboard_buffer_read = (keyboard_buffer_read + 1) % BUFFER_SIZE; + monitor_unlock(&monitor); return c; } From 6029845609e7bd5887efe49160948e22d1cfd260 Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Tue, 7 May 2019 12:33:51 -0400 Subject: [PATCH 3/7] Modify clock to use monitor class. --- kernel/clock.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/kernel/clock.c b/kernel/clock.c index 871a150e..a337c650 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -9,6 +9,7 @@ See the file LICENSE for details. #include "clock.h" #include "ioports.h" #include "process.h" +#include "monitor.h" #define CLICKS_PER_SECOND 10 @@ -21,12 +22,12 @@ See the file LICENSE for details. static uint32_t clicks = 0; static uint32_t seconds = 0; -static struct list queue = { 0, 0 }; +static struct monitor monitor = MONITOR_INIT_INTERRUPT_SAFE; static void clock_interrupt(int i, int code) { clicks++; - process_wakeup_all(&queue); + monitor_notify_all(&monitor); if(clicks >= CLICKS_PER_SECOND) { clicks = 0; seconds++; @@ -35,11 +36,21 @@ static void clock_interrupt(int i, int code) } } -clock_t clock_read() +static clock_t clock_read_unlocked() { clock_t result; + result.seconds = seconds; result.millis = 1000 * clicks / CLICKS_PER_SECOND; + + return result; +} + +clock_t clock_read() +{ + monitor_lock(&monitor); + clock_t result = clock_read_unlocked(); + monitor_unlock(&monitor); return result; } @@ -60,12 +71,16 @@ void clock_wait(uint32_t millis) clock_t start, elapsed; uint32_t total; - start = clock_read(); + monitor_lock(&monitor); + + start = clock_read_unlocked(); do { - process_wait(&queue); - elapsed = clock_diff(start, clock_read()); + monitor_wait(&monitor); + elapsed = clock_diff(start, clock_read_unlocked()); total = elapsed.millis + elapsed.seconds * 1000; } while(total < millis); + + monitor_unlock(&monitor); } void clock_init() From 5acbcc9417bf0a701e424c4b67a70ff0a9543c4d Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Tue, 7 May 2019 13:04:25 -0400 Subject: [PATCH 4/7] Modify pipe to use monitors. --- kernel/pipe.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/kernel/pipe.c b/kernel/pipe.c index 656f1512..92ed4dc3 100644 --- a/kernel/pipe.c +++ b/kernel/pipe.c @@ -9,6 +9,7 @@ See the file LICENSE for details. #include "kmalloc.h" #include "process.h" #include "list.h" +#include "monitor.h" #define PIPE_SIZE (1024) @@ -19,7 +20,7 @@ struct pipe { int blocking; int flushed; int refcount; - struct list queue; + struct monitor monitor; }; struct pipe *pipe_create() @@ -30,8 +31,7 @@ struct pipe *pipe_create() p->write_pos = 0; p->blocking = 1; p->flushed = 0; - p->queue.head = 0; - p->queue.tail = 0; + p->monitor = (struct monitor) MONITOR_INIT_PROCESS_SAFE; p->refcount = 1; return p; } @@ -77,19 +77,19 @@ int pipe_write(struct pipe *p, char *buffer, int size) return -1; } int written = 0; + + monitor_lock(&p->monitor); + if(p->blocking) { for(written = 0; written < size; written++) { while((p->write_pos + 1) % PIPE_SIZE == p->read_pos) { - if(p->flushed) { - p->flushed = 0; - return written; - } - process_wait(&p->queue); + if(p->flushed) goto done; + monitor_wait(&p->monitor); } p->buffer[p->write_pos] = buffer[written]; p->write_pos = (p->write_pos + 1) % PIPE_SIZE; } - process_wakeup_all(&p->queue); + monitor_notify_all(&p->monitor); } else { while(written < size && p->write_pos != (p->read_pos - 1) % PIPE_SIZE) { p->buffer[p->write_pos] = buffer[written]; @@ -97,7 +97,10 @@ int pipe_write(struct pipe *p, char *buffer, int size) written++; } } + + done: p->flushed = 0; + monitor_unlock(&p->monitor); return written; } @@ -107,22 +110,23 @@ int pipe_read_internal(struct pipe *p, char *buffer, int size, int block) return -1; } int read = 0; + + monitor_lock(&p->monitor); + if(p->blocking) { for(read = 0; read < size; read++) { while(p->write_pos == p->read_pos) { - if(p->flushed) { - p->flushed = 0; - return read; - } - if (block == 0) { - return -1; + if(p->flushed) goto done; + if(block == 0) { + read = -1; + goto done; } - process_wait(&p->queue); + monitor_wait(&p->monitor); } buffer[read] = p->buffer[p->read_pos]; p->read_pos = (p->read_pos + 1) % PIPE_SIZE; } - process_wakeup_all(&p->queue); + monitor_notify_all(&p->monitor); } else { while(read < size && p->read_pos != p->write_pos) { buffer[read] = p->buffer[p->read_pos]; @@ -130,7 +134,10 @@ int pipe_read_internal(struct pipe *p, char *buffer, int size, int block) read++; } } - p->flushed = 0; + + done: + p->flushed = 0; + monitor_unlock(&p->monitor); return read; } From 9cdefc9eac6dc42cb28f6bca7d74e4964f490d46 Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Wed, 8 May 2019 11:40:52 -0400 Subject: [PATCH 5/7] Simplify pipe code. --- kernel/pipe.c | 69 +++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/kernel/pipe.c b/kernel/pipe.c index 92ed4dc3..35bdf96e 100644 --- a/kernel/pipe.c +++ b/kernel/pipe.c @@ -71,71 +71,54 @@ int pipe_set_blocking(struct pipe *p, int b) return 0; } +static int pipe_is_full( struct pipe *p ) +{ + return (p->write_pos + 1) % PIPE_SIZE == p->read_pos; +} + +static int pipe_is_empty( struct pipe *p ) +{ + return p->write_pos==p->read_pos; +} + int pipe_write(struct pipe *p, char *buffer, int size) { - if(!p || !buffer) { - return -1; - } int written = 0; monitor_lock(&p->monitor); - if(p->blocking) { - for(written = 0; written < size; written++) { - while((p->write_pos + 1) % PIPE_SIZE == p->read_pos) { - if(p->flushed) goto done; - monitor_wait(&p->monitor); - } - p->buffer[p->write_pos] = buffer[written]; - p->write_pos = (p->write_pos + 1) % PIPE_SIZE; - } - monitor_notify_all(&p->monitor); - } else { - while(written < size && p->write_pos != (p->read_pos - 1) % PIPE_SIZE) { - p->buffer[p->write_pos] = buffer[written]; - p->write_pos = (p->write_pos + 1) % PIPE_SIZE; - written++; + for(written = 0; written < size; written++) { + while(pipe_is_full(p)) { + if(!p->blocking || p->flushed ) break; + monitor_notify_all(&p->monitor); + monitor_wait(&p->monitor); } + p->buffer[p->write_pos] = buffer[written]; + p->write_pos = (p->write_pos + 1) % PIPE_SIZE; } - done: + monitor_notify_all(&p->monitor); p->flushed = 0; monitor_unlock(&p->monitor); return written; } -int pipe_read_internal(struct pipe *p, char *buffer, int size, int block) +static int pipe_read_internal(struct pipe *p, char *buffer, int size, int block) { - if(!p || !buffer) { - return -1; - } int read = 0; monitor_lock(&p->monitor); - if(p->blocking) { - for(read = 0; read < size; read++) { - while(p->write_pos == p->read_pos) { - if(p->flushed) goto done; - if(block == 0) { - read = -1; - goto done; - } - monitor_wait(&p->monitor); - } - buffer[read] = p->buffer[p->read_pos]; - p->read_pos = (p->read_pos + 1) % PIPE_SIZE; - } - monitor_notify_all(&p->monitor); - } else { - while(read < size && p->read_pos != p->write_pos) { - buffer[read] = p->buffer[p->read_pos]; - p->read_pos = (p->read_pos + 1) % PIPE_SIZE; - read++; + for(read = 0; read < size; read++) { + while(pipe_is_empty(p)) { + if(p->flushed || !p->blocking || !block) break; + monitor_notify_all(&p->monitor); + monitor_wait(&p->monitor); } + buffer[read] = p->buffer[p->read_pos]; + p->read_pos = (p->read_pos + 1) % PIPE_SIZE; } - done: p->flushed = 0; monitor_unlock(&p->monitor); return read; From 0b4676deb2a9a7e5bf54ce3573a06220e1325088 Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Wed, 8 May 2019 11:46:25 -0400 Subject: [PATCH 6/7] Remove blocking property of pipes and corresponding system calls. (Use read_nonblock or write_nonblock instead.) --- include/kernel/syscall.h | 1 - include/library/syscalls.h | 1 - kernel/kobject.c | 10 ---------- kernel/kobject.h | 1 - kernel/pipe.c | 15 ++------------- kernel/pipe.h | 1 - kernel/syscall_handler.c | 8 -------- library/syscalls.c | 5 ----- user/pipetest.c | 1 - 9 files changed, 2 insertions(+), 41 deletions(-) diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index 24838d42..08ce9b23 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -46,7 +46,6 @@ typedef enum { SYSCALL_OBJECT_STATS, SYSCALL_OBJECT_SET_TAG, SYSCALL_OBJECT_GET_TAG, - SYSCALL_OBJECT_SET_BLOCKING, SYSCALL_OBJECT_MAX, SYSCALL_SYSTEM_STATS, SYSCALL_SYSTEM_TIME, diff --git a/include/library/syscalls.h b/include/library/syscalls.h index 37feca56..328427c4 100644 --- a/include/library/syscalls.h +++ b/include/library/syscalls.h @@ -54,7 +54,6 @@ int syscall_object_close(int fd); int syscall_object_stats(int fd, struct object_stats *stats ); int syscall_object_set_tag(int fd, char *tag); int syscall_object_get_tag(int fd, char *buffer, int buffer_size); -int syscall_object_set_blocking(int fd, int b); int syscall_object_max(); /* Syscalls that query or affect the whole system state. */ diff --git a/kernel/kobject.c b/kernel/kobject.c index 5c09ec20..99ba7714 100644 --- a/kernel/kobject.c +++ b/kernel/kobject.c @@ -313,16 +313,6 @@ int kobject_close(struct kobject *kobject) return 0; } -int kobject_set_blocking(struct kobject *kobject, int b) -{ - switch (kobject->type) { - case KOBJECT_PIPE: - return pipe_set_blocking(kobject->data.pipe, b); - default: - return 0; - } -} - int kobject_size(struct kobject *kobject, int *dims, int n) { switch (kobject->type) { diff --git a/kernel/kobject.h b/kernel/kobject.h index 0785f70d..d28c28d9 100644 --- a/kernel/kobject.h +++ b/kernel/kobject.h @@ -54,7 +54,6 @@ struct kobject * kobject_copy( struct kobject *ksrc, struct kobject **kdst ); int kobject_remove( struct kobject *kobject, const char *name ); int kobject_close(struct kobject *kobject); -int kobject_set_blocking(struct kobject *kobject, int b); int kobject_get_type(struct kobject *kobject); int kobject_set_tag(struct kobject *kobject, char *new_tag); int kobject_get_tag(struct kobject *kobject, char *buffer, int buffer_size); diff --git a/kernel/pipe.c b/kernel/pipe.c index 35bdf96e..365efaab 100644 --- a/kernel/pipe.c +++ b/kernel/pipe.c @@ -17,7 +17,6 @@ struct pipe { char *buffer; int read_pos; int write_pos; - int blocking; int flushed; int refcount; struct monitor monitor; @@ -29,7 +28,6 @@ struct pipe *pipe_create() p->buffer = kmalloc(PIPE_SIZE * sizeof(char)); p->read_pos = 0; p->write_pos = 0; - p->blocking = 1; p->flushed = 0; p->monitor = (struct monitor) MONITOR_INIT_PROCESS_SAFE; p->refcount = 1; @@ -62,15 +60,6 @@ void pipe_delete(struct pipe *p) } } -int pipe_set_blocking(struct pipe *p, int b) -{ - if(p) { - p->blocking = b; - return 1; - } - return 0; -} - static int pipe_is_full( struct pipe *p ) { return (p->write_pos + 1) % PIPE_SIZE == p->read_pos; @@ -89,7 +78,7 @@ int pipe_write(struct pipe *p, char *buffer, int size) for(written = 0; written < size; written++) { while(pipe_is_full(p)) { - if(!p->blocking || p->flushed ) break; + if(p->flushed ) break; monitor_notify_all(&p->monitor); monitor_wait(&p->monitor); } @@ -111,7 +100,7 @@ static int pipe_read_internal(struct pipe *p, char *buffer, int size, int block) for(read = 0; read < size; read++) { while(pipe_is_empty(p)) { - if(p->flushed || !p->blocking || !block) break; + if(p->flushed || !block) break; monitor_notify_all(&p->monitor); monitor_wait(&p->monitor); } diff --git a/kernel/pipe.h b/kernel/pipe.h index d533aa76..7f969218 100644 --- a/kernel/pipe.h +++ b/kernel/pipe.h @@ -7,7 +7,6 @@ struct pipe *pipe_create(); struct pipe *pipe_addref( struct pipe *p ); void pipe_delete(struct pipe *p); void pipe_flush(struct pipe *p); -int pipe_set_blocking(struct pipe *p, int b); int pipe_write(struct pipe *p, char *buffer, int size); int pipe_read(struct pipe *p, char *buffer, int size); diff --git a/kernel/syscall_handler.c b/kernel/syscall_handler.c index 5cb3d7fc..8dc979ed 100644 --- a/kernel/syscall_handler.c +++ b/kernel/syscall_handler.c @@ -522,12 +522,6 @@ int sys_object_get_tag(int fd, char *buffer, int buffer_size) return kobject_get_tag(current->ktable[fd], buffer, buffer_size); } -int sys_object_set_blocking(int fd, int b) -{ - if(!is_valid_object(fd)) return KERROR_INVALID_OBJECT; - return kobject_set_blocking(current->ktable[fd], b); -} - int sys_object_size(int fd, int *dims, int n) { if(!is_valid_object(fd)) return KERROR_INVALID_OBJECT; @@ -673,8 +667,6 @@ int32_t syscall_handler(syscall_t n, uint32_t a, uint32_t b, uint32_t c, uint32_ return sys_object_set_tag(a, (char *) b); case SYSCALL_OBJECT_GET_TAG: return sys_object_get_tag(a, (char *) b, c); - case SYSCALL_OBJECT_SET_BLOCKING: - return sys_object_set_blocking(a, b); case SYSCALL_OBJECT_SIZE: return sys_object_size(a, (int *) b, c); case SYSCALL_OBJECT_MAX: diff --git a/library/syscalls.c b/library/syscalls.c index 62dc3712..9340cdc6 100644 --- a/library/syscalls.c +++ b/library/syscalls.c @@ -168,11 +168,6 @@ int syscall_object_get_tag(int fd, char *buffer, int buffer_size) return syscall(SYSCALL_OBJECT_GET_TAG, fd, (uint32_t)buffer, buffer_size, 0, 0); } -int syscall_object_set_blocking(int fd, int b) -{ - return syscall(SYSCALL_OBJECT_SET_BLOCKING, fd, b, 0, 0, 0); -} - int syscall_object_size(int fd, int *dims, int n) { return syscall(SYSCALL_OBJECT_SIZE, fd, (uint32_t) dims, n, 0, 0); diff --git a/user/pipetest.c b/user/pipetest.c index bb2d926f..93e337d5 100644 --- a/user/pipetest.c +++ b/user/pipetest.c @@ -6,7 +6,6 @@ int main(int argc, char *argv[]) { printf("%d: Running pipe test!\n", syscall_process_self()); int w = syscall_open_pipe(); - syscall_object_set_blocking(w, 0); int x = syscall_process_fork(); if(x) { printf("%d: Writing...\n", syscall_process_self()); From bae3994d21a58539ca4699a14d9e928550faa040 Mon Sep 17 00:00:00 2001 From: Douglas Thain Date: Fri, 6 Sep 2019 09:30:53 -0400 Subject: [PATCH 7/7] Remove flushed flag, rely on notify_all to wake up waiters. --- kernel/kobject.c | 4 ---- kernel/pipe.c | 15 +++++---------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/kernel/kobject.c b/kernel/kobject.c index 99ba7714..2381e665 100644 --- a/kernel/kobject.c +++ b/kernel/kobject.c @@ -305,10 +305,6 @@ int kobject_close(struct kobject *kobject) kfree(kobject->tag); kfree(kobject); return 0; - } else if(kobject->refcount>1 ) { - if(kobject->type==KOBJECT_PIPE) { - pipe_flush(kobject->data.pipe); - } } return 0; } diff --git a/kernel/pipe.c b/kernel/pipe.c index 365efaab..866edf27 100644 --- a/kernel/pipe.c +++ b/kernel/pipe.c @@ -11,7 +11,7 @@ See the file LICENSE for details. #include "list.h" #include "monitor.h" -#define PIPE_SIZE (1024) +#define PIPE_SIZE PAGE_SIZE struct pipe { char *buffer; @@ -24,7 +24,7 @@ struct pipe { struct pipe *pipe_create() { - struct pipe *p = kmalloc(sizeof(*p)); + struct pipe *p = page_alloc(0); p->buffer = kmalloc(PIPE_SIZE * sizeof(char)); p->read_pos = 0; p->write_pos = 0; @@ -42,9 +42,7 @@ struct pipe *pipe_addref( struct pipe *p ) void pipe_flush(struct pipe *p) { - if(p) { - p->flushed = 1; - } + p->flushed = 1; } void pipe_delete(struct pipe *p) @@ -53,9 +51,7 @@ void pipe_delete(struct pipe *p) p->refcount--; if(p->refcount==0) { - if(p->buffer) { - kfree(p->buffer); - } + if(p->buffer) page_free(p->buffer); kfree(p); } } @@ -87,7 +83,6 @@ int pipe_write(struct pipe *p, char *buffer, int size) } monitor_notify_all(&p->monitor); - p->flushed = 0; monitor_unlock(&p->monitor); return written; } @@ -108,7 +103,7 @@ static int pipe_read_internal(struct pipe *p, char *buffer, int size, int block) p->read_pos = (p->read_pos + 1) % PIPE_SIZE; } - p->flushed = 0; + monitor_notify_all(&p->monitor); monitor_unlock(&p->monitor); return read; }