diff --git a/emu/memory.c b/emu/memory.c index 06a457d144..a6100eb301 100644 --- a/emu/memory.c +++ b/emu/memory.c @@ -72,7 +72,6 @@ void mem_destroy(struct mem *mem) { } free(mem->pgdir); - mem->pgdir = NULL; //mkemkemke Trying something here write_unlock_and_destroy(&mem->lock); diff --git a/fs/proc/pid.c b/fs/proc/pid.c index 9d02d72050..d2a1547c05 100644 --- a/fs/proc/pid.c +++ b/fs/proc/pid.c @@ -85,7 +85,9 @@ static int proc_pid_stat_show(struct proc_entry *entry, struct proc_data *buf) { // bunch of shit that can only be accessed by a debugger proc_printf(buf, "%lu ", 0l); // startcode proc_printf(buf, "%lu ", 0l); // endcode + mem_ref_cnt_mod(&task->mm->mem, 1); proc_printf(buf, "%lu ", task->mm ? task->mm->stack_start : 0); + mem_ref_cnt_mod(&task->mm->mem, -1); proc_printf(buf, "%lu ", 0l); // kstkesp proc_printf(buf, "%lu ", 0l); // kstkeip @@ -279,7 +281,7 @@ static bool proc_pid_fd_readdir(struct proc_entry *entry, unsigned long *index, lock(&task->files->lock, 0); while (*index < task->files->size && task->files->files[*index] == NULL) (*index)++; - fd_t f = (*index)++; + fd_t f = (int)(*index)++; bool any_left = (unsigned) f < task->files->size; unlock(&task->files->lock); proc_put_task(task); @@ -307,21 +309,26 @@ static int proc_pid_fd_readlink(struct proc_entry *entry, char *buf) { static int proc_pid_exe_readlink(struct proc_entry *entry, char *buf) { struct task *task = proc_get_task(entry); - if ((task == NULL) || task->exiting == true) + if ((task == NULL) || task->exiting == true) { return _ESRCH; + } + task_ref_cnt_mod(task, 1); lock(&task->general_lock, 0); + task->mm->exefile->refcount++; int err = generic_getpath(task->mm->exefile, buf); + task->mm->exefile->refcount--; unlock(&task->general_lock); + task_ref_cnt_mod(task, -1); proc_put_task(task); return err; } static void proc_pid_task_getname(struct proc_entry *entry, char *buf) { - sprintf(buf, "%d", entry->pid); + snprintf(buf, sizeof(buf), "%d", entry->pid); } static int proc_pid_task_readlink(struct proc_entry *entry, char *buf) { - sprintf(buf, "/proc/%d", entry->pid); + snprintf(buf, sizeof(buf), "/proc/%d", entry->pid); return 0; } diff --git a/iSH-AOK.xcodeproj/project.pbxproj b/iSH-AOK.xcodeproj/project.pbxproj index 78ff01c86a..c1c835db8a 100644 --- a/iSH-AOK.xcodeproj/project.pbxproj +++ b/iSH-AOK.xcodeproj/project.pbxproj @@ -599,7 +599,6 @@ 5D8ACEFB284CE096003C50D3 /* sys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sys.h; sourceTree = ""; }; 5D8ACEFC284CE096003C50D3 /* sys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sys.c; sourceTree = ""; }; 5D8C94D3287E53AD0095EDEE /* fp_sync.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fp_sync.c; sourceTree = ""; }; - 5D8CEFF92894C81400D24ED8 /* resource_locking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resource_locking.h; sourceTree = ""; }; 5D8CFA842B1198B300D50E57 /* RTCDevice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RTCDevice.m; sourceTree = ""; }; 5D8CFA882B1198DB00D50E57 /* RTCDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RTCDevice.h; sourceTree = ""; }; 5D9897CE28B6B953003D3670 /* AppStore.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = AppStore.xcconfig; sourceTree = ""; }; @@ -1145,7 +1144,6 @@ BB7D933C2087C2880008DA78 /* kernel */ = { isa = PBXGroup; children = ( - 5D8CEFF92894C81400D24ED8 /* resource_locking.h */, 497F6C9F254E5C9800C82F46 /* calls.c */, 497F6C7B254E5C9700C82F46 /* calls.h */, 497F6C82254E5C9700C82F46 /* elf.h */, diff --git a/jit/jit.c b/jit/jit.c index 55ea871feb..f7fc77e2e0 100644 --- a/jit/jit.c +++ b/jit/jit.c @@ -37,11 +37,12 @@ struct jit *jit_new(struct mmu *mmu) { void jit_free(struct jit *jit) { if (!jit) return; + struct task* safe = current; - bool signal_pending = !!(current->pending & ~current->blocked); - while((task_ref_cnt_get(current, 0) > 2) || (locks_held_count(current)) || (signal_pending)) { // Wait for now, task is in one or more critical sections, and/or has locks, or signals in flight + bool signal_pending = !!(safe->pending & ~safe->blocked); + while((task_ref_cnt_get(safe, 0) > 3) || (locks_held_count(safe)) || (signal_pending)) { // Wait for now, task is in one or more critical sections, and/or has locks, or signals in flight nanosleep(&lock_pause, NULL); - signal_pending = current->blocked; + signal_pending = safe->blocked; } lock(&jit->lock, 0); for (size_t i = 0; i < jit->hash_size; i++) { diff --git a/kernel/exec.c b/kernel/exec.c index 59d21a7b3d..b495ad6294 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -153,7 +153,7 @@ static addr_t find_hole_for_elf(struct elf_header *header, struct prg_header *ph static intptr_t elf_exec(struct fd *fd, const char *file, struct exec_args argv, struct exec_args envp) { intptr_t err = 0; - + // read the headers struct elf_header header; if ((err = read_header(fd, &header)) < 0) @@ -161,7 +161,7 @@ static intptr_t elf_exec(struct fd *fd, const char *file, struct exec_args argv, struct prg_header *ph; if ((err = read_prg_headers(fd, header, &ph)) < 0) return err; - + // look for an interpreter char *interp_name = NULL; struct fd *interp_fd = NULL; @@ -175,19 +175,19 @@ static intptr_t elf_exec(struct fd *fd, const char *file, struct exec_args argv, err = _EINVAL; goto out_free_interp; } - + interp_name = malloc(ph[i].filesize); err = _ENOMEM; if (interp_name == NULL) goto out_free_ph; - + // read the interpreter name out of the file err = _EIO; if (fd->ops->lseek(fd, ph[i].offset, SEEK_SET) < 0) goto out_free_interp; if (fd->ops->read(fd, interp_name, ph[i].filesize) != ph[i].filesize) goto out_free_interp; - + // open interpreter and read headers interp_fd = generic_open(interp_name, O_RDONLY, 0); if (IS_ERR(interp_fd)) { @@ -203,7 +203,7 @@ static intptr_t elf_exec(struct fd *fd, const char *file, struct exec_args argv, goto out_free_interp; } } - + // free the process's memory. // from this point on, if any error occurs the process will have to be // killed before it even starts. please don't be too sad about it, it's @@ -213,6 +213,9 @@ static intptr_t elf_exec(struct fd *fd, const char *file, struct exec_args argv, // pointer before it's released and then try to lock it after it's // released. lock(¤t->general_lock, 0); + while(current->mm->mem.reference.count) { + nanosleep(&lock_pause, NULL); + } mm_release(current->mm); task_set_mm(current, mm_new()); unlock(¤t->general_lock); diff --git a/kernel/exit.c b/kernel/exit.c index 42173f7d49..0f3d915c9c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -20,7 +20,7 @@ static void halt_system(void); // Checks if a task's thread group can be exited by waiting for the task's reference count // to drop and checking if it holds any locks. static bool exit_tgroup(struct task *task) { - while((task_ref_cnt_get(task, 0) > 2) || (locks_held_count(task))) { // Wait for now, task is in one or more critical sections, and/or has locks + while((task_ref_cnt_get(task, 0) > 3) || (locks_held_count(task))) { // Wait for now, task is in one or more critical sections, and/or has locks nanosleep(&lock_pause, NULL); } struct tgroup *group = task->group; @@ -172,11 +172,13 @@ noreturn void do_exit_group(int status) { unlock(&pids_lock); unlock(&group->lock); - struct task *foo = current; // debugging - if(current->pid <= MAX_PID) // abort if crazy. -mke - do_exit(current, status); + struct task *safe = current; // debugging + if(safe->pid <= MAX_PID) {// abort if crazy. -mke + task_ref_cnt_mod(safe, 1); // No need to decrement, since we aren't coming back. + do_exit(safe, status); + } - task_ref_cnt_mod(current, -1); + task_ref_cnt_mod(safe, -1); unlock(&pids_lock); // Shouldn't get here pthread_exit(NULL); } @@ -297,8 +299,9 @@ int do_wait(int idtype, pid_t_ id, struct siginfo_ *info, struct rusage_ *rusage if (options & ~(WNOHANG_|WUNTRACED_|WEXITED_|WCONTINUED_|WNOWAIT_|__WALL_)) return _EINVAL; + struct task *safe = current; // Odd things seem to happeen to current sometimes, safe the pointer and use it complex_lockt(&pids_lock, 0); - task_ref_cnt_mod(current, 1); + task_ref_cnt_mod(safe, 1); int err; bool got_signal = false; @@ -307,9 +310,9 @@ int do_wait(int idtype, pid_t_ id, struct siginfo_ *info, struct rusage_ *rusage // look for a zombie child bool no_children = true; struct task *parent; - list_for_each_entry(¤t->group->threads, parent, group_links) { + list_for_each_entry(&safe->group->threads, parent, group_links) { struct task *task; - list_for_each_entry(¤t->children, task, siblings) { + list_for_each_entry(&safe->children, task, siblings) { if (!task_is_leader(task)) continue; if (idtype == P_PGID_ && task->group->pgid != id) @@ -348,7 +351,7 @@ int do_wait(int idtype, pid_t_ id, struct siginfo_ *info, struct rusage_ *rusage goto error; // no matching zombie found, wait for one - if (wait_for(¤t->group->child_exit, &pids_lock, NULL)) { + if (wait_for(&safe->group->child_exit, &pids_lock, NULL)) { // maybe we got a SIGCHLD! go through the loop one more time to make // sure the newly exited process is returned in that case. got_signal = true; @@ -358,12 +361,12 @@ int do_wait(int idtype, pid_t_ id, struct siginfo_ *info, struct rusage_ *rusage info->sig = SIGCHLD_; found_something: - task_ref_cnt_mod(current, -1); + task_ref_cnt_mod(safe, -1); unlock(&pids_lock); return 0; error: - task_ref_cnt_mod(current, -1); + task_ref_cnt_mod(safe, -1); unlock(&pids_lock); return err; } diff --git a/kernel/mmap.c b/kernel/mmap.c index f9ed3f3f23..7cd08d8f74 100644 --- a/kernel/mmap.c +++ b/kernel/mmap.c @@ -42,6 +42,8 @@ void mm_retain(struct mm *mm) { } void mm_release(struct mm *mm) { + struct task* safe; + safe = current; if (--mm->refcount == 0) { if (mm->exefile != NULL) fd_close(mm->exefile); @@ -51,7 +53,7 @@ void mm_release(struct mm *mm) { } mem_destroy(&mm->mem); - while(task_ref_cnt_get(current, 1) > 2) { //FIXME: Should now unlock after mem_destroy + while(task_ref_cnt_get(safe, 1) > 3) { //FIXME: Should now unlock after mem_destroy nanosleep(&lock_pause, NULL); } diff --git a/kernel/task.c b/kernel/task.c index df0a9f8ae0..6357416848 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -124,8 +124,10 @@ dword_t get_count_of_blocked_tasks(void) { struct pid *pid_entry; complex_lockt(&pids_lock, 0); list_for_each_entry(&alive_pids_list, pid_entry, alive) { - if (pid_entry->task->io_block) { - res++; + if(pid_entry->task != NULL) { // It + if (pid_entry->task->io_block) { + res++; + } } } // task_ref_cnt_mod(current, -1); diff --git a/util/rw_locks.h b/util/rw_locks.h index 6beb86dae9..8e25b2bb5a 100644 --- a/util/rw_locks.h +++ b/util/rw_locks.h @@ -214,12 +214,14 @@ static inline void write_unlock_and_destroy(wrlock_t *lock) { } static inline void read_unlock_and_destroy(wrlock_t *lock) { + task_ref_cnt_mod(current, 1); atomic_l_lockf("ruad_lock", 0); if(trylockw(lock)) // It should be locked, but just in case. Likely masking underlying issue. -mke _read_unlock(lock); _lock_destroy(lock); atomic_l_unlockf(); + task_ref_cnt_mod(current, -1); } static inline int trylockw(wrlock_t *lock) {