aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-10 16:28:38 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-10 16:28:38 +0100
commit0c710141bbb9bd62617d981a3dbaed1b8775fded (patch)
tree0094294fc5b6182bada5db8e5a64cd3a52e872e2 /src/kernel
parent48c1c4dcc449d05e9950a861e165f456e0d583a1 (diff)
downloadkogata-0c710141bbb9bd62617d981a3dbaed1b8775fded.tar.gz
kogata-0c710141bbb9bd62617d981a3dbaed1b8775fded.zip
Add simple shared memory facility to IPC (no syscall yet)
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/dev/vesa.c18
-rw-r--r--src/kernel/include/ipc.h4
-rw-r--r--src/kernel/include/pager.h5
-rw-r--r--src/kernel/include/vfs.h10
-rw-r--r--src/kernel/user/ipc.c78
-rw-r--r--src/kernel/user/nullfs.c4
-rw-r--r--src/kernel/user/pager.c6
-rw-r--r--src/kernel/user/process.c2
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
@@ -33,6 +33,9 @@ typedef struct pager {
union {
struct {
+ bool allow_resize;
+ } swap_pager;
+ struct {
fs_node_t* node;
vfs_pager_ops_t *ops;
} vfs_pager;
@@ -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;