mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-12 14:21:18 +08:00
[BZ #4938]
2007-08-21 Ulrich Drepper <drepper@redhat.com> [BZ #4938] * allocatestack.c (__reclaim_stacks): Clear the TSD in the reclaimed stack if necessary. * Makefile (tests): Add tst-tsd6. * tst-tsd6.c: New file.
This commit is contained in:
parent
45dc3ad77e
commit
2a01ce56b7
@ -1,3 +1,11 @@
|
||||
2007-08-21 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
[BZ #4938]
|
||||
* allocatestack.c (__reclaim_stacks): Clear the TSD in the
|
||||
reclaimed stack if necessary.
|
||||
* Makefile (tests): Add tst-tsd6.
|
||||
* tst-tsd6.c: New file.
|
||||
|
||||
2007-08-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_robust_dead):
|
||||
|
@ -227,7 +227,7 @@ tests = tst-typesizes \
|
||||
tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \
|
||||
tst-detach1 \
|
||||
tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
|
||||
tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 \
|
||||
tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \
|
||||
tst-tls1 tst-tls2 \
|
||||
tst-fork1 tst-fork2 tst-fork3 tst-fork4 \
|
||||
tst-atfork1 \
|
||||
|
@ -794,6 +794,26 @@ __reclaim_stacks (void)
|
||||
|
||||
/* Account for the size of the stack. */
|
||||
stack_cache_actsize += curp->stackblock_size;
|
||||
|
||||
if (curp->specific_used)
|
||||
{
|
||||
/* Clear the thread-specific data. */
|
||||
memset (curp->specific_1stblock, '\0',
|
||||
sizeof (curp->specific_1stblock));
|
||||
|
||||
curp->specific_used = false;
|
||||
|
||||
for (size_t cnt = 1; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
|
||||
if (curp->specific[cnt] != NULL)
|
||||
{
|
||||
memset (curp->specific[cnt], '\0',
|
||||
sizeof (curp->specific_1stblock));
|
||||
|
||||
/* We have allocated the block which we do not
|
||||
free here so re-set the bit. */
|
||||
curp->specific_used = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
89
nptl/tst-tsd6.c
Normal file
89
nptl/tst-tsd6.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define NKEYS 100
|
||||
static pthread_key_t keys[NKEYS];
|
||||
static pthread_barrier_t b;
|
||||
|
||||
|
||||
static void *
|
||||
tf (void *arg)
|
||||
{
|
||||
void *res = NULL;
|
||||
for (int i = 0; i < NKEYS; ++i)
|
||||
{
|
||||
void *p = pthread_getspecific (keys[i]);
|
||||
pthread_setspecific (keys[i], (void *) 7);
|
||||
if (p != NULL)
|
||||
res = p;
|
||||
}
|
||||
if (arg != NULL)
|
||||
{
|
||||
pthread_barrier_wait (arg);
|
||||
pthread_barrier_wait (arg);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
pthread_barrier_init (&b, NULL, 2);
|
||||
|
||||
for (int i = 0; i < NKEYS; ++i)
|
||||
if (pthread_key_create (&keys[i], NULL) != 0)
|
||||
{
|
||||
puts ("cannot create keys");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pthread_t th;
|
||||
if (pthread_create (&th, NULL, tf, &b) != 0)
|
||||
{
|
||||
puts ("cannot create thread in parent");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pthread_barrier_wait (&b);
|
||||
|
||||
pid_t pid = fork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
if (pthread_create (&th, NULL, tf, NULL) != 0)
|
||||
{
|
||||
puts ("cannot create thread in child");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
void *res;
|
||||
pthread_join (th, &res);
|
||||
|
||||
exit (res != NULL);
|
||||
}
|
||||
else if (pid == -1)
|
||||
{
|
||||
puts ("cannot create child process");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int s;
|
||||
if (TEMP_FAILURE_RETRY (waitpid (pid, &s, 0)) != pid)
|
||||
{
|
||||
puts ("failing to wait for child process");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pthread_barrier_wait (&b);
|
||||
pthread_join (th, NULL);
|
||||
|
||||
return !WIFEXITED (s) ? 2 : WEXITSTATUS (s);
|
||||
}
|
||||
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
Loading…
x
Reference in New Issue
Block a user