diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 3 | ||||
-rw-r--r-- | linuxthreads/tst-context.c | 98 |
2 files changed, 101 insertions, 0 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 1e86a66..8644eda 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,5 +1,8 @@ 2001-07-23 Ulrich Drepper <drepper@redhat.com> + * Makefile (tests): Add tst-context. + * tst-context.c: New file. + * sysdeps/pthread/bits/stdio-lock.h: Define _IO_cleanup_region_start_noarg. diff --git a/linuxthreads/tst-context.c b/linuxthreads/tst-context.c new file mode 100644 index 0000000..cf4783d --- /dev/null +++ b/linuxthreads/tst-context.c @@ -0,0 +1,98 @@ +#include <errno.h> +#include <error.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <ucontext.h> + +#include "pt-machine.h" + + +#define N 4 + +#ifdef FLOATING_STACKS +static char stacks[N][8192]; +static ucontext_t ctx[N][2]; +static volatile int failures; + +static void +fct (long int n) +{ + /* Just to use the thread local descriptor. */ + printf ("%ld: in %s now\n", n, __FUNCTION__); + errno = 0; +} + +static void * +threadfct (void *arg) +{ + int n = (int) (long int) arg; + + printf ("%d: %s: before makecontext\n", n, __FUNCTION__); + + ctx[n][1].uc_stack.ss_sp = stacks[n]; + ctx[n][1].uc_stack.ss_size = 8192; + ctx[n][1].uc_link = &ctx[n][0]; + makecontext (&ctx[n][1], (void (*) (void)) fct, 1, (long int) n); + + printf ("%d: %s: before swapcontext\n", n, __FUNCTION__); + + if (swapcontext (&ctx[n][0], &ctx[n][1]) != 0) + { + ++failures; + printf ("%d: %s: swapcontext failed\n", n, __FUNCTION__); + } + else + printf ("%d: back in %s\n", n, __FUNCTION__); + + return NULL; +} +#endif + + +static volatile int global; + +int +main (void) +{ +#ifndef FLOATING_STACKS + puts ("not supported"); + return 0; +#else + int n; + pthread_t th[N]; + ucontext_t mctx; + + puts ("making contexts"); + if (getcontext (&mctx) != 0) + { + if (errno == ENOSYS) + exit (0); + + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (1); + } + + /* Play some tricks with this context. */ + if (++global == 1) + if (setcontext (&mctx) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (1); + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (1); + } + + for (n = 0; n < N; ++n) + if (pthread_create (&th[n], NULL, threadfct, (void *) n) != 0) + error (EXIT_FAILURE, errno, "cannot create all threads"); + + for (n = 0; n < N; ++n) + pthread_join (th[n], NULL); + + return failures; +#endif +} |