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:
Ulrich Drepper 2007-08-21 23:55:36 +00:00
parent 45dc3ad77e
commit 2a01ce56b7
4 changed files with 118 additions and 1 deletions

View File

@ -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):

View File

@ -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 \

View File

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