--- Gnu-Mach/kern/thread.c 2020/09/02 04:36:57 1.1 +++ Gnu-Mach/kern/thread.c 2020/09/02 04:47:43 1.1.1.5 @@ -31,64 +31,53 @@ * Thread management primitives implementation. */ -#include -#include -#include -#include -#include -#include -#include -#include - +#include #include #include #include #include #include #include -#include "vm_param.h" +#include #include #include +#include +#include +#include #include -#include #include #include #include #include +#include #include #include #include -#include +#include +#include +#include #include +#include #include #include #include +#include #include /* for splsched */ +#include #include /* for MACHINE_STACK */ -#if NET_ATM -#include -#endif - thread_t active_threads[NCPUS]; vm_offset_t active_stacks[NCPUS]; -struct zone *thread_zone; +struct kmem_cache thread_cache; queue_head_t reaper_queue; decl_simple_lock_data(, reaper_lock) -extern int tick; - -extern void pcb_module_init(void); - /* private */ struct thread thread_template; #if MACH_DEBUG -void stack_init(vm_offset_t stack); /* forward */ -void stack_finalize(vm_offset_t stack); /* forward */ - #define STACK_MARKER 0xdeadbeefU boolean_t stack_check_usage = FALSE; decl_simple_lock_data(, stack_usage_lock) @@ -157,7 +146,7 @@ boolean_t stack_alloc_try( thread_t thread, void (*resume)(thread_t)) { - register vm_offset_t stack; + vm_offset_t stack; stack_lock(); stack = stack_free_list; @@ -216,7 +205,7 @@ void stack_alloc( * addresses of a stack given an address in the middle. */ - if (kmem_alloc_aligned(kernel_map, &stack, KERNEL_STACK_SIZE) + if (kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE) != KERN_SUCCESS) panic("stack_alloc"); @@ -238,7 +227,7 @@ void stack_alloc( void stack_free( thread_t thread) { - register vm_offset_t stack; + vm_offset_t stack; stack = stack_detach(thread); @@ -261,7 +250,7 @@ void stack_free( void stack_collect(void) { - register vm_offset_t stack; + vm_offset_t stack; spl_t s; s = splsched(); @@ -276,7 +265,7 @@ void stack_collect(void) #if MACH_DEBUG stack_finalize(stack); #endif /* MACH_DEBUG */ - kmem_free(kernel_map, stack, KERNEL_STACK_SIZE); + kmem_free(kmem_map, stack, KERNEL_STACK_SIZE); s = splsched(); stack_lock(); @@ -293,7 +282,7 @@ void stack_collect(void) */ void stack_privilege( - register thread_t thread) + thread_t thread) { /* * This implementation only works for the current thread. @@ -308,11 +297,8 @@ void stack_privilege( void thread_init(void) { - thread_zone = zinit( - sizeof(struct thread), - THREAD_MAX * sizeof(struct thread), - THREAD_CHUNK * sizeof(struct thread), - 0, "threads"); + kmem_cache_init(&thread_cache, "thread", sizeof(struct thread), 0, + NULL, NULL, NULL, 0); /* * Fill in a template thread for fast initialization. @@ -409,11 +395,11 @@ void thread_init(void) } kern_return_t thread_create( - register task_t parent_task, + task_t parent_task, thread_t *child_thread) /* OUT */ { - register thread_t new_thread; - register processor_set_t pset; + thread_t new_thread; + processor_set_t pset; if (parent_task == TASK_NULL) return KERN_INVALID_ARGUMENT; @@ -422,13 +408,15 @@ kern_return_t thread_create( * Allocate a thread and initialize static fields */ - new_thread = (thread_t) zalloc(thread_zone); + new_thread = (thread_t) kmem_cache_alloc(&thread_cache); if (new_thread == THREAD_NULL) return KERN_RESOURCE_SHORTAGE; *new_thread = thread_template; + record_time_stamp (&new_thread->creation_time); + /* * Initialize runtime-dependent fields */ @@ -446,10 +434,6 @@ kern_return_t thread_create( ipc_thread_init(new_thread); -#if NET_ATM - new_thread->nw_ep_waited = 0; -#endif - /* * Find the processor set for the parent task. */ @@ -546,7 +530,6 @@ kern_return_t thread_create( #endif /* HW_FOOTPRINT */ #if MACH_PCSAMPLE - new_thread->pc_sample.buffer = 0; new_thread->pc_sample.seqno = 0; new_thread->pc_sample.sampletypes = 0; #endif /* MACH_PCSAMPLE */ @@ -589,11 +572,11 @@ kern_return_t thread_create( unsigned int thread_deallocate_stack = 0; void thread_deallocate( - register thread_t thread) + thread_t thread) { spl_t s; - register task_t task; - register processor_set_t pset; + task_t task; + processor_set_t pset; time_value_t user_time, system_time; @@ -709,7 +692,7 @@ void thread_deallocate( * Clean up any machine-dependent resources. */ if ((thread->state & TH_SWAPPED) == 0) { - spl_t _s_ = splsched(); + splsched(); stack_free(thread); (void) splx(s); thread_deallocate_stack++; @@ -720,11 +703,11 @@ void thread_deallocate( evc_notify_abort(thread); pcb_terminate(thread); - zfree(thread_zone, (vm_offset_t) thread); + kmem_cache_free(&thread_cache, (vm_offset_t) thread); } void thread_reference( - register thread_t thread) + thread_t thread) { spl_t s; @@ -758,10 +741,10 @@ void thread_reference( * since it needs a kernel stack to execute.) */ kern_return_t thread_terminate( - register thread_t thread) + thread_t thread) { - register thread_t cur_thread = current_thread(); - register task_t cur_task; + thread_t cur_thread = current_thread(); + task_t cur_task; spl_t s; if (thread == THREAD_NULL) @@ -860,13 +843,32 @@ kern_return_t thread_terminate( * reference to itself. */ ipc_thread_terminate(thread); -#if NET_ATM - mk_waited_collect(thread); -#endif thread_deallocate(thread); return KERN_SUCCESS; } +kern_return_t thread_terminate_release( + thread_t thread, + task_t task, + mach_port_t thread_name, + mach_port_t reply_port, + vm_offset_t address, + vm_size_t size) +{ + if (task == NULL) + return KERN_INVALID_ARGUMENT; + + mach_port_deallocate(task->itk_space, thread_name); + + if (reply_port != MACH_PORT_NULL) + mach_port_destroy(task->itk_space, reply_port); + + if ((address != 0) || (size != 0)) + vm_deallocate(task->map, address, size); + + return thread_terminate(thread); +} + /* * thread_force_terminate: * @@ -876,9 +878,9 @@ kern_return_t thread_terminate( */ void thread_force_terminate( - register thread_t thread) + thread_t thread) { - boolean_t deallocate_here = FALSE; + boolean_t deallocate_here; spl_t s; ipc_thread_disable(thread); @@ -901,9 +903,6 @@ thread_force_terminate( (void) thread_halt(thread, TRUE); ipc_thread_terminate(thread); -#if NET_ATM - mk_waited_collect(thread); -#endif #if MACH_HOST thread_unfreeze(thread); @@ -921,11 +920,11 @@ thread_force_terminate( * */ kern_return_t thread_halt( - register thread_t thread, + thread_t thread, boolean_t must_halt) { - register thread_t cur_thread = current_thread(); - register kern_return_t ret; + thread_t cur_thread = current_thread(); + kern_return_t ret; spl_t s; if (thread == cur_thread) @@ -969,7 +968,7 @@ kern_return_t thread_halt( * operation can never cause a deadlock.) */ if (cur_thread->ast & AST_HALT) { - thread_wakeup_with_result((event_t)&cur_thread->wake_active, + thread_wakeup_with_result(TH_EV_WAKE_ACTIVE(cur_thread), THREAD_INTERRUPTED); thread_unlock(thread); thread_unlock(cur_thread); @@ -1007,7 +1006,7 @@ kern_return_t thread_halt( */ while ((thread->ast & AST_HALT) && (!(thread->state & TH_HALTED))) { thread->wake_active = TRUE; - thread_sleep((event_t) &thread->wake_active, + thread_sleep(TH_EV_WAKE_ACTIVE(thread), simple_lock_addr(thread->lock), TRUE); if (thread->state & TH_HALTED) { @@ -1046,7 +1045,7 @@ kern_return_t thread_halt( s = splsched(); thread_lock(thread); thread_ast_clear(thread, AST_HALT); - thread_wakeup_with_result((event_t)&thread->wake_active, + thread_wakeup_with_result(TH_EV_WAKE_ACTIVE(thread), THREAD_INTERRUPTED); thread_unlock(thread); (void) splx(s); @@ -1124,7 +1123,7 @@ kern_return_t thread_halt( } } -void walking_zombie(void) +void __attribute__((noreturn)) walking_zombie(void) { panic("the zombie walks!"); } @@ -1135,7 +1134,7 @@ void walking_zombie(void) */ void thread_halt_self(void) { - register thread_t thread = current_thread(); + thread_t thread = current_thread(); spl_t s; if (thread->ast & AST_TERMINATE) { @@ -1145,15 +1144,12 @@ void thread_halt_self(void) * reaper thread. */ ipc_thread_terminate(thread); -#if NET_ATM - mk_waited_collect(thread); -#endif thread_hold(thread); s = splsched(); simple_lock(&reaper_lock); - enqueue_tail(&reaper_queue, (queue_entry_t) thread); + enqueue_tail(&reaper_queue, &(thread->links)); simple_unlock(&reaper_lock); thread_lock(thread); @@ -1192,7 +1188,7 @@ void thread_halt_self(void) * suspends is maintained. */ void thread_hold( - register thread_t thread) + thread_t thread) { spl_t s; @@ -1214,11 +1210,11 @@ void thread_hold( */ kern_return_t thread_dowait( - register thread_t thread, + thread_t thread, boolean_t must_halt) { - register boolean_t need_wakeup; - register kern_return_t ret = KERN_SUCCESS; + boolean_t need_wakeup; + kern_return_t ret = KERN_SUCCESS; spl_t s; if (thread == current_thread()) @@ -1288,7 +1284,7 @@ thread_dowait( * Check for failure if interrupted. */ thread->wake_active = TRUE; - thread_sleep((event_t) &thread->wake_active, + thread_sleep(TH_EV_WAKE_ACTIVE(thread), simple_lock_addr(thread->lock), TRUE); thread_lock(thread); if ((current_thread()->wait_result != THREAD_AWAKENED) && @@ -1312,13 +1308,13 @@ thread_dowait( (void) splx(s); if (need_wakeup) - thread_wakeup((event_t) &thread->wake_active); + thread_wakeup(TH_EV_WAKE_ACTIVE(thread)); return ret; } void thread_release( - register thread_t thread) + thread_t thread) { spl_t s; @@ -1337,9 +1333,9 @@ void thread_release( } kern_return_t thread_suspend( - register thread_t thread) + thread_t thread) { - register boolean_t hold; + boolean_t hold; spl_t spl; if (thread == THREAD_NULL) @@ -1348,6 +1344,13 @@ kern_return_t thread_suspend( hold = FALSE; spl = splsched(); thread_lock(thread); + /* Wait for thread to get interruptible */ + while (thread->state & TH_UNINT) { + assert_wait(TH_EV_STATE(thread), TRUE); + thread_unlock(thread); + thread_block(NULL); + thread_lock(thread); + } if (thread->user_stop_count++ == 0) { hold = TRUE; thread->suspend_count++; @@ -1376,9 +1379,9 @@ kern_return_t thread_suspend( kern_return_t thread_resume( - register thread_t thread) + thread_t thread) { - register kern_return_t ret; + kern_return_t ret; spl_t s; if (thread == THREAD_NULL) @@ -1414,7 +1417,7 @@ kern_return_t thread_resume( * Return thread's machine-dependent state. */ kern_return_t thread_get_state( - register thread_t thread, + thread_t thread, int flavor, thread_state_t old_state, /* pointer to OUT array */ natural_t *old_state_count) /*IN/OUT*/ @@ -1438,7 +1441,7 @@ kern_return_t thread_get_state( * Change thread's machine-dependent state. */ kern_return_t thread_set_state( - register thread_t thread, + thread_t thread, int flavor, thread_state_t new_state, natural_t new_state_count) @@ -1459,7 +1462,7 @@ kern_return_t thread_set_state( } kern_return_t thread_info( - register thread_t thread, + thread_t thread, int flavor, thread_info_t thread_info_out, /* pointer to OUT array */ natural_t *thread_info_count) /*IN/OUT*/ @@ -1471,9 +1474,13 @@ kern_return_t thread_info( return KERN_INVALID_ARGUMENT; if (flavor == THREAD_BASIC_INFO) { - register thread_basic_info_t basic_info; + thread_basic_info_t basic_info; - if (*thread_info_count < THREAD_BASIC_INFO_COUNT) { + /* Allow *thread_info_count to be one smaller than the + usual amount, because creation_time is a new member + that some callers might not know about. */ + + if (*thread_info_count < THREAD_BASIC_INFO_COUNT - 1) { return KERN_INVALID_ARGUMENT; } @@ -1496,6 +1503,7 @@ kern_return_t thread_info( &basic_info->system_time); basic_info->base_priority = thread->priority; basic_info->cur_priority = thread->sched_pri; + basic_info->creation_time = thread->creation_time; /* * To calculate cpu_usage, first correct for timer rate, @@ -1513,12 +1521,11 @@ kern_return_t thread_info( (basic_info->cpu_usage * 1000000)/sched_usec; #endif /* SIMPLE_CLOCK */ + flags = 0; if (thread->state & TH_SWAPPED) - flags = TH_FLAGS_SWAPPED; - else if (thread->state & TH_IDLE) - flags = TH_FLAGS_IDLE; - else - flags = 0; + flags |= TH_FLAGS_SWAPPED; + if (thread->state & TH_IDLE) + flags |= TH_FLAGS_IDLE; if (thread->state & TH_HALTED) state = TH_STATE_HALTED; @@ -1548,11 +1555,12 @@ kern_return_t thread_info( thread_unlock(thread); splx(s); - *thread_info_count = THREAD_BASIC_INFO_COUNT; + if (*thread_info_count > THREAD_BASIC_INFO_COUNT) + *thread_info_count = THREAD_BASIC_INFO_COUNT; return KERN_SUCCESS; } else if (flavor == THREAD_SCHED_INFO) { - register thread_sched_info_t sched_info; + thread_sched_info_t sched_info; if (*thread_info_count < THREAD_SCHED_INFO_COUNT) { return KERN_INVALID_ARGUMENT; @@ -1594,7 +1602,7 @@ kern_return_t thread_info( } kern_return_t thread_abort( - register thread_t thread) + thread_t thread) { if (thread == THREAD_NULL || thread == current_thread()) { return KERN_INVALID_ARGUMENT; @@ -1685,10 +1693,10 @@ thread_t kernel_thread( * This kernel thread runs forever looking for threads to destroy * (when they request that they be destroyed, of course). */ -void reaper_thread_continue(void) +void __attribute__((noreturn)) reaper_thread_continue(void) { for (;;) { - register thread_t thread; + thread_t thread; spl_t s; s = splsched(); @@ -1803,12 +1811,12 @@ thread_unfreeze( void thread_doassign( - register thread_t thread, - register processor_set_t new_pset, + thread_t thread, + processor_set_t new_pset, boolean_t release_freeze) { - register processor_set_t pset; - register boolean_t old_empty, new_empty; + processor_set_t pset; + boolean_t old_empty, new_empty; boolean_t recompute_pri = FALSE; spl_t s; @@ -2111,8 +2119,8 @@ thread_policy( int data) { #if MACH_FIXPRI - register kern_return_t ret = KERN_SUCCESS; - register int temp; + kern_return_t ret = KERN_SUCCESS; + int temp; spl_t s; #endif /* MACH_FIXPRI */ @@ -2228,7 +2236,6 @@ thread_wire( void thread_collect_scan(void) { -#if 0 register thread_t thread, prev_thread; processor_set_t pset, prev_pset; @@ -2281,7 +2288,6 @@ void thread_collect_scan(void) thread_deallocate(prev_thread); if (prev_pset != PROCESSOR_SET_NULL) pset_deallocate(prev_pset); -#endif /* 0 */ } boolean_t thread_collect_allowed = TRUE; @@ -2315,7 +2321,7 @@ void consider_thread_collect(void) #if MACH_DEBUG vm_size_t stack_usage( - register vm_offset_t stack) + vm_offset_t stack) { int i; @@ -2332,7 +2338,7 @@ vm_size_t stack_usage( */ void stack_init( - register vm_offset_t stack) + vm_offset_t stack) { if (stack_check_usage) { int i; @@ -2348,7 +2354,7 @@ void stack_init( */ void stack_finalize( - register vm_offset_t stack) + vm_offset_t stack) { if (stack_check_usage) { vm_size_t used = stack_usage(stack); @@ -2409,7 +2415,7 @@ kern_return_t host_stack_usage( vm_size_t *maxusagep, vm_offset_t *maxstackp) { - unsigned int total; + natural_t total; vm_size_t maxusage; if (host == HOST_NULL) @@ -2441,8 +2447,8 @@ kern_return_t processor_set_stack_usage( vm_size_t maxusage; vm_offset_t maxstack; - register thread_t *threads; - register thread_t tmp_thread; + thread_t *threads; + thread_t tmp_thread; unsigned int actual; /* this many things */ unsigned int i; @@ -2560,7 +2566,7 @@ kern_return_t processor_set_stack_usage( void thread_stats(void) { - register thread_t thread; + thread_t thread; int total = 0, rpcreply = 0; queue_iterate(&default_pset.threads, thread, thread_t, pset_threads) {