struct pcpu * uinet_pcpu_get(void) { int bound_cpu; /* * If the CPU binding is unknown, use PCPU data for CPU 0. */ bound_cpu = uhi_thread_bound_cpu(mp_ncpus); if (-1 == bound_cpu) return (&pcpup[0]); else return (&pcpup[bound_cpu]); }
void uinet_init_thread0(void) { struct thread *td; int cpuid; td = &thread0; td->td_proc = &proc0; KASSERT(sizeof(td->td_wchan) >= sizeof(uhi_thread_t), ("uinet_init_thread0: can't safely store host thread id")); td->td_wchan = (void *)uhi_thread_self(); cpuid = uhi_thread_bound_cpu(); td->td_oncpu = (cpuid == -1) ? 0 : cpuid; uinet_thread0.td = td; uhi_thread_set_thread_specific_data(&uinet_thread0); }
int uinet_initialize_thread(void) { struct uinet_thread *utd; struct thread *td; int cpuid; /* * uinet_shutdown() waits for a message from the shutdown thread * indicating shutdown is complete. If uinet_shutdown() is called * from a signal handler running in a thread context that is holding * a lock that the shutdown activity needs to acquire in order to * complete, deadlock will occur. Masking all signals in all * threads that use the uinet API prevents such a deadlock by * preventing all signal handlers (and thus any that might call * uinet_shutdown()) from running in the context of any thread that * might be holding a lock required by the shutdown thread. */ uhi_mask_all_signals(); utd = uhi_thread_get_thread_specific_data(); if (NULL == utd) { utd = uinet_thread_alloc(NULL); if (NULL == utd) return (ENOMEM); td = utd->td; KASSERT(sizeof(td->td_wchan) >= sizeof(uhi_thread_t), ("uinet_initialize_thread: can't safely store host thread id")); td->td_wchan = (void *)uhi_thread_self(); uhi_thread_set_thread_specific_data(utd); } else { td = utd->td; } cpuid = uhi_thread_bound_cpu(); td->td_oncpu = (cpuid == -1) ? 0 : cpuid; return (0); }