Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 May 2009 20:24:09 +0200
From:      =?ISO-8859-1?Q?Marius_N=FCnnerich?= <marius@nuenneri.ch>
To:        Mikolaj Golub <to.my.trociny@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Memory leak on thread removal
Message-ID:  <b649e5e0905161124pcface05u87ba27029d095cd3@mail.gmail.com>
In-Reply-To: <86k54hvuzv.fsf@kopusha.onet>
References:  <814ovqn8dp.fsf@zhuzha.ua1> <b649e5e0905150448m52d0a802h50c298e529031825@mail.gmail.com> <86k54hvuzv.fsf@kopusha.onet>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, May 16, 2009 at 19:05, Mikolaj Golub <to.my.trociny@gmail.com> wrot=
e:
>
> On Fri, 15 May 2009 13:48:51 +0200 Marius N=FCnnerich wrote:
>
> =A0MN> On Tue, May 12, 2009 at 08:27, Mikolaj Golub <to.my.trociny@gmail.=
com> wrote:
> =A0>> Hi,
> =A0>>
> =A0>> The code below is compiled with -fopenmp and run on FreeBSD6/7 (i38=
6, amd64):
> =A0>>
> =A0>> #include <omp.h>
> =A0>> #include <unistd.h>
> =A0>>
> =A0>> int n =3D 4, m =3D 2;
> =A0>>
> =A0>> int main () {
> =A0>> =A0 =A0 =A0 =A0for (;;) {
> =A0>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int i;
> =A0>>
> =A0>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0//sleep(2);
> =A0>> #pragma omp parallel for num_threads(m)
> =A0>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for(i =3D 0; i < 1; i++) {}
> =A0>>
> =A0>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0//sleep(2);
> =A0>> #pragma omp parallel for num_threads(n)
> =A0>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0for(i =3D 0; i < 1; i++) {}
> =A0>>
> =A0>> =A0 =A0 =A0 =A0}
> =A0>>
> =A0>> =A0 =A0 =A0 =A0return 0;
> =A0>> }
> =A0>>
> =A0>> During the run the program's virtual memory usage constantly grows.=
 The growth
> =A0>> is observed only when n !=3D m. When running the program with uncom=
mented
> =A0>> sleep() and observing the number of threads with 'top -H' I see in =
turn 2 or 4
> =A0>> threads. So it looks like memory leak when thread is removed. Shoul=
d I fill
> =A0>> PR?
>
> It looks like I have found the leak. The problem is in libgomp/team.c.
> gomp_thread_start() does sem_init() but sem_destroy() is never called. Th=
is
> patch solves the problem for me:
>
> --- contrib/gcclibs/libgomp/team.c.orig 2009-05-16 17:32:57.000000000 +03=
00
> +++ contrib/gcclibs/libgomp/team.c =A0 =A0 =A02009-05-16 19:16:37.0000000=
00 +0300
> @@ -164,9 +164,12 @@ new_team (unsigned nthreads, struct gomp
> =A0static void
> =A0free_team (struct gomp_team *team)
> =A0{
> + =A0int i;
> =A0 free (team->work_shares);
> =A0 gomp_mutex_destroy (&team->work_share_lock);
> =A0 gomp_barrier_destroy (&team->barrier);
> + =A0for(i =3D 1; i < team->nthreads; i++)
> + =A0 =A0gomp_sem_destroy (team->ordered_release[i]);
> =A0 gomp_sem_destroy (&team->master_release);
> =A0 free (team);
> =A0}
>
> I am going to fill PR to gcc mainstream, but should I also register this =
in
> FreeBSD bugtrack as gcc is part of the base?
>
> BTW, the problem is not observed under Linux. I have not looked in Linux =
code
> but it looks like sem_init() implementation for Linux does not do memory
> allocation. The memory for the test program below grows under FreeBSD and=
 does
> not under Linux.
>
> #include <semaphore.h>
>
> int
> main(int argc, char *argv[]) {
>
> =A0 =A0 =A0 =A0sem_t sem;
>
> =A0 =A0 =A0 =A0for(;;) { sem_init(&sem, 0, 0);}
>
> =A0 =A0 =A0 =A0return 0;
> }

Wow! Thanks for tracking this down. I think you can file both PR's so
that FreeBSD can include your patch before it comes in via upstream.

>
>
> =A0MN> I can confirm this. I briefly looked through the libgomp code but
> =A0MN> didn't see the leak. Anybody knows good tools how to investigate t=
his?
>
> http://freshmeat.net/projects/lmdbg
>
> This is a small memory leak debugger. It does not provide all functionali=
ty
> you can find in more sophisticated tools but is lightweight, portable and
> simple in use. It was very useful when I traced this bug.

Thanks, I'll take a look at it.



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