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);
 }
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to