From 0c710141bbb9bd62617d981a3dbaed1b8775fded Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 10 Mar 2015 16:28:38 +0100 Subject: Add simple shared memory facility to IPC (no syscall yet) --- src/kernel/dev/vesa.c | 18 ++--------- src/kernel/include/ipc.h | 4 +++ src/kernel/include/pager.h | 5 ++- src/kernel/include/vfs.h | 10 +++--- src/kernel/user/ipc.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ src/kernel/user/nullfs.c | 4 +-- src/kernel/user/pager.c | 6 +++- src/kernel/user/process.c | 2 +- 8 files changed, 101 insertions(+), 26 deletions(-) diff --git a/src/kernel/dev/vesa.c b/src/kernel/dev/vesa.c index 2a7b876..645a649 100644 --- a/src/kernel/dev/vesa.c +++ b/src/kernel/dev/vesa.c @@ -215,8 +215,6 @@ typedef struct { // ---- VESA code bool vesa_open(fs_node_ptr n, int mode); -size_t vesa_read(fs_handle_t *f, size_t offset, size_t len, char* buf); -size_t vesa_write(fs_handle_t *f, size_t offset, size_t len, const char* buf); void vesa_close(fs_handle_t *f); int vesa_ioctl(fs_node_ptr n, int command, void* data); bool vesa_stat(fs_node_ptr n, stat_t *st); @@ -227,8 +225,8 @@ bool vesa_set_mode(vesa_driver_t *d, int n); fs_node_ops_t vesa_fs_ops = { .open = vesa_open, - .read = vesa_read, - .write = vesa_write, + .read = fs_read_from_pager, + .write = fs_write_to_pager, .close = vesa_close, .ioctl = vesa_ioctl, .stat = vesa_stat, @@ -363,18 +361,6 @@ bool vesa_open(fs_node_ptr n, int mode) { return true; } -size_t vesa_read(fs_handle_t *f, size_t offset, size_t len, char* buf) { - vesa_driver_t *d = (vesa_driver_t*)f->node->data; - - return pager_read(d->pager, offset, len, buf); -} - -size_t vesa_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) { - vesa_driver_t *d = (vesa_driver_t*)f->node->data; - - return pager_write(d->pager, offset, len, buf); -} - void vesa_close(fs_handle_t *f) { // nothing to do } diff --git a/src/kernel/include/ipc.h b/src/kernel/include/ipc.h index 05d14a8..4f8573c 100644 --- a/src/kernel/include/ipc.h +++ b/src/kernel/include/ipc.h @@ -14,6 +14,10 @@ typedef struct { fs_handle_pair_t make_channel(bool blocking); +// ---- shared memory regions + +fs_handle_t* make_shm(size_t size); + // ---- Tokens for sharing file descriptors between processes #define TOKEN_LIFETIME 1500000 // in usecs diff --git a/src/kernel/include/pager.h b/src/kernel/include/pager.h index 03e5da4..a53c7d3 100644 --- a/src/kernel/include/pager.h +++ b/src/kernel/include/pager.h @@ -32,6 +32,9 @@ typedef struct pager { pager_ops_t *ops; union { + struct { + bool allow_resize; + } swap_pager; struct { fs_node_t* node; vfs_pager_ops_t *ops; @@ -49,7 +52,7 @@ typedef struct pager { user_region_t *maps; } pager_t; -pager_t* new_swap_pager(size_t size); +pager_t* new_swap_pager(size_t size, bool allow_resize); pager_t* new_vfs_pager(size_t size, fs_node_t* vfs_node, vfs_pager_ops_t *vfs_ops); pager_t* new_device_pager(size_t size, void* phys_offset); diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index c22ec9a..888c0bc 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -81,11 +81,11 @@ typedef struct fs_handle { typedef struct fs_node_ops { bool (*open)(fs_node_ptr n, int mode); - size_t (*read)(fs_handle_t *f, size_t offset, size_t len, char* buf); - size_t (*write)(fs_handle_t *f, size_t offset, size_t len, const char* buf); - bool (*readdir)(fs_handle_t *f, size_t ent_no, dirent_t *d); - int (*poll)(fs_handle_t *f, void** out_wait_obj); - void (*close)(fs_handle_t *f); + size_t (*read)(fs_handle_t *h, size_t offset, size_t len, char* buf); + size_t (*write)(fs_handle_t *h, size_t offset, size_t len, const char* buf); + bool (*readdir)(fs_handle_t *h, size_t ent_no, dirent_t *d); + int (*poll)(fs_handle_t *h, void** out_wait_obj); + void (*close)(fs_handle_t *h); bool (*stat)(fs_node_ptr n, stat_t *st); int (*ioctl)(fs_node_ptr n, int command, void* data); diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c index a8362ea..e565082 100644 --- a/src/kernel/user/ipc.c +++ b/src/kernel/user/ipc.c @@ -227,6 +227,84 @@ void channel_dispose(fs_node_t *n) { free(c); } +// ---- ------ ------ +// ---- Shared memory +// ---- ------ ------ + +bool shm_open(fs_node_ptr n, int mode); +void shm_close(fs_handle_t *h); +bool shm_stat(fs_node_ptr n, stat_t *st); +void shm_dispose(fs_node_t *n); + +fs_node_ops_t shm_ops = { + .open = shm_open, + .read = fs_read_from_pager, + .write = fs_write_to_pager, + .readdir = 0, + .poll = 0, + .close = shm_close, + .stat = shm_stat, + .ioctl = 0, + .walk = 0, + .delete = 0, + .move = 0, + .create = 0, + .dispose = shm_dispose, +}; + +fs_handle_t* make_shm(size_t size) { + fs_node_t *n = 0; + fs_handle_t *h = 0; + + n = (fs_node_t*)malloc(sizeof(fs_node_t)); + if (n == 0) goto error; + memset(n, 0, sizeof(fs_node_t)); + + h = (fs_handle_t*)malloc(sizeof(fs_handle_t)); + if (h == 0) goto error; + + n->pager = new_swap_pager(size, false); + if (n->pager == 0) goto error; + + n->refs = 1; + n->lock = MUTEX_UNLOCKED; + n->ops = &shm_ops; + n->data = 0; + + h->fs = 0; + h->node = n; + h->refs = 1; + h->mode = FM_READ | FM_WRITE | FM_MMAP; + + return h; + +error: + if (n && n->pager) delete_pager(n->pager); + if (n) free(n); + if (h) free(h); + return 0; +} + +bool shm_open(fs_node_ptr n, int mode) { + int ok_modes = FM_READ | FM_WRITE | FM_MMAP; + if (mode & ~ok_modes) return false; + + return true; +} + +void shm_close(fs_handle_t *h) { + // nothing to do +} + +bool shm_stat(fs_node_ptr n, stat_t *st) { + // TODO + return false; +} + +void shm_dispose(fs_node_t *n) { + delete_pager(n->pager); +} + // ---- ------ // ---- Tokens // ---- ------ diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index d4f345f..636d7fa 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -204,7 +204,7 @@ bool nullfs_add_ram_file(fs_t *fs, const char* name, const char* data, size_t in nullfs_file_t *f = (nullfs_file_t*)malloc(sizeof(nullfs_file_t)); if (f == 0) return false; - p = new_swap_pager(init_sz); + p = new_swap_pager(init_sz, true); if (p == 0) goto error; f->ok_modes = ok_modes & (FM_MMAP | FM_TRUNC | FM_READ | FM_WRITE); @@ -339,7 +339,7 @@ bool nullfs_d_create(fs_node_ptr n, const char* file, int type) { nullfs_file_t *f = (nullfs_file_t*)malloc(sizeof(nullfs_file_t)); if (f == 0) goto f_error; - p = new_swap_pager(0); + p = new_swap_pager(0, true); if (p == 0) goto f_error; f->ok_modes = FM_READ | FM_WRITE | FM_TRUNC | FM_APPEND; diff --git a/src/kernel/user/pager.c b/src/kernel/user/pager.c index 79f293b..b9233b0 100644 --- a/src/kernel/user/pager.c +++ b/src/kernel/user/pager.c @@ -26,7 +26,7 @@ pager_ops_t swap_pager_ops = { .resize = swap_pager_resize, }; -pager_t *new_swap_pager(size_t size) { +pager_t *new_swap_pager(size_t size, bool allow_resize) { pager_t *p = (pager_t*)malloc(sizeof(pager_t)); if (p == 0) return 0; @@ -38,6 +38,8 @@ pager_t *new_swap_pager(size_t size) { p->lock = MUTEX_UNLOCKED; p->maps = 0; + p->swap_pager.allow_resize = allow_resize; + return p; error: @@ -86,6 +88,8 @@ void swap_page_release(pager_t *p, size_t offset, size_t len) { } bool swap_pager_resize(pager_t *p, size_t new_size) { + if (!p->swap_pager.allow_resize) return false; + // later : remove unused pages in swap file return true; diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index 4d79327..85530ca 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -500,7 +500,7 @@ bool mmap(process_t *proc, void* addr, size_t size, int mode) { r->size = size; r->own_pager = true; - r->pager = new_swap_pager(size); + r->pager = new_swap_pager(size, false); if (r->pager == 0) goto error; r->offset = 0; -- cgit v1.2.3