diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-08 13:57:35 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-03-08 13:57:35 +0100 |
commit | 845fff4dad1159d3d5b94efaf8e547af8d280a5e (patch) | |
tree | 3b962216b7167d7be723e0b2dfbcea0e4312db53 /src/kernel/user | |
parent | 93af9a589980403f9887936963a6ce4f189dc020 (diff) | |
download | kogata-845fff4dad1159d3d5b94efaf8e547af8d280a5e.tar.gz kogata-845fff4dad1159d3d5b94efaf8e547af8d280a5e.zip |
Change prototypes for read, write, readdir, close ; implement blocking IPC.
Diffstat (limited to 'src/kernel/user')
-rw-r--r-- | src/kernel/user/ipc.c | 107 | ||||
-rw-r--r-- | src/kernel/user/nullfs.c | 26 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 8 |
3 files changed, 79 insertions, 62 deletions
diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c index b23af56..a518304 100644 --- a/src/kernel/user/ipc.c +++ b/src/kernel/user/ipc.c @@ -4,10 +4,10 @@ #include <mutex.h> #include <thread.h> -static size_t channel_read(fs_node_ptr c, size_t offset, size_t len, char* buf); -static size_t channel_write(fs_node_ptr c, size_t offset, size_t len, const char* buf); +static size_t channel_read(fs_handle_t *c, size_t offset, size_t len, char* buf); +static size_t channel_write(fs_handle_t *c, size_t offset, size_t len, const char* buf); static bool channel_stat(fs_node_ptr c, stat_t *st); -static void channel_close(fs_node_ptr c); +static void channel_close(fs_handle_t *c); static fs_node_ops_t channel_ops = { .read = channel_read, @@ -33,7 +33,7 @@ typedef struct channel { size_t buf_use_begin, buf_used; // circular buffer } channel_t; -fs_handle_pair_t make_channel() { +fs_handle_pair_t make_channel(bool blocking) { fs_handle_pair_t ret = { .a = 0, .b = 0 }; channel_t *a = 0, *b = 0; @@ -61,7 +61,7 @@ fs_handle_pair_t make_channel() { ret.a->data = a; ret.b->data = b; ret.a->refs = ret.b->refs = 1; - ret.a->mode = ret.b->mode = FM_READ | FM_WRITE; + ret.a->mode = ret.b->mode = FM_READ | FM_WRITE | (blocking ? FM_BLOCKING : 0); return ret; @@ -74,65 +74,82 @@ error: return ret; } -size_t channel_read(fs_node_ptr ch, size_t offset, size_t len, char* buf) { - channel_t *c = (channel_t*)ch; +size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_buf) { + channel_t *c = (channel_t*)h->data; + + size_t ret = 0; - mutex_lock(&c->lock); + do { + size_t len = req_len - ret; + char *buf = orig_buf + ret; + + mutex_lock(&c->lock); - if (c->buf_used < len) len = c->buf_used; + if (c->buf_used < len) len = c->buf_used; - if (len) { - size_t len0 = len, len1 = 0; + if (len) { + size_t len0 = len, len1 = 0; - if (c->buf_use_begin + len > CHANNEL_BUFFER_SIZE) { - len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin; - len1 = len - len0; + if (c->buf_use_begin + len > CHANNEL_BUFFER_SIZE) { + len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin; + len1 = len - len0; + } + memcpy(buf, c->buf + c->buf_use_begin, len0); + if (len1) memcpy(buf + len0, c->buf, len1); + + c->buf_use_begin = (c->buf_use_begin + len) % CHANNEL_BUFFER_SIZE; + c->buf_used -= len; + + if (c->buf_used == 0) c->buf_use_begin = 0; } - memcpy(buf, c->buf + c->buf_use_begin, len0); - if (len1) memcpy(buf + len0, c->buf, len1); - c->buf_use_begin = (c->buf_use_begin + len) % CHANNEL_BUFFER_SIZE; - c->buf_used -= len; - - if (c->buf_used == 0) c->buf_use_begin = 0; - } + ret += len; - mutex_unlock(&c->lock); + mutex_unlock(&c->lock); + } while ((h->mode & FM_BLOCKING) && ret < req_len); - return len; + return ret; } -size_t channel_write(fs_node_ptr ch, size_t offset, size_t len, const char* buf) { - channel_t *tc = (channel_t*)ch; +size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char* orig_buf) { + channel_t *tc = (channel_t*)h->data; channel_t *c = tc->other_side; if (c == 0) return 0; - while (!mutex_try_lock(&c->lock)) { - yield(); - if (tc->other_side == 0) return 0; - } - - if (c->buf_used + len > CHANNEL_BUFFER_SIZE) len = CHANNEL_BUFFER_SIZE - c->buf_used; + size_t ret = 0; - if (len) { - size_t len0 = len, len1 = 0; + do { + size_t len = req_len - ret; + const char* buf = orig_buf + ret; - 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; + while (!mutex_try_lock(&c->lock)) { + yield(); + if (tc->other_side == 0) break; } - memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0); - if (len1) memcpy(c->buf, buf + len0, len1); - c->buf_used += len; - } + if (c->buf_used + len > CHANNEL_BUFFER_SIZE) len = CHANNEL_BUFFER_SIZE - c->buf_used; - mutex_unlock(&c->lock); + 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; + } + memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0); + if (len1) memcpy(c->buf, buf + len0, len1); + + c->buf_used += len; + } - if (len) resume_on(c); // notify processes that may be waiting for data + mutex_unlock(&c->lock); - return len; + if (len) resume_on(c); // notify processes that may be waiting for data + ret += len; + } while ((h->mode & FM_BLOCKING) && ret < req_len); + + return ret; } bool channel_stat(fs_node_ptr ch, stat_t *st) { @@ -149,8 +166,8 @@ bool channel_stat(fs_node_ptr ch, stat_t *st) { return true; } -void channel_close(fs_node_ptr ch) { - channel_t *c = (channel_t*)ch; +void channel_close(fs_handle_t *ch) { + channel_t *c = (channel_t*)ch->data; mutex_lock(&c->lock); diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index 77bc3e8..60872ab 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -19,16 +19,16 @@ static bool nullfs_d_delete(fs_node_ptr n, const char* file); static bool nullfs_d_move(fs_node_ptr n, const char* old_name, fs_node_t *new_parent, const char *new_name); static bool nullfs_d_create(fs_node_ptr n, const char* file, int type); static void nullfs_d_dispose(fs_node_ptr n); -static bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d); -static void nullfs_d_close(fs_node_ptr f); +static bool nullfs_d_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d); +static void nullfs_d_close(fs_handle_t *f); // nullfs ram file node static bool nullfs_f_open(fs_node_ptr n, int mode); static bool nullfs_f_stat(fs_node_ptr n, stat_t *st); static void nullfs_f_dispose(fs_node_ptr n); -static size_t nullfs_f_read(fs_node_ptr f, size_t offset, size_t len, char* buf); -static size_t nullfs_f_write(fs_node_ptr f, size_t offset, size_t len, const char* buf); -static void nullfs_f_close(fs_node_ptr f); +static size_t nullfs_f_read(fs_handle_t *f, size_t offset, size_t len, char* buf); +static size_t nullfs_f_write(fs_handle_t *f, size_t offset, size_t len, const char* buf); +static void nullfs_f_close(fs_handle_t *f); // VTables that go with it static fs_driver_ops_t nullfs_driver_ops = { @@ -410,10 +410,10 @@ void nullfs_d_dispose(fs_node_ptr n) { // nothing to do } -bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d) { +bool nullfs_d_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d) { // Very nonefficient !! - nullfs_dir_t *h = (nullfs_dir_t*)f; + nullfs_dir_t *h = (nullfs_dir_t*)f->data; mutex_lock(&h->lock); @@ -442,7 +442,7 @@ bool nullfs_d_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d) { return ok; } -void nullfs_d_close(fs_node_ptr f) { +void nullfs_d_close(fs_handle_t *f) { // Nothing to do } @@ -486,8 +486,8 @@ void nullfs_f_dispose(fs_node_ptr n) { // -- File handle -- -static size_t nullfs_f_read(fs_node_ptr h, size_t offset, size_t len, char* buf) { - nullfs_file_t *f = (nullfs_file_t*)h; +static size_t nullfs_f_read(fs_handle_t *h, size_t offset, size_t len, char* buf) { + nullfs_file_t *f = (nullfs_file_t*)h->data; mutex_lock(&f->lock); size_t ret = 0; @@ -503,8 +503,8 @@ end_read: return ret; } -static size_t nullfs_f_write(fs_node_ptr h, size_t offset, size_t len, const char* buf) { - nullfs_file_t *f = (nullfs_file_t*)h; +static size_t nullfs_f_write(fs_handle_t *h, size_t offset, size_t len, const char* buf) { + nullfs_file_t *f = (nullfs_file_t*)h->data; mutex_lock(&f->lock); size_t ret = 0; @@ -532,7 +532,7 @@ end_write: return ret; } -static void nullfs_f_close(fs_node_ptr h) { +static void nullfs_f_close(fs_handle_t *h) { // nothing to do } diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index 2af8cf0..4e8cf53 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -449,7 +449,7 @@ void ref_file(fs_handle_t *file) { void unref_file(fs_handle_t *file) { file->refs--; if (file->refs == 0) { - file->ops->close(file->data); + file->ops->close(file); if (file->node) unref_fs_node(file->node); if (file->fs) unref_fs(file->fs); free(file); @@ -465,7 +465,7 @@ size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) { if (f->ops->read == 0) return 0; - return f->ops->read(f->data, offset, len, buf); + return f->ops->read(f, offset, len, buf); } size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) { @@ -473,7 +473,7 @@ size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) { if (f->ops->write == 0) return 0; - return f->ops->write(f->data, offset, len, buf); + return f->ops->write(f, offset, len, buf); } bool file_stat(fs_handle_t *f, stat_t *st) { @@ -491,7 +491,7 @@ int file_ioctl(fs_handle_t *f, int command, void* data) { bool file_readdir(fs_handle_t *f, size_t ent_no, dirent_t *d) { if (!(f->mode & FM_READDIR)) return 0; - return f->ops->readdir && f->ops->readdir(f->data, ent_no, d); + return f->ops->readdir && f->ops->readdir(f, ent_no, d); } /* vim: set ts=4 sw=4 tw=0 noet :*/ |