Author: davidxu
Date: Tue Feb 14 04:20:02 2012
New Revision: 231635
URL: http://svn.freebsd.org/changeset/base/231635

Log:
   MFC 231106:
   Plug a memory leak. When a cached thread is reused, don't clear sleep
   queue pointers, just reuse it.
  
   MFC 231503:
   Make code more stable by checking NULL pointers.

Modified:
  stable/9/lib/libthr/thread/thr_list.c
  stable/9/lib/libthr/thread/thr_private.h
Directory Properties:
  stable/9/lib/libthr/   (props changed)

Modified: stable/9/lib/libthr/thread/thr_list.c
==============================================================================
--- stable/9/lib/libthr/thread/thr_list.c       Tue Feb 14 04:18:59 2012        
(r231634)
+++ stable/9/lib/libthr/thread/thr_list.c       Tue Feb 14 04:20:02 2012        
(r231635)
@@ -149,11 +149,20 @@ _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);
                }
+               if ((thread->sleepqueue = _sleepq_alloc()) == NULL ||
+                   (thread->wake_addr = _thr_alloc_wake_addr()) == NULL) {
+                       thr_destroy(curthread, thread);
+                       atomic_fetchadd_int(&total_threads, -1);
+                       return (NULL);
+               }
+       } else {
+               bzero(&thread->_pthread_startzero, 
+                       __rangeof(struct pthread, _pthread_startzero, 
_pthread_endzero));
        }
        if (curthread != NULL) {
                THR_LOCK_ACQUIRE(curthread, &tcb_lock);
@@ -163,10 +172,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 +200,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 +217,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: stable/9/lib/libthr/thread/thr_private.h
==============================================================================
--- stable/9/lib/libthr/thread/thr_private.h    Tue Feb 14 04:18:59 2012        
(r231634)
+++ stable/9/lib/libthr/thread/thr_private.h    Tue Feb 14 04:20:02 2012        
(r231635)
@@ -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