Google 그룹스는 더 이상 새로운 유즈넷 게시물 또는 구독을 지원하지 않습니다. 과거의 콘텐츠는 계속 볼 수 있습니다.

malloc reentrant?

조회수 37회
읽지 않은 첫 메시지로 건너뛰기

Stephan Meyen

읽지 않음,
2005. 7. 20. 오전 6:05:4405. 7. 20.
받는사람
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

읽지 않음,
2005. 7. 20. 오전 8:46:3705. 7. 20.
받는사람

> "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

읽지 않음,
2005. 7. 20. 오전 10:12:0205. 7. 20.
받는사람
> 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

읽지 않음,
2005. 7. 20. 오후 4:09:5805. 7. 20.
받는사람
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

읽지 않음,
2005. 7. 21. 오전 1:02:0405. 7. 21.
받는사람
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

읽지 않음,
2005. 7. 21. 오전 1:44:2805. 7. 21.
받는사람

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개