Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Nov 2010 05:09:47 +0000 (UTC)
From:      David Xu <davidxu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r215162 - user/davidxu/libthr/sys/kern
Message-ID:  <201011120509.oAC59lDZ096568@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davidxu
Date: Fri Nov 12 05:09:47 2010
New Revision: 215162
URL: http://svn.freebsd.org/changeset/base/215162

Log:
  Add a ring buffer to delay the releasing of a thread id, this avoids
  a thread id being reused too quickly.

Modified:
  user/davidxu/libthr/sys/kern/kern_thread.c

Modified: user/davidxu/libthr/sys/kern/kern_thread.c
==============================================================================
--- user/davidxu/libthr/sys/kern/kern_thread.c	Fri Nov 12 04:28:25 2010	(r215161)
+++ user/davidxu/libthr/sys/kern/kern_thread.c	Fri Nov 12 05:09:47 2010	(r215162)
@@ -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
@@ -155,7 +194,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);
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011120509.oAC59lDZ096568>