Use subr_unit to allocate thread ID's with.
Tested by: davidxu
This commit is contained in:
parent
00a6eab3e5
commit
2f7506bdfd
@ -103,31 +103,8 @@ SYSCTL_PROC(_kern_threads, OID_AUTO, virtual_cpu, CTLTYPE_INT|CTLFLAG_RW,
|
||||
0, sizeof(virtual_cpu), sysctl_kse_virtual_cpu, "I",
|
||||
"debug virtual cpus");
|
||||
|
||||
/*
|
||||
* Thread ID allocator. The allocator keeps track of assigned IDs by
|
||||
* using a bitmap. The bitmap is created in parts. The parts are linked
|
||||
* together.
|
||||
*/
|
||||
typedef u_long tid_bitmap_word;
|
||||
|
||||
#define TID_IDS_PER_PART 1024
|
||||
#define TID_IDS_PER_IDX (sizeof(tid_bitmap_word) << 3)
|
||||
#define TID_BITMAP_SIZE (TID_IDS_PER_PART / TID_IDS_PER_IDX)
|
||||
#define TID_MIN (PID_MAX + 1)
|
||||
|
||||
struct tid_bitmap_part {
|
||||
STAILQ_ENTRY(tid_bitmap_part) bmp_next;
|
||||
tid_bitmap_word bmp_bitmap[TID_BITMAP_SIZE];
|
||||
lwpid_t bmp_base;
|
||||
int bmp_free;
|
||||
};
|
||||
|
||||
static STAILQ_HEAD(, tid_bitmap_part) tid_bitmap =
|
||||
STAILQ_HEAD_INITIALIZER(tid_bitmap);
|
||||
static uma_zone_t tid_zone;
|
||||
|
||||
struct mtx tid_lock;
|
||||
MTX_SYSINIT(tid_lock, &tid_lock, "TID lock", MTX_DEF);
|
||||
static struct unrhdr *tid_unrhdr;
|
||||
|
||||
/*
|
||||
* Prepare a thread for use.
|
||||
@ -197,45 +174,10 @@ static int
|
||||
thread_init(void *mem, int size, int flags)
|
||||
{
|
||||
struct thread *td;
|
||||
struct tid_bitmap_part *bmp, *new;
|
||||
int bit, idx;
|
||||
|
||||
td = (struct thread *)mem;
|
||||
|
||||
mtx_lock(&tid_lock);
|
||||
STAILQ_FOREACH(bmp, &tid_bitmap, bmp_next) {
|
||||
if (bmp->bmp_free)
|
||||
break;
|
||||
}
|
||||
/* Create a new bitmap if we run out of free bits. */
|
||||
if (bmp == NULL) {
|
||||
mtx_unlock(&tid_lock);
|
||||
new = uma_zalloc(tid_zone, M_WAITOK);
|
||||
mtx_lock(&tid_lock);
|
||||
bmp = STAILQ_LAST(&tid_bitmap, tid_bitmap_part, bmp_next);
|
||||
if (bmp == NULL || bmp->bmp_free < TID_IDS_PER_PART/2) {
|
||||
/* 1=free, 0=assigned. This way we can use ffsl(). */
|
||||
memset(new->bmp_bitmap, ~0U, sizeof(new->bmp_bitmap));
|
||||
new->bmp_base = (bmp == NULL) ? TID_MIN :
|
||||
bmp->bmp_base + TID_IDS_PER_PART;
|
||||
new->bmp_free = TID_IDS_PER_PART;
|
||||
STAILQ_INSERT_TAIL(&tid_bitmap, new, bmp_next);
|
||||
bmp = new;
|
||||
new = NULL;
|
||||
}
|
||||
} else
|
||||
new = NULL;
|
||||
/* We have a bitmap with available IDs. */
|
||||
idx = 0;
|
||||
while (idx < TID_BITMAP_SIZE && bmp->bmp_bitmap[idx] == 0UL)
|
||||
idx++;
|
||||
bit = ffsl(bmp->bmp_bitmap[idx]) - 1;
|
||||
td->td_tid = bmp->bmp_base + idx * TID_IDS_PER_IDX + bit;
|
||||
bmp->bmp_bitmap[idx] &= ~(1UL << bit);
|
||||
bmp->bmp_free--;
|
||||
mtx_unlock(&tid_lock);
|
||||
if (new != NULL)
|
||||
uma_zfree(tid_zone, new);
|
||||
td->td_tid = alloc_unr(tid_unrhdr);
|
||||
|
||||
vm_thread_new(td, 0);
|
||||
cpu_thread_setup(td);
|
||||
@ -254,9 +196,6 @@ static void
|
||||
thread_fini(void *mem, int size)
|
||||
{
|
||||
struct thread *td;
|
||||
struct tid_bitmap_part *bmp;
|
||||
lwpid_t tid;
|
||||
int bit, idx;
|
||||
|
||||
td = (struct thread *)mem;
|
||||
turnstile_free(td->td_turnstile);
|
||||
@ -264,19 +203,7 @@ thread_fini(void *mem, int size)
|
||||
umtxq_free(td->td_umtxq);
|
||||
vm_thread_dispose(td);
|
||||
|
||||
STAILQ_FOREACH(bmp, &tid_bitmap, bmp_next) {
|
||||
if (td->td_tid >= bmp->bmp_base &&
|
||||
td->td_tid < bmp->bmp_base + TID_IDS_PER_PART)
|
||||
break;
|
||||
}
|
||||
KASSERT(bmp != NULL, ("No TID bitmap?"));
|
||||
mtx_lock(&tid_lock);
|
||||
tid = td->td_tid - bmp->bmp_base;
|
||||
idx = tid / TID_IDS_PER_IDX;
|
||||
bit = 1UL << (tid % TID_IDS_PER_IDX);
|
||||
bmp->bmp_bitmap[idx] |= bit;
|
||||
bmp->bmp_free++;
|
||||
mtx_unlock(&tid_lock);
|
||||
free_unr(tid_unrhdr, td->td_tid);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -362,11 +289,12 @@ void
|
||||
threadinit(void)
|
||||
{
|
||||
|
||||
mtx_init(&tid_lock, "TID lock", NULL, MTX_DEF);
|
||||
tid_unrhdr = new_unrhdr(PID_MAX + 1, INT_MAX, &tid_lock);
|
||||
|
||||
thread_zone = uma_zcreate("THREAD", sched_sizeof_thread(),
|
||||
thread_ctor, thread_dtor, thread_init, thread_fini,
|
||||
UMA_ALIGN_CACHE, 0);
|
||||
tid_zone = uma_zcreate("TID", sizeof(struct tid_bitmap_part),
|
||||
NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0);
|
||||
ksegrp_zone = uma_zcreate("KSEGRP", sched_sizeof_ksegrp(),
|
||||
ksegrp_ctor, NULL, NULL, NULL,
|
||||
UMA_ALIGN_CACHE, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user