void cpu_lwp_exit(void) { struct thread *td = curthread; struct pcb *pcb; npxexit(); pcb = td->td_pcb; /* Some i386 functionality was dropped */ KKASSERT(pcb->pcb_ext == NULL); /* * disable all hardware breakpoints */ if (pcb->pcb_flags & PCB_DBREGS) { reset_dbregs(); pcb->pcb_flags &= ~PCB_DBREGS; } td->td_gd->gd_cnt.v_swtch++; crit_enter_quick(td); if (td->td_flags & TDF_TSLEEPQ) tsleep_remove(td); lwkt_deschedule_self(td); lwkt_remove_tdallq(td); cpu_thread_exit(); }
/* * Userland override of lwkt_exit. The only difference is * the manipulation of gd->gd_num_threads; */ void lwkt_exit(void) { thread_t td = curthread; globaldata_t gd = mycpu; if (td->td_flags & TDF_VERBOSE) printf("kthread %p %s has exited\n", td, td->td_comm); crit_enter(); lwkt_deschedule_self(td); ++gd->gd_tdfreecount; if (td->td_flags & TDF_SYSTHREAD) --gd->gd_sys_threads; --gd->gd_num_threads; TAILQ_INSERT_TAIL(&gd->gd_tdfreeq, td, td_threadq); cpu_thread_exit(); }
void cpu_lwp_exit(void) { struct thread *td = curthread; struct pcb *pcb; struct pcb_ext *ext; /* * If we were using a private TSS do a forced-switch to ourselves * to switch back to the common TSS before freeing it. */ pcb = td->td_pcb; if ((ext = pcb->pcb_ext) != NULL) { crit_enter(); pcb->pcb_ext = NULL; lwkt_switch_return(td->td_switch(td)); crit_exit(); kmem_free(&kernel_map, (vm_offset_t)ext, ctob(IOPAGES + 1)); } user_ldt_free(pcb); if (pcb->pcb_flags & PCB_DBREGS) { /* * disable all hardware breakpoints */ reset_dbregs(); pcb->pcb_flags &= ~PCB_DBREGS; } td->td_gd->gd_cnt.v_swtch++; crit_enter_quick(td); if (td->td_flags & TDF_TSLEEPQ) tsleep_remove(td); lwkt_deschedule_self(td); lwkt_remove_tdallq(td); cpu_thread_exit(); }