diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index 2f5f8a58..4b87d1f7 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -1329,15 +1329,20 @@ done: mcs_rwlock_reader_lock_noirq(&tproc->update_lock, &updatelock); savelock = &tthread->sigpendinglock; head = &tthread->sigpending; - if(sig == SIGKILL || - (tproc->status != PS_EXITED && - tproc->status != PS_ZOMBIE && - tthread->status != PS_EXITED)){ + mcs_rwlock_reader_lock_noirq(&tproc->threads_lock, &lock); + if (tthread->status != PS_EXITED && + (sig == SIGKILL || + (tproc->status != PS_EXITED && tproc->status != PS_ZOMBIE))) { hold_thread(tthread); + if ((rc = hold_thread(tthread))) { + kprintf("%s: ERROR hold_thread returned %d,tid=%d\n", __FUNCTION__, rc, tthread->tid); + tthread = NULL; + } } else{ tthread = NULL; } + mcs_rwlock_reader_unlock_noirq(&tproc->threads_lock, &lock); mcs_rwlock_reader_unlock_noirq(&tproc->update_lock, &updatelock); mcs_rwlock_reader_unlock_noirq(&thash->lock[hash], &lock); } diff --git a/kernel/include/process.h b/kernel/include/process.h index 7c0b6f74..8eb8142c 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -575,9 +575,6 @@ struct process { int nr_processes; /* For partitioned execution */ }; -void hold_thread(struct thread *ftn); -void release_thread(struct thread *ftn); - /* * Scheduling policies */ @@ -753,7 +750,7 @@ struct thread *create_thread(unsigned long user_pc, struct thread *clone_thread(struct thread *org, unsigned long pc, unsigned long sp, int clone_flags); void destroy_thread(struct thread *thread); -void hold_thread(struct thread *thread); +int hold_thread(struct thread *thread); void release_thread(struct thread *thread); void flush_process_memory(struct process_vm *vm); void hold_process_vm(struct process_vm *vm); diff --git a/kernel/process.c b/kernel/process.c index 81856187..3a5da9f3 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -2571,14 +2571,15 @@ out: return error; } -void hold_thread(struct thread *thread) +int hold_thread(struct thread *thread) { if (thread->status == PS_EXITED) { - panic("hold_thread: already exited process"); + kprintf("hold_thread: ERROR: already exited process,tid=%d\n", thread->tid); + return -ESRCH; } ihk_atomic_inc(&thread->refcount); - return; + return 0; } void diff --git a/kernel/syscall.c b/kernel/syscall.c index f462c636..b8682fc4 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1004,13 +1004,13 @@ void terminate(int rc, int sig) sync_child_event(proc->monitoring_event); // clean up threads - mcs_rwlock_reader_lock(&proc->threads_lock, &lock); // conflict clone + mcs_rwlock_writer_lock(&proc->threads_lock, &lock); // conflict clone mcs_rwlock_writer_lock_noirq(&proc->update_lock, &updatelock); if (proc->status == PS_EXITED) { - mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock); - mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); preempt_disable(); mythread->status = PS_EXITED; + mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock); + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); release_thread(mythread); preempt_enable(); schedule(); @@ -1021,10 +1021,10 @@ void terminate(int rc, int sig) exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff); mythread->exit_status = exit_status; proc->status = PS_EXITED; - terminate_mcexec(rc, sig); - mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock); - mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); + + terminate_mcexec(rc, sig); mcs_rwlock_writer_lock(&proc->threads_lock, &lock); list_del(&mythread->siblings_list); @@ -1174,7 +1174,9 @@ void terminate(int rc, int sig) finalize_process(proc); preempt_disable(); + mcs_rwlock_writer_lock(&proc->threads_lock, &lock); mythread->status = PS_EXITED; + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); release_thread(mythread); release_process_vm(vm); preempt_enable(); @@ -5475,16 +5477,16 @@ do_exit(int code) FUTEX_WAKE, 1, 0, NULL, 0, 0, 1); } - mcs_rwlock_reader_lock(&proc->threads_lock, &lock); + mcs_rwlock_writer_lock(&proc->threads_lock, &lock); if(proc->status == PS_EXITED){ - mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); terminate(exit_status, 0); return; } preempt_disable(); thread->status = PS_EXITED; sync_child_event(thread->proc->monitoring_event); - mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); release_thread(thread); preempt_enable();