aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/user')
-rw-r--r--src/kernel/user/ipc.c7
-rw-r--r--src/kernel/user/process.c66
-rw-r--r--src/kernel/user/syscall.c2
-rw-r--r--src/kernel/user/vfs.c34
4 files changed, 83 insertions, 26 deletions
diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c
index 7f34fdf..308a9c1 100644
--- a/src/kernel/user/ipc.c
+++ b/src/kernel/user/ipc.c
@@ -83,6 +83,10 @@ fs_handle_pair_t make_channel(bool blocking) {
ret.b->node = nb;
ret.a->refs = ret.b->refs = 1;
ret.a->mode = ret.b->mode = FM_READ | FM_WRITE | (blocking ? FM_BLOCKING : 0);
+ ret.a->lock = ret.b->lock = MUTEX_UNLOCKED;
+
+ dbg_printf("hREF1c0x%p\n", ret.a);
+ dbg_printf("hREF1c0x%p\n", ret.b);
return ret;
@@ -274,8 +278,11 @@ fs_handle_t* make_shm(size_t size) {
h->fs = 0;
h->node = n;
h->refs = 1;
+ h->lock = MUTEX_UNLOCKED;
h->mode = FM_READ | FM_WRITE | FM_MMAP;
+ dbg_printf("hREF1s0x%p\n", h);
+
return h;
error:
diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c
index 2a4d98f..f56998e 100644
--- a/src/kernel/user/process.c
+++ b/src/kernel/user/process.c
@@ -9,6 +9,8 @@
static int next_pid = 1;
+void munmap_inner(process_t *proc, user_region_t *r);
+
void proc_user_exception(registers_t *regs);
void proc_usermem_pf(void* proc, registers_t *regs, void* addr);
@@ -154,20 +156,21 @@ bool start_process(process_t *p, void* entry) {
return true;
}
-void current_process_exit(int status, int exit_code) {
- void process_exit_v(void* args) {
- exit_data_t *d = (exit_data_t*)args;
- process_exit(d->proc, d->status, d->exit_code);
- free(d);
- }
+void current_process_exit_task(void* args) {
+ exit_data_t *d = (exit_data_t*)args;
+ process_exit(d->proc, d->status, d->exit_code);
+ free(d);
+}
- exit_data_t *d = (exit_data_t*)malloc(sizeof(exit_data_t));
+void current_process_exit(int status, int exit_code) {
+ exit_data_t *d;
+ while ((d = (exit_data_t*)malloc(sizeof(exit_data_t))) == 0) yield();
d->proc = current_process();;
d->status = status;
d->exit_code = exit_code;
- while (!worker_push(process_exit_v, d)) yield();
+ while (!worker_push(current_process_exit_task, d)) yield();
exit();
}
@@ -207,8 +210,9 @@ void process_exit(process_t *p, int status, int exit_code) {
process_t *ch = p->children;
p->children = ch->next_child;
- if (ch->status == PS_RUNNING || ch->status == PS_LOADING)
+ if (ch->status == PS_RUNNING || ch->status == PS_LOADING) {
process_exit(ch, PS_KILLED, 0);
+ }
free(ch);
}
@@ -222,7 +226,7 @@ void process_exit(process_t *p, int status, int exit_code) {
// unmap memory
while (p->regions != 0) {
- munmap(p, p->regions->addr);
+ munmap_inner(p, p->regions);
}
ASSERT(btree_count(p->regions_idx) == 0);
delete_btree(p->regions_idx);
@@ -441,6 +445,7 @@ bool proc_add_fs(process_t *p, fs_t *fs, const char* name) {
mutex_lock(&p->lock);
+ if (p->filesystems == 0) goto end;
if (hashtbl_find(p->filesystems, n) != 0) goto end;
add_ok = hashtbl_add(p->filesystems, n, fs);
@@ -458,7 +463,7 @@ end:
fs_t *proc_find_fs(process_t *p, const char* name) {
mutex_lock(&p->lock);
- fs_t *ret = (fs_t*)hashtbl_find(p->filesystems, name);
+ fs_t *ret = (p->filesystems != 0 ? (fs_t*)hashtbl_find(p->filesystems, name) : 0);
mutex_unlock(&p->lock);
return ret;
@@ -477,11 +482,10 @@ void proc_rm_fs(process_t *p, const char* name) {
}
int proc_add_fd(process_t *p, fs_handle_t *f) {
- int fd = p->next_fd++;
-
mutex_lock(&p->lock);
- bool add_ok = hashtbl_add(p->files, (void*)fd, f);
+ int fd = p->next_fd++;
+ bool add_ok = (p->files != 0 ? hashtbl_add(p->files, (void*)fd, f) : false);
mutex_unlock(&p->lock);
@@ -497,6 +501,7 @@ bool proc_add_fd_as(process_t *p, fs_handle_t *f, int fd) {
mutex_lock(&p->lock);
+ if (p->files == 0) goto end;
if (hashtbl_find(p->files, (void*)fd) != 0) goto end;
if (fd >= p->next_fd) p->next_fd = fd + 1;
@@ -511,7 +516,7 @@ end:
fs_handle_t *proc_read_fd(process_t *p, int fd) {
mutex_lock(&p->lock);
- fs_handle_t *ret = (fs_handle_t*)hashtbl_find(p->files, (void*)fd);
+ fs_handle_t *ret = (p->files != 0 ? (fs_handle_t*)hashtbl_find(p->files, (void*)fd) : 0);
mutex_unlock(&p->lock);
return ret;
@@ -520,7 +525,7 @@ fs_handle_t *proc_read_fd(process_t *p, int fd) {
void proc_close_fd(process_t *p, int fd) {
mutex_lock(&p->lock);
- fs_handle_t *x = (fs_handle_t*)hashtbl_find(p->files, (void*)fd);
+ fs_handle_t *x = (p->files != 0 ? (fs_handle_t*)hashtbl_find(p->files, (void*)fd) : 0);
if (x != 0) {
unref_file(x);
hashtbl_remove(p->files, (void*)fd);
@@ -536,7 +541,7 @@ void proc_close_fd(process_t *p, int fd) {
user_region_t *find_user_region(process_t *proc, const void* addr) {
mutex_lock(&proc->lock);
- user_region_t *r = (user_region_t*)btree_lower(proc->regions_idx, addr);
+ user_region_t *r = (proc->regions_idx != 0 ? (user_region_t*)btree_lower(proc->regions_idx, addr) : 0);
if (r != 0) {
ASSERT(addr >= r->addr);
@@ -561,6 +566,8 @@ bool mmap(process_t *proc, void* addr, size_t size, int mode) {
mutex_lock(&proc->lock);
+ if (proc->regions_idx == 0) goto error;
+
r->proc = proc;
r->addr = addr;
r->size = size;
@@ -592,6 +599,7 @@ error:
}
bool mmap_file(process_t *proc, fs_handle_t *h, size_t offset, void* addr, size_t size, int mode) {
+ dbg_printf("Mmap file 0x%p\n", h);
if (find_user_region(proc, addr) != 0) return false;
if ((uint32_t)addr & (~PAGE_MASK)) return false;
@@ -611,6 +619,8 @@ bool mmap_file(process_t *proc, fs_handle_t *h, size_t offset, void* addr, size_
mutex_lock(&proc->lock);
+ if (proc->regions_idx == 0) goto error;
+
r->addr = addr;
r->size = size;
@@ -673,12 +683,9 @@ bool mchmap(process_t *proc, void* addr, int mode) {
return true;
}
-bool munmap(process_t *proc, void* addr) {
- user_region_t *r = find_user_region(proc, addr);
- if (r == 0) return false;
-
- mutex_lock(&proc->lock);
-
+void munmap_inner(process_t *proc, user_region_t *r) {
+ // assume theprocess lock is locked
+ // will always succeed
if (proc->regions == r) {
proc->regions = r->next_in_proc;
} else {
@@ -707,14 +714,23 @@ bool munmap(process_t *proc, void* addr) {
}
switch_pagedir(save_pd);
- mutex_unlock(&proc->lock);
-
pager_rm_map(r->pager, r);
if (r->file != 0) unref_file(r->file);
if (r->own_pager) delete_pager(r->pager);
free(r);
+}
+
+bool munmap(process_t *proc, void* addr) {
+ user_region_t *r = find_user_region(proc, addr);
+ if (r == 0) return false;
+
+ mutex_lock(&proc->lock);
+
+ munmap_inner(proc, r);
+
+ mutex_unlock(&proc->lock);
return true;
}
diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c
index 350262c..42b06eb 100644
--- a/src/kernel/user/syscall.c
+++ b/src/kernel/user/syscall.c
@@ -307,7 +307,7 @@ uint32_t select_sc(sc_args_t args) {
uint64_t select_begin_time = get_kernel_time();
void** wait_objs = (void**)malloc((n+1) * sizeof(void*));
- if (!wait_objs) return false;
+ if (wait_objs == 0) return false;
bool ret = false;
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index a967f70..db01888 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -42,6 +42,7 @@ fs_t *make_fs(const char* drv_name, fs_handle_t *source, const char* opts) {
if (fs->root == 0) goto fail;
fs->refs = 1;
+ fs->lock = MUTEX_UNLOCKED;
fs->from_fs = 0;
fs->ok_modes = FM_ALL_MODES;
fs->root->refs = 1;
@@ -49,6 +50,8 @@ fs_t *make_fs(const char* drv_name, fs_handle_t *source, const char* opts) {
fs->root->parent = 0;
fs->root->children = 0;
+ dbg_printf("sREF1m0x%p\n", fs);
+
// Look for driver
for(fs_driver_t *i = drivers; i != 0; i = i->next) {
if ((drv_name != 0 && strcmp(i->name, drv_name) == 0) || (drv_name == 0 && source != 0)) {
@@ -75,6 +78,8 @@ fs_t *fs_subfs(fs_t *fs, const char* root, int ok_modes) {
if (subfs == 0) return 0;
subfs->refs = 1;
+ subfs->lock = MUTEX_UNLOCKED;
+
subfs->from_fs = fs;
subfs->ok_modes = ok_modes & fs->ok_modes;
@@ -83,6 +88,8 @@ fs_t *fs_subfs(fs_t *fs, const char* root, int ok_modes) {
subfs->root = new_root;
+ dbg_printf("sREF1s0x%p\n", fs);
+
return subfs;
}
@@ -91,10 +98,20 @@ bool fs_add_source(fs_t *fs, fs_handle_t *source, const char* opts) {
}
void ref_fs(fs_t *fs) {
+ dbg_printf("sREF++0x%p(%d)\n", fs, fs->refs);
+
+ mutex_lock(&fs->lock);
+
fs->refs++;
+
+ mutex_unlock(&fs->lock);
}
void unref_fs(fs_t *fs) {
+ dbg_printf("sREF--0x%p(%d)\n", fs, fs->refs);
+
+ mutex_lock(&fs->lock);
+
fs->refs--;
if (fs->refs == 0) {
if (fs->from_fs != 0) {
@@ -105,6 +122,8 @@ void unref_fs(fs_t *fs) {
}
if (fs->ops->shutdown) fs->ops->shutdown(fs->data);
free(fs);
+ } else {
+ mutex_unlock(&fs->lock);
}
}
@@ -432,10 +451,13 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) {
if (!open_ok) goto error;
h->refs = 1;
+ h->lock = MUTEX_UNLOCKED;
h->fs = fs;
h->node = n;
h->mode = mode;
+ dbg_printf("hREF1o0x%p\n", h);
+
// our reference to node n is transferred to the file handle
mutex_unlock(&n->lock);
ref_fs(fs);
@@ -449,16 +471,28 @@ error:
}
void ref_file(fs_handle_t *file) {
+ dbg_printf("hREF++0x%p(%d)\n", file, file->refs);
+
+ mutex_lock(&file->lock);
+
file->refs++;
+
+ mutex_unlock(&file->lock);
}
void unref_file(fs_handle_t *file) {
+ dbg_printf("hREF--0x%p(%d)\n", file, file->refs);
+
+ mutex_lock(&file->lock);
+
file->refs--;
if (file->refs == 0) {
if (file->node->ops->close) file->node->ops->close(file);
unref_fs_node(file->node);
if (file->fs) unref_fs(file->fs);
free(file);
+ } else {
+ mutex_unlock(&file->lock);
}
}