void rundown_thread(void) { struct kthread * thread = (struct kthread *) get_current_ethread(); struct kmutant * mutant; struct list_head * cur_entry; ktrace("\n"); local_irq_disable(); while (!list_empty(&thread->mutant_list_head)) { /* Get the Mutant */ cur_entry = thread->mutant_list_head.next; mutant = list_entry(cur_entry, struct kmutant, mutant_list_entry); /* check apc disable */ mutant->header.signal_state = 1; mutant->abandoned = 1; mutant->owner_thread = NULL; list_del(&mutant->mutant_list_entry); if(!list_empty(&mutant->header.wait_list_head)) { wait_test(&mutant->header, MUTANT_INCREMENT); } } local_irq_enable(); }
int main() { char p = 'F'; int ch = 0; printf("Hello world!Hello printf!\n"); //fork_test(); wait_test(); //run_pro_test(); //read_test(); return 0; }
int main(int argc, char **argv) { (void) printf("Congrats! You're running this executable.\n"); (void) printf("Now let's see how you handle the tests...\n"); mmap_test(); null_test(); zero_test(); brk_test(); fault_test(); wait_test(); cow_fork(); fork_test(); return 0; }
LONG STDCALL release_mutant(IN struct kmutant *Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait) { struct ethread *thread = get_current_ethread(); LONG prev; local_irq_disable(); prev = Mutant->header.signal_state; if (Abandon == FALSE) Mutant->header.signal_state++; else { Mutant->header.signal_state = 1; Mutant->abandoned = TRUE; } if (Mutant->header.signal_state == 1) { if (prev <= 0) { list_del(&Mutant->mutant_list_entry); thread->tcb.kernel_apc_disable += Mutant->apc_disable; } Mutant->owner_thread = NULL; if (!list_empty(&Mutant->header.wait_list_head)) wait_test(&Mutant->header, Increment); } if (Wait == FALSE) local_irq_enable(); else thread->tcb.wait_next = TRUE; return prev; }
void __exit_process(struct eprocess * process) { unsigned long old_state; ktrace("()\n"); /* close all handles associated with our process, this needs to be done * when the last thread still runs */ __destroy_handle_table(process->object_table, delete_handle_callback, process); /* remove all reserved area and mapped area */ remove_all_win32_area(&process->ep_reserved_head); remove_all_win32_area(&process->ep_mapped_head); /* FIXME: spin_lock_irq(&t); */ local_irq_disable(); #if 0 if (process->win32process) kfree(process->win32process); #endif if (process->ep_handle_info_table) { free_handle_info_table(process->ep_handle_info_table); kfree(process->ep_handle_info_table); process->ep_handle_info_table = NULL; } old_state = process->pcb.header.signal_state; process->pcb.header.signal_state = true; if ((!old_state) && !list_empty(&process->pcb.header.wait_list_head)) { /* Satisfy waits */ wait_test((struct dispatcher_header *)&process->pcb,IO_NO_INCREMENT); } local_irq_enable(); /* FIXME: spin_unlock_irq(&t); */ }
/* * notification of exit * - the exit_status is as sys_wait() would return * - notification includes fatal signals */ static void thread_exit(struct ethread *thread, int exit_status) { struct eprocess *process = thread->threads_process; BOOLEAN last; /* if Terminated, do nothing */ ktrace("thread %p, exit_status %ld\n", thread, thread->exit_status); thread->terminated = 1; /* Can't terminate a thread if it attached another process */ if (thread->tcb.apc_state_index) { return; } /* TODO: Lower to Passive Level */ /* Lock the Process before we modify its thread entries */ lock_process(process); list_del(&thread->thread_list_entry); /* TODO: close port */ /* TODO: Rundown Win32 Structures */ /* Set the last Thread Exit Status */ process->last_thread_exit_status = thread->exit_status; /* The last Thread shuts down the Process */ if ((last = list_empty(&process->thread_list_head))) { /* Save the Exit Time if not already done by NtTerminateProcess. This happens when the last thread just terminates without explicitly terminating the process. TODO */ #if 0 process->exit_time = thread->exit_time; #endif __exit_process(process); } #if 0 if (thread->tcb.win32thread) { kfree(thread->tcb.win32thread); thread->tcb.win32thread = NULL; } #endif /* Free the TEB, if last thread, teb is freed by exit() */ if (thread->tcb.teb && !last) { delete_teb(thread->tcb.teb); thread->tcb.teb = NULL; } list_del(&thread->tcb.thread_list_entry); /* Unlock the Process */ unlock_process(process); /* Rundown Mutexes */ rundown_thread(); /* Satisfy waits */ local_irq_disable(); thread->tcb.header.signal_state = true; if (!list_empty(&thread->tcb.header.wait_list_head)) wait_test((struct dispatcher_header *)&thread->tcb, IO_NO_INCREMENT); local_irq_enable(); } /* end thread_exit() */
int main(void) { fork_test(); wait_test(); return 0; }