[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>
|
2007-08-21 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_robust_dead):
|
* 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-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \
|
||||||
tst-detach1 \
|
tst-detach1 \
|
||||||
tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
|
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-tls1 tst-tls2 \
|
||||||
tst-fork1 tst-fork2 tst-fork3 tst-fork4 \
|
tst-fork1 tst-fork2 tst-fork3 tst-fork4 \
|
||||||
tst-atfork1 \
|
tst-atfork1 \
|
||||||
|
|
|
@ -794,6 +794,26 @@ __reclaim_stacks (void)
|
||||||
|
|
||||||
/* Account for the size of the stack. */
|
/* Account for the size of the stack. */
|
||||||
stack_cache_actsize += curp->stackblock_size;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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…
Reference in New Issue