--- Gnu-Mach/kern/thread.c 2020/09/02 04:36:57 1.1 +++ Gnu-Mach/kern/thread.c 2020/09/02 04:45:22 1.1.1.4 @@ -31,55 +31,47 @@ * 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 /* 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 */ @@ -216,7 +208,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"); @@ -276,7 +268,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(); @@ -308,11 +300,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. @@ -422,13 +411,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 +437,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 +533,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 */ @@ -709,7 +695,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,7 +706,7 @@ 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( @@ -860,9 +846,6 @@ 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; } @@ -878,7 +861,7 @@ void thread_force_terminate( register thread_t thread) { - boolean_t deallocate_here = FALSE; + boolean_t deallocate_here; spl_t s; ipc_thread_disable(thread); @@ -901,9 +884,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); @@ -1145,9 +1125,6 @@ void thread_halt_self(void) * reaper thread. */ ipc_thread_terminate(thread); -#if NET_ATM - mk_waited_collect(thread); -#endif thread_hold(thread); @@ -1348,6 +1325,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(&thread->state, TRUE); + thread_unlock(thread); + thread_block(NULL); + thread_lock(thread); + } if (thread->user_stop_count++ == 0) { hold = TRUE; thread->suspend_count++; @@ -1473,7 +1457,11 @@ kern_return_t thread_info( if (flavor == THREAD_BASIC_INFO) { register 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 +1484,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 +1502,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,7 +1536,8 @@ 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) { @@ -2409,7 +2398,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)