diff options
Diffstat (limited to 'src/kernel/user')
-rw-r--r-- | src/kernel/user/ipc.c | 7 | ||||
-rw-r--r-- | src/kernel/user/process.c | 66 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 2 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 34 |
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); } } |