if (__predict_true(lid == 0)) {
- /*
- * XXX: l_lid are expected to be unique (for a process)
- * if LWP_PIDLID is sometimes set this won't be true.
- * Once 2^31 threads have been allocated we have to
- * scan to ensure we allocate a unique value.
- */
- lid = ++p2->p_nlwpid;
- if (__predict_false(lid & LID_SCAN)) {
- lid = lwp_find_free_lid(lid, l2, p2);
+ if (p2->p_nlwps == 0 && l1->l_lid != 1) {
+ KASSERT(p2->p_nlwpid == 0);
+ /*
+ * XXX: When forking (p_nlwps == 0) copy
+ * the parent LID to keep the expectations
+ * of our runtime linker. Set LID_SCAN so
+ * that subsequent calls will search the
+ * LID space.
+ * Avoid this when the next LID (p_nlwpid+1)
+ * (== 1 after fork) is the same as the parent
+ * LID.
+ */
+ lid = l1->l_lid;
p2->p_nlwpid = lid | LID_SCAN;
- /* l2 as been inserted into p_lwps in order */
- goto skip_insert;
+ } else {
+ /*
+ * XXX: l_lid are expected to be unique (for a process)
+ * if LWP_PIDLID is sometimes set this won't be true.
+ * Once 2^31 threads have been allocated we have to
+ * scan to ensure we allocate a unique value.
+ */
+ lid = ++p2->p_nlwpid;
+ if (__predict_false(lid & LID_SCAN)) {
+ lid = lwp_find_free_lid(lid, l2, p2);
+ p2->p_nlwpid = lid | LID_SCAN;
+ /* l2 has been inserted into p_lwps in order */
+ goto skip_insert;
+ }
+ p2->p_nlwpid = lid;
}
- p2->p_nlwpid = lid;
}
LIST_INSERT_HEAD(&p2->p_lwps, l2, l_sibling);
skip_insert: