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)                                            \
_______________________________________________
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