Index: kern_thread.c =================================================================== --- kern_thread.c (revision 213714) +++ kern_thread.c (working copy) @@ -361,6 +361,8 @@ td = curthread; p = td->td_proc; + KASSERT((td->td_flags & TDF_TIDHASH) == 0, + ("thread is still on hash table.")); PROC_SLOCK_ASSERT(p, MA_OWNED); mtx_assert(&Giant, MA_NOTOWNED); @@ -949,6 +951,9 @@ rw_rlock(&tidhash_lock); LIST_FOREACH(td, TIDHASH(tid), td_hash) { + KASSERT(TIDHASH(td->td_tid) == TIDHASH(tid), + ("process %p (pid %d), thread %p changed thread id.", + td->td_proc, td->td_proc->p_pid, td)); if (td->td_tid == tid) { if (pid != -1 && td->td_proc->p_pid != pid) { td = NULL; @@ -993,9 +998,29 @@ void tidhash_remove(struct thread *td) { +#ifdef INVARIANTS + struct thread *td2; + lwpid_t tid; +#endif + rw_wlock(&tidhash_lock); +#ifdef INVARIANTS thread_lock(td); if ((td->td_flags & TDF_TIDHASH) != 0) { + tid = td->td_tid; + LIST_FOREACH(td2, TIDHASH(tid), td_hash) { + if (td2 == td) + break; + } + thread_unlock(td); + KASSERT(td2 != NULL, + ("process %p (pid %d), thread %p changed thread id.", + td->td_proc, td->td_proc->p_pid, td)); + } else + thread_unlock(td); +#endif + thread_lock(td); + if ((td->td_flags & TDF_TIDHASH) != 0) { LIST_REMOVE(td, td_hash); td->td_flags &= ~TDF_TIDHASH; } Index: init_main.c =================================================================== --- init_main.c (revision 213714) +++ init_main.c (working copy) @@ -443,7 +443,6 @@ */ LIST_INSERT_HEAD(&allproc, p, p_list); LIST_INSERT_HEAD(PIDHASH(0), p, p_hash); - LIST_INSERT_HEAD(TIDHASH(0), td, td_hash); mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); p->p_pgrp = &pgrp0; LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash); @@ -462,6 +461,8 @@ STAILQ_INIT(&p->p_ktr); p->p_nice = NZERO; td->td_tid = PID_MAX + 1; + LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash); + td->td_flags |= TDF_TIDHASH; td->td_state = TDS_RUNNING; td->td_pri_class = PRI_TIMESHARE; td->td_user_pri = PUSER;