Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: threaded programs report bogus process size ?
In article <h9u2f5$qap$1%serpens.de@localhost>,
Michael van Elst <mlelstv%serpens.de@localhost> wrote:
>njoly%pasteur.fr@localhost (Nicolas Joly) writes:
>
>>I just noticed that threaded processes may report increasing process
>>size of their life ...
>
>libpthread never frees the pthread data structure and associated
>thread stack when a thread ends but puts it onto a private queue
>("deadqueue") and reclaims it again when a new thread is created.
>
>The reclaim can fail when a new thread is created shortly after
>an old thread ended because of a race with the kernel. As a result
>a new thread is allocated.
>
>So _some_ leakage is allowed by design.
>
>The problem is that the reclaim operation is only tried for the
>thread that ended last (the top of the "deadqueue"). So in a
>tight pthread_create/join loop the leaked threads just pile up.
>
>To correct this the reclaim operation should loop over the queue
>and try to reclaim any of the dead threads.
This seems to fix it.
christos
Index: pthread.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread.c,v
retrieving revision 1.112
diff -u -u -r1.112 pthread.c
--- pthread.c 2 Jul 2009 09:59:00 -0000 1.112
+++ pthread.c 30 Sep 2009 00:12:20 -0000
@@ -316,7 +316,7 @@
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*startfunc)(void *), void *arg)
{
- pthread_t newthread;
+ pthread_t newthread, first_thread;
pthread_attr_t nattr;
struct pthread_attr_private *p;
char * volatile name;
@@ -353,8 +353,13 @@
*/
if (!PTQ_EMPTY(&pthread__deadqueue)) {
pthread_mutex_lock(&pthread__deadqueue_lock);
- newthread = PTQ_FIRST(&pthread__deadqueue);
- if (newthread != NULL) {
+ first_thread = PTQ_FIRST(&pthread__deadqueue);
+ newthread = first_thread;
+ do {
+ if (newthread == NULL) {
+ pthread_mutex_unlock(&pthread__deadqueue_lock);
+ break;
+ }
PTQ_REMOVE(&pthread__deadqueue, newthread, pt_deadq);
pthread_mutex_unlock(&pthread__deadqueue_lock);
/* Still running? */
@@ -366,10 +371,11 @@
PTQ_INSERT_TAIL(&pthread__deadqueue,
newthread, pt_deadq);
pthread_mutex_unlock(&pthread__deadqueue_lock);
- newthread = NULL;
- }
- } else
- pthread_mutex_unlock(&pthread__deadqueue_lock);
+ } else
+ break;
+ pthread_mutex_lock(&pthread__deadqueue_lock);
+ newthread = PTQ_FIRST(&pthread__deadqueue);
+ } while (newthread != first_thread);
}
/*
Home |
Main Index |
Thread Index |
Old Index