From aa29fcda50b37273dfa86c55b58b0f1201315337 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 20 May 2022 23:06:14 -0700 Subject: [PATCH] Various tweaks and function name changes. Checkpoint. Works well --- emu/memory.c | 10 ++++++---- fs/fake-db.c | 4 ++-- fs/fake.c | 2 +- fs/real.c | 2 +- fs/sockrestart.c | 4 ++-- fs/tty-real.c | 6 +++--- jit/jit.c | 7 ++++++- kernel/calls.c | 12 ++++++------ kernel/errno.c | 2 +- kernel/signal.c | 2 +- kernel/task.c | 10 +++++----- linux/fakefs.c | 6 +++--- util/sync.h | 21 +++++++++++++++++++-- 13 files changed, 56 insertions(+), 32 deletions(-) diff --git a/emu/memory.c b/emu/memory.c index d80870e67e..a509383efb 100644 --- a/emu/memory.c +++ b/emu/memory.c @@ -59,8 +59,7 @@ void mem_destroy(struct mem *mem) { mem->pgdir = NULL; //mkemkemke Trying something here - //write_unlock(&mem->lock); - //lock_destroy(&mem->lock); + //write_unlock; write_unlock_and_destroy(&mem->lock); if(doEnableExtraLocking) @@ -193,6 +192,9 @@ int pt_unmap_always(struct mem *mem, page_t start, pages_t pages) { if (--data->refcount == 0) { // vdso wasn't allocated with mmap, it's just in our data segment if (data->data != vdso_data) { + //while(current->delay_task_delete_requests) { // Wait for now, task is in one or more critical sections + // nanosleep(&lock_pause, NULL); + // } int err = munmap(data->data, data->size); if (err != 0) die("munmap(%p, %lu) failed: %s", data->data, data->size, strerror(errno)); @@ -310,12 +312,12 @@ void *mem_ptr(struct mem *mem, addr_t addr, int type) { // TODO: Is P_WRITE really correct? The page shouldn't be writable without ptrace. entry->flags |= P_WRITE | P_COW; } + delay_task_delete_up_vote(current); #if ENGINE_JIT // get rid of any compiled blocks in this page jit_invalidate_page(mem->mmu.jit, page); #endif - delay_task_delete_up_vote(current); // if page is cow, ~~milk~~ copy it if (entry->flags & P_COW) { void *data = (char *) entry->data->data + entry->offset; @@ -384,6 +386,6 @@ void mem_coredump(struct mem *mem, const char *file) { return; } } - printk("dumped %d pages\n", pages); + printk("WARNING: dumped %d pages\n", pages); close(fd); } diff --git a/fs/fake-db.c b/fs/fake-db.c index b27bfcbcfd..41aed9db30 100644 --- a/fs/fake-db.c +++ b/fs/fake-db.c @@ -148,7 +148,7 @@ void path_rename(struct fakefs_db *fs, const char *src, const char *dst) { #if DEBUG_sql static int trace_callback(unsigned UNUSED(why), void *UNUSED(fuck), void *stmt, void *_sql) { char *sql = _sql; - printk("%d sql trace: %s %s\n", current ? current->pid : -1, sqlite3_expanded_sql(stmt), sql[0] == '-' ? sql : ""); + printk("WARNING: %d sql trace: %s %s\n", current ? current->pid : -1, sqlite3_expanded_sql(stmt), sql[0] == '-' ? sql : ""); return 0; } #endif @@ -173,7 +173,7 @@ extern int fakefs_migrate(struct fakefs_db *fs, int root_fd); int fake_db_init(struct fakefs_db *fs, const char *db_path, int root_fd) { int err = sqlite3_open_v2(db_path, &fs->db, SQLITE_OPEN_READWRITE, NULL); if (err != SQLITE_OK) { - printk("error opening database: %s\n", sqlite3_errmsg(fs->db)); + printk("ERROR: sqlite3 opening database: %s\n", sqlite3_errmsg(fs->db)); sqlite3_close(fs->db); return _EINVAL; } diff --git a/fs/fake.c b/fs/fake.c index 76ebd8e396..95a32cf7eb 100644 --- a/fs/fake.c +++ b/fs/fake.c @@ -376,7 +376,7 @@ static int fakefs_mount(struct mount *mount) { static int fakefs_umount(struct mount *mount) { int err = fake_db_deinit(&mount->fakefs); if (err != SQLITE_OK) { - printk("sqlite failed to close: %d\n", err); + printk("ERROR: sqlite failed to close: %d\n", err); } /* return realfs.umount(mount); */ return 0; diff --git a/fs/real.c b/fs/real.c index 331d104ac7..2cf9c5f22b 100644 --- a/fs/real.c +++ b/fs/real.c @@ -232,7 +232,7 @@ int realfs_poll(struct fd *fd) { p.revents &= ~POLLPRI; if (p.revents & POLLNVAL) { - printk("pollnval %d flags %d events %d revents %d\n", fd->real_fd, flags, p.events, p.revents); + printk("WARNING: pollnval %d flags %d events %d revents %d\n", fd->real_fd, flags, p.events, p.revents); // Seriously, fuck Darwin. I just want to poll on POLLIN|POLLOUT|POLLPRI. // But if there's almost any kind of error, you just get POLLNVAL back, // and no information about the bits that are in fact set. So ask for each diff --git a/fs/sockrestart.c b/fs/sockrestart.c index dfc64279a0..456512b837 100644 --- a/fs/sockrestart.c +++ b/fs/sockrestart.c @@ -100,12 +100,12 @@ void sockrestart_on_resume() { list_remove(&saved->saved); int new_sock = socket(saved->name_addr.sa_family, saved->type, saved->proto); if (new_sock < 0) { - printk("restarting socket(%d, %d, %d) failed: %s\n", + printk("WARNING: restarting socket(%d, %d, %d) failed: %s\n", saved->name_addr.sa_family, saved->type, saved->proto, strerror(errno)); goto thank_u_next; } if (bind(new_sock, (struct sockaddr *) &saved->name, saved->name_len) < 0) { - printk("rebinding socket failed: %s\n", strerror(errno)); + printk("WARNING: rebinding socket failed: %s\n", strerror(errno)); goto thank_u_next; } dup2(new_sock, saved->sock->real_fd); diff --git a/fs/tty-real.c b/fs/tty-real.c index b8bbb2070f..734e61b857 100644 --- a/fs/tty-real.c +++ b/fs/tty-real.c @@ -21,9 +21,9 @@ static void *real_tty_read_thread(void *_tty) { for (;;) { int err = read(STDIN_FILENO, &ch, 1); if (err != 1) { - printk("tty read returned %d\n", err); + printk("ERROR: tty read returned %d\n", err); if (err < 0) - printk("error: %s\n", strerror(errno)); + printk("ERROR:real_tty_read_thread() %s\n", strerror(errno)); continue; } if (ch == '\x1c') { @@ -128,7 +128,7 @@ static int real_tty_write(struct tty *tty, const void *buf, size_t len, bool UNU void real_tty_reset_term() { if (!real_tty_is_open) return; if (tcsetattr(STDIN_FILENO, TCSANOW, &old_termios) < 0 && errno != ENOTTY) { - printk("failed to reset terminal: %s\n", strerror(errno)); + printk("WARNING: failed to reset terminal: %s\n", strerror(errno)); abort(); } } diff --git a/jit/jit.c b/jit/jit.c index 21f3b7eab3..e11650ce15 100644 --- a/jit/jit.c +++ b/jit/jit.c @@ -117,6 +117,7 @@ static struct jit_block *jit_lookup(struct jit *jit, addr_t addr) { static struct jit_block *jit_block_compile(addr_t ip, struct tlb *tlb) { struct gen_state state; TRACE("%d %08x --- compiling:\n", current_pid(), ip); + gen_start(ip, &state); while (true) { if (!gen_step(&state, tlb)) @@ -230,7 +231,11 @@ static int cpu_step_to_interrupt(struct cpu_state *cpu, struct tlb *tlb) { TRACE("%d %08x --- cycle %ld\n", current_pid(), ip, frame->cpu.cycle); - interrupt = jit_enter(block, frame, tlb); + if(block != NULL) { + interrupt = jit_enter(block, frame, tlb); + } else { + interrupt = INT_NONE; // Try to recover. -mke + } if (interrupt == INT_NONE && ++frame->cpu.cycle % (1 << 10) == 0) interrupt = INT_TIMER; *cpu = frame->cpu; diff --git a/kernel/calls.c b/kernel/calls.c index dfe8f3b4c4..3c88d352df 100644 --- a/kernel/calls.c +++ b/kernel/calls.c @@ -263,11 +263,11 @@ void handle_interrupt(int interrupt) { if (interrupt == INT_SYSCALL) { unsigned syscall_num = cpu->eax; if (syscall_num >= NUM_SYSCALLS || syscall_table[syscall_num] == NULL) { - printk("%d(%s) missing syscall %d\n", current->pid, current->comm, syscall_num); + printk("ERROR: %d(%s) missing syscall %d\n", current->pid, current->comm, syscall_num); deliver_signal(current, SIGSYS_, SIGINFO_NIL); } else { if (syscall_table[syscall_num] == (syscall_t) syscall_stub) { - printk("%d(%s) stub syscall %d\n", current->pid, current->comm, syscall_num); + printk("WARNING: %d(%s) stub syscall %d\n", current->pid, current->comm, syscall_num); } if (syscall_table[syscall_num] == (syscall_t) syscall_stub_silent) { // Fail silently @@ -306,7 +306,7 @@ void handle_interrupt(int interrupt) { delay_task_delete_down_vote(current); read_unlock(¤t->mem->lock); if (ptr == NULL) { - printk("%d page fault on 0x%x at 0x%x\n", current->pid, cpu->segfault_addr, cpu->eip); + printk("ERROR: %d page fault on 0x%x at 0x%x\n", current->pid, cpu->segfault_addr, cpu->eip); struct siginfo_ info = { .code = mem_segv_reason(current->mem, cpu->segfault_addr), .fault.addr = cpu->segfault_addr, @@ -314,7 +314,7 @@ void handle_interrupt(int interrupt) { deliver_signal(current, SIGSEGV_, info); } } else if (interrupt == INT_UNDEFINED) { - printk("%d(%s) illegal instruction at 0x%x: ", current->pid, current->comm, cpu->eip); + printk("WARNING: %d(%s) illegal instruction at 0x%x: ", current->pid, current->comm, cpu->eip); for (int i = 0; i < 8; i++) { uint8_t b; if (user_get(cpu->eip + i, b)) @@ -342,7 +342,7 @@ void handle_interrupt(int interrupt) { }); unlock(&pids_lock); } else if (interrupt != INT_TIMER) { - printk("%d(%s) unhandled interrupt %d\n", current->pid, current->comm, interrupt); + printk("WARNING: %d(%s) unhandled interrupt %d\n", current->pid, current->comm, interrupt); sys_exit(interrupt); } @@ -372,7 +372,7 @@ void dump_maps() { } void dump_stack(int lines) { - printk("stack at %x, base at %x, ip at %x\n", current->cpu.esp, current->cpu.ebp, current->cpu.eip); + printk("WARNING: stack at %x, base at %x, ip at %x\n", current->cpu.esp, current->cpu.ebp, current->cpu.eip); for (int i = 0; i < lines*8; i++) { dword_t stackword; if (user_get(current->cpu.esp + (i * 4), stackword)) diff --git a/kernel/errno.c b/kernel/errno.c index 923c8b490d..f79f5945ba 100644 --- a/kernel/errno.c +++ b/kernel/errno.c @@ -94,7 +94,7 @@ int err_map(int err) { ERRCASE(EDQUOT) } #undef ERRCASE - printk("unknown error %d\n", err); + printk("ERROR: unknown error %d\n", err); return -(err | 0x1000); } diff --git a/kernel/signal.c b/kernel/signal.c index ea758025c0..c9081ae909 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -293,7 +293,7 @@ static void receive_signal(struct sighand *sighand, struct siginfo_ *info) { // install frame if (user_write(sp, &frame, frame_size)) { - printk("failed to install frame for %d at %#x\n", info->sig, sp); + printk("WARNING: failed to install frame for %d at %#x\n", info->sig, sp); deliver_signal(current, SIGSEGV_, SIGINFO_NIL); } diff --git a/kernel/task.c b/kernel/task.c index 204da63640..9078a0c546 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -278,7 +278,7 @@ void extra_lockf(dword_t pid) { time(&newest_extra_lock_time); // Initialize if((now - newest_extra_lock_time > maxl) && (extra_lock_queue_size)) { // If we have a lock, and there has been no activity for awhile, kill it - printk("ERROR: The newest_extra_lock time(lockf) has exceded %d seconds (%d). Resetting\n", maxl, now - newest_extra_lock_time); + printk("ERROR: The newest_extra_lock time(extra_lockf) has exceded %d seconds (%d). Resetting\n", maxl, now - newest_extra_lock_time); pthread_mutex_unlock(&extra_lock); pid = 0; extra_lock_queue_size = 0; @@ -294,14 +294,14 @@ void extra_lockf(dword_t pid) { nanosleep(&mylock_pause, &mylock_pause); //mylock_pause.tv_nsec+=10; if(count > 200000) { - printk("ERROR: Possible deadlock(lockf), aborted lock attempt(PID: %d Process: %s)\n",current_pid(), current_comm() ); + printk("ERROR: Possible deadlock(extra_lockf), aborted lock attempt(PID: %d Process: %s)\n",current_pid(), current_comm() ); return; } // Loop until lock works. Maybe this will help make the multithreading work? -mke } if(count > 100000) { - printk("WARNING: large lock attempt count(lockf(%d))\n",count); + printk("WARNING: large lock attempt count(extra_lockf(%d))\n",count); } time(&newest_extra_lock_time); // Update time extra_lock_pid = pid; //Save, we may need it later to make sure the lock gets removed if the pid is killed @@ -318,14 +318,14 @@ void extra_lockf(dword_t pid) { nanosleep(&mylock_pause, &mylock_pause); //mylock_pause.tv_nsec+=10; if(count > 200000) { - printk("ERROR: Possible deadlock(lockf), aborted lock attempt(PID: %d Process: %s)\n", current_pid(), current_comm() ); + printk("ERROR: Possible deadlock(extra_lockf), aborted lock attempt(PID: %d Process: %s)\n", current_pid(), current_comm() ); return; } // Loop until lock works. Maybe this will help make the multithreading work? -mke } if(count > 150000) { - printk("WARNING: large lock attempt count(lockf(%d))\n", count); + printk("WARNING: large lock attempt count(extra_lockf(%d))\n", count); } pthread_mutex_trylock(&extra_lock); time(&newest_extra_lock_time); // Update time diff --git a/linux/fakefs.c b/linux/fakefs.c index b0137faa84..9e93acee7a 100644 --- a/linux/fakefs.c +++ b/linux/fakefs.c @@ -93,7 +93,7 @@ static struct dentry *fakefs_lookup(struct inode *ino, struct dentry *dentry, un out: if (IS_ERR(child)) { db_rollback(&info->db); - printk("fakefs_lookup failed: %pe\n", child); + printk("ERROR: fakefs_lookup failed: %pe\n", child); } else { db_commit(&info->db); } @@ -534,7 +534,7 @@ static int read_inode(struct inode *ino) { ino->i_op = &fakefs_iops; break; default: - printk("read_inode: unexpected S_IFMT: %o\n", ino->i_mode & S_IFMT); + printk("ERROR: read_inode: unexpected S_IFMT: %o\n", ino->i_mode & S_IFMT); return -EIO; } return 0; @@ -569,7 +569,7 @@ static int fakefs_fill_super(struct super_block *sb, struct fs_context *fc) { db_begin(&info->db); root->i_ino = path_get_inode(&info->db, ""); if (root->i_ino == 0) { - printk("fakefs: could not find root inode\n"); + printk("ERROR: fakefs: could not find root inode\n"); db_rollback(&info->db); iput(root); return -EINVAL; diff --git a/util/sync.h b/util/sync.h index 86304d4c0e..7c51f48f1f 100644 --- a/util/sync.h +++ b/util/sync.h @@ -110,7 +110,24 @@ static inline void write_unlock_and_destroy(wrlock_t *lock); static inline void loop_lock_read(wrlock_t *lock) { unsigned count = 0; + long count_max = (255000 - lock_pause.tv_nsec); // As sleep time increases, decrease acceptable loops. -mke while(pthread_rwlock_tryrdlock(&lock->l)) { + count++; + if(lock->val > 10000) { // Housten, we have a problem. most likely the associated task has been reaped. Ugh --mke + printk("ERROR: loop_lock_read() failure. Pending read locks > 1000, loops = %d. Faking it to make it.\n", count); + _read_unlock(lock); + lock->val = 0; + loop_lock_read(lock); + pthread_mutex_unlock(&nested_lock); + return; + } else if(count > count_max) { + printk("ERROR: loop_lock_read() tries excede %d, dealing with likely deadlock.\n", count_max); + _read_unlock(lock); + lock->val = 0; + loop_lock_read(lock); + pthread_mutex_unlock(&nested_lock); + return; + } pthread_mutex_unlock(&nested_lock); nanosleep(&lock_pause, NULL); nested_lockf(count); @@ -134,13 +151,13 @@ static inline void loop_lock_write(wrlock_t *lock) { printk("ERROR: loop_lock_write() tries excede %d, dealing with likely deadlock.\n", count_max); _read_unlock(lock); lock->val = 0; - pthread_mutex_unlock(&nested_lock); pthread_rwlock_wrlock(&lock->l); + pthread_mutex_unlock(&nested_lock); return; } pthread_mutex_unlock(&nested_lock); nanosleep(&lock_pause, NULL); - unsigned count = 0; + unsigned count = 0; // This is a different scope from the 'count' above nested_lockf(count); } }