svn commit: r231106 - head/lib/libthr/thread

David Xu davidxu at FreeBSD.org
Tue Feb 7 02:57:36 UTC 2012


Author: davidxu
Date: Tue Feb  7 02:57:36 2012
New Revision: 231106
URL: http://svn.freebsd.org/changeset/base/231106

Log:
  Plug a memory leak. When a cached thread is reused, don't clear sleep
  queue pointers, just reuse it.
  
  PR:		164828
  MFC after:	1 week

Modified:
  head/lib/libthr/thread/thr_list.c
  head/lib/libthr/thread/thr_private.h

Modified: head/lib/libthr/thread/thr_list.c
==============================================================================
--- head/lib/libthr/thread/thr_list.c	Tue Feb  7 02:21:46 2012	(r231105)
+++ head/lib/libthr/thread/thr_list.c	Tue Feb  7 02:57:36 2012	(r231106)
@@ -149,11 +149,16 @@ _thr_alloc(struct pthread *curthread)
 		if (total_threads > MAX_THREADS)
 			return (NULL);
 		atomic_fetchadd_int(&total_threads, 1);
-		thread = malloc(sizeof(struct pthread));
+		thread = calloc(1, sizeof(struct pthread));
 		if (thread == NULL) {
 			atomic_fetchadd_int(&total_threads, -1);
 			return (NULL);
 		}
+		thread->sleepqueue = _sleepq_alloc();
+		thread->wake_addr = _thr_alloc_wake_addr();
+	} else {
+		bzero(&thread->_pthread_startzero, 
+			__rangeof(struct pthread, _pthread_startzero, _pthread_endzero));
 	}
 	if (curthread != NULL) {
 		THR_LOCK_ACQUIRE(curthread, &tcb_lock);
@@ -163,10 +168,7 @@ _thr_alloc(struct pthread *curthread)
 		tcb = _tcb_ctor(thread, 1 /* initial tls */);
 	}
 	if (tcb != NULL) {
-		memset(thread, 0, sizeof(*thread));
 		thread->tcb = tcb;
-		thread->sleepqueue = _sleepq_alloc();
-		thread->wake_addr = _thr_alloc_wake_addr();
 	} else {
 		thr_destroy(curthread, thread);
 		atomic_fetchadd_int(&total_threads, -1);
@@ -194,8 +196,6 @@ _thr_free(struct pthread *curthread, str
 	}
 	thread->tcb = NULL;
 	if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) {
-		_sleepq_free(thread->sleepqueue);
-		_thr_release_wake_addr(thread->wake_addr);
 		thr_destroy(curthread, thread);
 		atomic_fetchadd_int(&total_threads, -1);
 	} else {
@@ -213,6 +213,10 @@ _thr_free(struct pthread *curthread, str
 static void
 thr_destroy(struct pthread *curthread __unused, struct pthread *thread)
 {
+	if (thread->sleepqueue != NULL)
+		_sleepq_free(thread->sleepqueue);
+	if (thread->wake_addr != NULL)
+		_thr_release_wake_addr(thread->wake_addr);
 	free(thread);
 }
 

Modified: head/lib/libthr/thread/thr_private.h
==============================================================================
--- head/lib/libthr/thread/thr_private.h	Tue Feb  7 02:21:46 2012	(r231105)
+++ head/lib/libthr/thread/thr_private.h	Tue Feb  7 02:57:36 2012	(r231106)
@@ -343,6 +343,7 @@ struct pthread_key {
  * Thread structure.
  */
 struct pthread {
+#define _pthread_startzero	tid
 	/* Kernel thread id. */
 	long			tid;
 #define	TID_TERMINATED		1
@@ -506,12 +507,6 @@ struct pthread {
 	/* Event */
 	td_event_msg_t		event_buf;
 
-	struct wake_addr	*wake_addr;
-#define WAKE_ADDR(td)           ((td)->wake_addr)
-
-	/* Sleep queue */
-	struct	sleepqueue	*sleepqueue;
-
 	/* Wait channel */
 	void			*wchan;
 
@@ -526,6 +521,14 @@ struct pthread {
 
 	/* Deferred threads from pthread_cond_signal. */
 	unsigned int 		*defer_waiters[MAX_DEFER_WAITERS];
+#define _pthread_endzero	wake_addr
+
+	struct wake_addr	*wake_addr;
+#define WAKE_ADDR(td)           ((td)->wake_addr)
+
+	/* Sleep queue */
+	struct	sleepqueue	*sleepqueue;
+
 };
 
 #define THR_SHOULD_GC(thrd) 						\


More information about the svn-src-all mailing list