--- Gnu-Mach/kern/thread.c 2020/09/02 04:47:43 1.1.1.5 +++ Gnu-Mach/kern/thread.c 2020/09/02 04:54:10 1.1.1.8 @@ -70,6 +70,7 @@ thread_t active_threads[NCPUS]; vm_offset_t active_stacks[NCPUS]; struct kmem_cache thread_cache; +struct kmem_cache thread_stack_cache; queue_head_t reaper_queue; decl_simple_lock_data(, reaper_lock) @@ -124,10 +125,6 @@ vm_offset_t stack_free_list; /* splsche unsigned int stack_free_count = 0; /* splsched only */ unsigned int stack_free_limit = 1; /* patchable */ -unsigned int stack_alloc_hits = 0; /* debugging */ -unsigned int stack_alloc_misses = 0; /* debugging */ -unsigned int stack_alloc_max = 0; /* debugging */ - /* * The next field is at the base of the stack, * so the low end is left unsullied. @@ -160,10 +157,10 @@ boolean_t stack_alloc_try( if (stack != 0) { stack_attach(thread, stack, resume); - stack_alloc_hits++; + counter(c_stack_alloc_hits++); return TRUE; } else { - stack_alloc_misses++; + counter(c_stack_alloc_misses++); return FALSE; } } @@ -175,7 +172,7 @@ boolean_t stack_alloc_try( * May block. */ -void stack_alloc( +kern_return_t stack_alloc( thread_t thread, void (*resume)(thread_t)) { @@ -199,22 +196,15 @@ void stack_alloc( (void) splx(s); if (stack == 0) { - /* - * Kernel stacks should be naturally aligned, - * so that it is easy to find the starting/ending - * addresses of a stack given an address in the middle. - */ - - if (kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE) - != KERN_SUCCESS) - panic("stack_alloc"); - + stack = kmem_cache_alloc(&thread_stack_cache); + assert(stack != 0); #if MACH_DEBUG stack_init(stack); #endif /* MACH_DEBUG */ } stack_attach(thread, stack, resume); + return KERN_SUCCESS; } /* @@ -235,8 +225,11 @@ void stack_free( stack_lock(); stack_next(stack) = stack_free_list; stack_free_list = stack; - if (++stack_free_count > stack_alloc_max) - stack_alloc_max = stack_free_count; + stack_free_count += 1; +#if MACH_COUNTERS + if (stack_free_count > c_stack_alloc_max) + c_stack_alloc_max = stack_free_count; +#endif /* MACH_COUNTERS */ stack_unlock(); } } @@ -265,7 +258,7 @@ void stack_collect(void) #if MACH_DEBUG stack_finalize(stack); #endif /* MACH_DEBUG */ - kmem_free(kmem_map, stack, KERNEL_STACK_SIZE); + kmem_cache_free(&thread_stack_cache, stack); s = splsched(); stack_lock(); @@ -298,7 +291,15 @@ void stack_privilege( void thread_init(void) { kmem_cache_init(&thread_cache, "thread", sizeof(struct thread), 0, - NULL, NULL, NULL, 0); + NULL, 0); + /* + * Kernel stacks should be naturally aligned, + * so that it is easy to find the starting/ending + * addresses of a stack given an address in the middle. + */ + kmem_cache_init(&thread_stack_cache, "thread_stack", + KERNEL_STACK_SIZE, KERNEL_STACK_SIZE, + NULL, 0); /* * Fill in a template thread for fast initialization. @@ -341,7 +342,7 @@ void thread_init(void) /* thread_template.sched_stamp (later) */ thread_template.recover = (vm_offset_t) 0; - thread_template.vm_privilege = FALSE; + thread_template.vm_privilege = 0; thread_template.user_stop_count = 1; @@ -430,7 +431,7 @@ kern_return_t thread_create( * Create a pcb. The kernel stack is created later, * when the thread is swapped-in. */ - pcb_init(new_thread); + pcb_init(parent_task, new_thread); ipc_thread_init(new_thread); @@ -1132,7 +1133,7 @@ void __attribute__((noreturn)) walking_z * Thread calls this routine on exit from the kernel when it * notices a halt request. */ -void thread_halt_self(void) +void thread_halt_self(continuation_t continuation) { thread_t thread = current_thread(); spl_t s; @@ -1173,7 +1174,7 @@ void thread_halt_self(void) thread_unlock(thread); splx(s); counter(c_thread_halt_self_block++); - thread_block(thread_exception_return); + thread_block(continuation); /* * thread_release resets TH_HALTED. */ @@ -1348,7 +1349,7 @@ kern_return_t thread_suspend( while (thread->state & TH_UNINT) { assert_wait(TH_EV_STATE(thread), TRUE); thread_unlock(thread); - thread_block(NULL); + thread_block(thread_no_continuation); thread_lock(thread); } if (thread->user_stop_count++ == 0) { @@ -1424,6 +1425,12 @@ kern_return_t thread_get_state( { kern_return_t ret; +#if defined(__i386__) || defined(__x86_64__) + if (flavor == i386_DEBUG_STATE && thread == current_thread()) + /* This state can be obtained directly for the curren thread. */ + return thread_getstatus(thread, flavor, old_state, old_state_count); +#endif + if (thread == THREAD_NULL || thread == current_thread()) { return KERN_INVALID_ARGUMENT; } @@ -1448,6 +1455,12 @@ kern_return_t thread_set_state( { kern_return_t ret; +#if defined(__i386__) || defined(__x86_64__) + if (flavor == i386_DEBUG_STATE && thread == current_thread()) + /* This state can be set directly for the curren thread. */ + return thread_setstatus(thread, flavor, new_state, new_state_count); +#endif + if (thread == THREAD_NULL || thread == current_thread()) { return KERN_INVALID_ARGUMENT; } @@ -1503,7 +1516,8 @@ 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; + read_time_stamp(&thread->creation_time, + &basic_info->creation_time); /* * To calculate cpu_usage, first correct for timer rate, @@ -1667,9 +1681,13 @@ thread_t kernel_thread( continuation_t start, void * arg) { + kern_return_t kr; thread_t thread; - (void) thread_create(task, &thread); + kr = thread_create(task, &thread); + if (kr != KERN_SUCCESS) + return THREAD_NULL; + /* release "extra" ref that thread_create gave us */ thread_deallocate(thread); thread_start(thread, start); @@ -1974,6 +1992,9 @@ kern_return_t thread_get_assignment( thread_t thread, processor_set_t *pset) { + if (thread == THREAD_NULL) + return KERN_INVALID_ARGUMENT; + *pset = thread->processor_set; pset_reference(*pset); return KERN_SUCCESS; @@ -2212,11 +2233,11 @@ thread_wire( thread_lock(thread); if (wired) { - thread->vm_privilege = TRUE; + thread->vm_privilege = 1; stack_privilege(thread); } else { - thread->vm_privilege = FALSE; + thread->vm_privilege = 0; /*XXX stack_unprivilege(thread); */ thread->stack_privilege = 0; } @@ -2323,7 +2344,7 @@ void consider_thread_collect(void) vm_size_t stack_usage( vm_offset_t stack) { - int i; + unsigned i; for (i = 0; i < KERNEL_STACK_SIZE/sizeof(unsigned int); i++) if (((unsigned int *)stack)[i] != STACK_MARKER) @@ -2341,7 +2362,7 @@ void stack_init( vm_offset_t stack) { if (stack_check_usage) { - int i; + unsigned i; for (i = 0; i < KERNEL_STACK_SIZE/sizeof(unsigned int); i++) ((unsigned int *)stack)[i] = STACK_MARKER;