Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

malloc reentrant?

37 views
Skip to first unread message

Stephan Meyen

unread,
Jul 20, 2005, 6:05:44 AM7/20/05
to
Hello,

Unfortunately I didn't find the information anywhere in the internet so I
have to ask.
I'm developing a program that shall use pthreads and heavily relies on
dynamic data structures. Does anybody if malloc is reentrant? My glibc
is version 2.3.2.
"man signal" states a set of functions that according to the posix
standard should be reentrant, malloc not among them. Anyway, I tried a
program as stated below that creates 100 threads, each of them
allocating and freeing memory perpetually and it worked fine.
Does anybody have more than a "empiric prove" that malloc is reentrant?

Thanks in advance,
Stephan

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define ALLOCS 100000000
#define THREADS 100
#define SIZE 2

void* alloc_n_free (void * args)
{
int i, j, x;
int * v;

x = (int) args;
printf ("Thread %d started\n", x);
for (i = 0; i < ALLOCS; i++) {
v = malloc (sizeof (int) * SIZE);
for (j = 0; j < SIZE; j++) v[j] = x;
if (v[1] != x) fprintf (stderr, "wrong number!\n");
free (v);
}
printf ("Thread %d stopped\n", x);
return NULL;
}


int main (void)
{
int i;
pthread_t thread[THREADS];

for (i = 0; i < THREADS; i++) pthread_create( &thread[i], NULL,
alloc_n_free, (void*) i);

for (i = 0; i < THREADS; i++) pthread_join (thread[i], NULL);

return 0;
}

Jonathan Bartlett

unread,
Jul 20, 2005, 8:46:37 AM7/20/05
to

> "man signal" states a set of functions that according to the posix
> standard should be reentrant, malloc not among them. Anyway, I tried a
> program as stated below that creates 100 threads, each of them
> allocating and freeing memory perpetually and it worked fine.
> Does anybody have more than a "empiric prove" that malloc is reentrant?

There is a difference between "signal reentrant" and "thread reentrant".
Being reentrant by a thread is easy to accomplish by simply adding a
semaphore or similar lock. Being signal reentrant is not as easy,
because a signal handler can't wait for a lock because it is blocking
the main execution of the program.

glibc malloc is thread reentrant. Just remember to compile with
-D_REENTRANT or similar flag.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

John Reiser

unread,
Jul 20, 2005, 10:12:02 AM7/20/05
to
> Does anybody if malloc is reentrant? My glibc is version 2.3.2.
> "man signal" states a set of functions that according to the posix
> standard should be reentrant, malloc not among them.

{malloc, calloc, realloc, free, posix_memalign} of glibc-2.2+ are thread
safe. However, they are not async signal safe. They are not reentrant,
and must not be called directly or indirectly from a signal handler:
a crash may result, perhaps much later. The source begins:
/* Malloc implementation for multiple threads without lock contention.
Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <w...@malloc.de>
and Doug Lea <d...@cs.oswego.edu>, 2001.
...
This is a version (aka ptmalloc2) of malloc/free/realloc written by
Doug Lea and adapted to multiple threads/arenas by Wolfram Gloger.

* Version ptmalloc2-20011215
$Id: malloc.c,v 1.142 2004/12/11 21:14:40 drepper Exp $
based on:
VERSION 2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee)
*/
The source does contain calls to {mutex_lock, mutex_unlock}.

A significant consequence is that a signal handler that uses {printf,
fprintf} should employ {setbuf, setbuffer, setlinebuf, setvbuf} before
enabling receipt of the signal. Otherwise {printf, fprintf} may call
malloc to allocate a buffer, which can lead to trouble. POSIX does not
require {printf, fprintf} to be async signal safe, and glibc-2.* generally
has adopted a strategy of minimal conformance. But so far in practice,
deciding buffering in advance has been enough to make printf usable from
commmon signal handlers.

--

Kasper Dupont

unread,
Jul 20, 2005, 4:09:58 PM7/20/05
to
Jonathan Bartlett wrote:
>
> Being signal reentrant is not as easy,
> because a signal handler can't wait for a lock because it is blocking
> the main execution of the program.

The function can simply block signals. But two sigprocmask
calls on each malloc call wouldn't be good to performance.
I could imagine more efficient ways to block signals, but
they would require some minor kernel modifications.

--
Kasper Dupont -- der bruger for meget tid på usenet.
Note to self: Don't try to allocate 256000 pages
with GFP_KERNEL on x86.

Lawrence DąOliveiro

unread,
Jul 21, 2005, 1:02:04 AM7/21/05
to
In article <42DEAF96...@daimi.au.dk>,
Kasper Dupont <kas...@daimi.au.dk> wrote:

>Jonathan Bartlett wrote:
>>
>> Being signal reentrant is not as easy,
>> because a signal handler can't wait for a lock because it is blocking
>> the main execution of the program.
>
>The function can simply block signals. But two sigprocmask
>calls on each malloc call wouldn't be good to performance.
>I could imagine more efficient ways to block signals, but
>they would require some minor kernel modifications.

There should be a way to do this with a simple set of userland library
routines that wrap the signal handling.

Kasper Dupont

unread,
Jul 21, 2005, 1:44:28 AM7/21/05
to

Yes, that could probably be done. So when the
application calls signal or sigaction to register a
handler, the library remembers the handler, but
make a system call to register a wrapper.

The wrapper then checks if the invoked handler is
currently blocked in the library, if it is blocked,
it is simply added to a list of pending signals,
otherwise it is invoked immediately.

The unblock function invokes any pending signals.

Then it is possible to block and unblock signals
without the overhead of a system call. Of course the
devil is in the details, I imagine it would be easy
to introduce a race condition in such a library.

--
Kasper Dupont -- der bruger for meget tid pĺ usenet.

0 new messages