source: vendor/glibc-tests/glibc/linuxthreads/tst-context.c

Last change on this file was 2036, checked in by bird, 20 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 2.3 KB
Line 
1/* Ack, a hack! We need to get the proper definition, or lack thereof,
2 for FLOATING_STACKS. But when !IS_IN_libpthread, this can get defined
3 incidentally by <tls.h>. So kludge around it. */
4
5#define IS_IN_libpthread
6#include <tls.h>
7#undef IS_IN_libpthread
8#undef USE___THREAD
9
10#include <errno.h>
11#include <error.h>
12#include <pthread.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <ucontext.h>
16
17
18#define N 4
19
20#ifdef FLOATING_STACKS
21static char stacks[N][8192];
22static ucontext_t ctx[N][2];
23static volatile int failures;
24
25static void
26fct (long int n)
27{
28 /* Just to use the thread local descriptor. */
29 printf ("%ld: in %s now\n", n, __FUNCTION__);
30 errno = 0;
31}
32
33static void *
34threadfct (void *arg)
35{
36 int n = (int) (long int) arg;
37
38 if (getcontext (&ctx[n][1]) != 0)
39 {
40 printf ("%d: cannot get context: %m\n", n);
41 exit (1);
42 }
43
44 printf ("%d: %s: before makecontext\n", n, __FUNCTION__);
45
46 ctx[n][1].uc_stack.ss_sp = stacks[n];
47 ctx[n][1].uc_stack.ss_size = 8192;
48 ctx[n][1].uc_link = &ctx[n][0];
49 makecontext (&ctx[n][1], (void (*) (void)) fct, 1, (long int) n);
50
51 printf ("%d: %s: before swapcontext\n", n, __FUNCTION__);
52
53 if (swapcontext (&ctx[n][0], &ctx[n][1]) != 0)
54 {
55 ++failures;
56 printf ("%d: %s: swapcontext failed\n", n, __FUNCTION__);
57 }
58 else
59 printf ("%d: back in %s\n", n, __FUNCTION__);
60
61 return NULL;
62}
63#endif
64
65
66#ifdef FLOATING_STACKS
67static volatile int global;
68#endif
69
70int
71main (void)
72{
73#ifndef FLOATING_STACKS
74 puts ("not supported");
75 return 0;
76#else
77 int n;
78 pthread_t th[N];
79 ucontext_t mctx;
80
81 puts ("making contexts");
82 if (getcontext (&mctx) != 0)
83 {
84 if (errno == ENOSYS)
85 {
86 puts ("context handling not supported");
87 exit (0);
88 }
89
90 printf ("%s: getcontext: %m\n", __FUNCTION__);
91 exit (1);
92 }
93
94 /* Play some tricks with this context. */
95 if (++global == 1)
96 if (setcontext (&mctx) != 0)
97 {
98 printf ("%s: setcontext: %m\n", __FUNCTION__);
99 exit (1);
100 }
101 if (global != 2)
102 {
103 printf ("%s: 'global' not incremented twice\n", __FUNCTION__);
104 exit (1);
105 }
106
107 for (n = 0; n < N; ++n)
108 if (pthread_create (&th[n], NULL, threadfct, (void *) (long int) n) != 0)
109 error (EXIT_FAILURE, errno, "cannot create all threads");
110
111 for (n = 0; n < N; ++n)
112 pthread_join (th[n], NULL);
113
114 return failures;
115#endif
116}
Note: See TracBrowser for help on using the repository browser.