svn commit: r216314 - head/sys/kern
David Xu
davidxu at FreeBSD.org
Thu Dec 9 05:16:21 UTC 2010
Author: davidxu
Date: Thu Dec 9 05:16:20 2010
New Revision: 216314
URL: http://svn.freebsd.org/changeset/base/216314
Log:
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.
Modified:
head/sys/kern/kern_thread.c
Modified: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c Thu Dec 9 02:42:02 2010 (r216313)
+++ head/sys/kern/kern_thread.c Thu Dec 9 05:16:20 2010 (r216314)
@@ -81,15 +81,54 @@ MTX_SYSINIT(zombie_lock, &zombie_lock, "
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 *a
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 *a
osd_thread_exit(td);
EVENTHANDLER_INVOKE(thread_dtor, td);
- free_unr(tid_unrhdr, td->td_tid);
+ tid_free(td->td_tid);
}
/*
More information about the svn-src-all
mailing list