MFp4:
The unit number allocator reuses ID too fast, this may hide bugs in other code, add a ring buffer to delay freeing a thread ID.
This commit is contained in:
parent
171976dba2
commit
f88dac0410
@ -81,15 +81,54 @@ MTX_SYSINIT(zombie_lock, &zombie_lock, "zombie lock", MTX_SPIN);
|
||||
|
||||
static void thread_zombie(struct thread *);
|
||||
|
||||
#define TID_BUFFER_SIZE 1024
|
||||
|
||||
struct mtx tid_lock;
|
||||
static struct unrhdr *tid_unrhdr;
|
||||
|
||||
static lwpid_t tid_buffer[TID_BUFFER_SIZE];
|
||||
static int tid_head, tid_tail;
|
||||
static MALLOC_DEFINE(M_TIDHASH, "tidhash", "thread hash");
|
||||
|
||||
struct tidhashhead *tidhashtbl;
|
||||
u_long tidhash;
|
||||
struct rwlock tidhash_lock;
|
||||
|
||||
static lwpid_t
|
||||
tid_alloc(void)
|
||||
{
|
||||
lwpid_t tid;
|
||||
|
||||
tid = alloc_unr(tid_unrhdr);
|
||||
if (tid != -1)
|
||||
return (tid);
|
||||
mtx_lock(&tid_lock);
|
||||
if (tid_head == tid_tail) {
|
||||
mtx_unlock(&tid_lock);
|
||||
return (-1);
|
||||
}
|
||||
tid = tid_buffer[tid_head++];
|
||||
tid_head %= TID_BUFFER_SIZE;
|
||||
mtx_unlock(&tid_lock);
|
||||
return (tid);
|
||||
}
|
||||
|
||||
static void
|
||||
tid_free(lwpid_t tid)
|
||||
{
|
||||
lwpid_t tmp_tid = -1;
|
||||
|
||||
mtx_lock(&tid_lock);
|
||||
if ((tid_tail + 1) % TID_BUFFER_SIZE == tid_head) {
|
||||
tmp_tid = tid_buffer[tid_head++];
|
||||
tid_head = (tid_head + 1) % TID_BUFFER_SIZE;
|
||||
}
|
||||
tid_buffer[tid_tail++] = tid;
|
||||
tid_tail %= TID_BUFFER_SIZE;
|
||||
mtx_unlock(&tid_lock);
|
||||
if (tmp_tid != -1)
|
||||
free_unr(tid_unrhdr, tmp_tid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare a thread for use.
|
||||
*/
|
||||
@ -102,7 +141,7 @@ thread_ctor(void *mem, int size, void *arg, int flags)
|
||||
td->td_state = TDS_INACTIVE;
|
||||
td->td_oncpu = NOCPU;
|
||||
|
||||
td->td_tid = alloc_unr(tid_unrhdr);
|
||||
td->td_tid = tid_alloc();
|
||||
|
||||
/*
|
||||
* Note that td_critnest begins life as 1 because the thread is not
|
||||
@ -156,7 +195,7 @@ thread_dtor(void *mem, int size, void *arg)
|
||||
osd_thread_exit(td);
|
||||
|
||||
EVENTHANDLER_INVOKE(thread_dtor, td);
|
||||
free_unr(tid_unrhdr, td->td_tid);
|
||||
tid_free(td->td_tid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user