Line data Source code
1 : /* t-thread.c
2 : * Copyright 2012 g10 Code GmbH
3 : *
4 : * This file is free software; as a special exception the author gives
5 : * unlimited permission to copy and/or distribute it, with or without
6 : * modifications, as long as this notice is preserved.
7 : *
8 : * This file is distributed in the hope that it will be useful, but
9 : * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
10 : * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 : */
12 :
13 : #include "t-support.h"
14 :
15 :
16 : static int counter;
17 : static npth_mutex_t counter_mutex;
18 : static int thread_twoone_ready;
19 :
20 : static void *
21 1 : thread_one (void *arg)
22 : {
23 : int rc, i;
24 :
25 1 : info_msg ("thread-one started");
26 1 : npth_usleep (10); /* Give the other thread some time to start. */
27 11 : for (i=0; i < 10; i++)
28 : {
29 : /* We would not need the mutex here, but we use it to allow the
30 : system to switch to another thread. */
31 10 : rc = npth_mutex_lock (&counter_mutex);
32 10 : fail_if_err (rc);
33 :
34 10 : counter++;
35 :
36 10 : rc = npth_mutex_unlock (&counter_mutex);
37 10 : fail_if_err (rc);
38 : }
39 1 : info_msg ("thread-one terminated");
40 :
41 1 : return (void*)4711;
42 : }
43 :
44 :
45 : static void *
46 1 : thread_twoone (void *arg)
47 : {
48 : int rc, i;
49 :
50 1 : npth_setname_np (npth_self (), "thread-twoone");
51 1 : info_msg ("thread-twoone started");
52 :
53 1 : rc = npth_detach (npth_self ());
54 1 : fail_if_err (rc);
55 :
56 102 : while (counter < 100)
57 : {
58 100 : npth_usleep (1000);
59 100 : counter++;
60 : }
61 1 : info_msg ("thread-twoone terminated");
62 1 : thread_twoone_ready = 1;
63 :
64 1 : return NULL;
65 : }
66 :
67 :
68 : static void *
69 1 : thread_two (void *arg)
70 : {
71 : int rc, i;
72 :
73 1 : info_msg ("thread-two started");
74 :
75 11 : for (i=0; i < 10; i++)
76 : {
77 10 : rc = npth_mutex_lock (&counter_mutex);
78 10 : fail_if_err (rc);
79 :
80 10 : counter--;
81 :
82 10 : if (i == 5)
83 : {
84 : npth_t tid;
85 :
86 1 : info_msg ("creating thread-twoone");
87 1 : rc = npth_create (&tid, NULL, thread_twoone, NULL);
88 1 : fail_if_err (rc);
89 1 : npth_usleep (10); /* Give new thread some time to start. */
90 : }
91 :
92 10 : rc = npth_mutex_unlock (&counter_mutex);
93 10 : fail_if_err (rc);
94 : }
95 :
96 1 : info_msg ("busy waiting for thread twoone");
97 1994 : while (!thread_twoone_ready)
98 1992 : npth_sleep (0);
99 :
100 1 : info_msg ("thread-two terminated");
101 :
102 1 : return (void*)4722;
103 : }
104 :
105 :
106 :
107 :
108 :
109 : int
110 1 : main (int argc, char *argv[])
111 : {
112 : int rc;
113 : npth_attr_t tattr;
114 : int state;
115 : npth_t tid1, tid2;
116 : void *retval;
117 :
118 1 : if (argc >= 2 && !strcmp (argv[1], "--verbose"))
119 0 : opt_verbose = 1;
120 :
121 1 : rc = npth_init ();
122 1 : fail_if_err (rc);
123 :
124 1 : rc = npth_mutex_init (&counter_mutex, NULL);
125 1 : fail_if_err (rc);
126 :
127 1 : rc = npth_attr_init (&tattr);
128 1 : fail_if_err (rc);
129 1 : rc = npth_attr_getdetachstate (&tattr, &state);
130 1 : fail_if_err (rc);
131 1 : if ( state != NPTH_CREATE_JOINABLE )
132 0 : fail_msg ("new tattr is not joinable");
133 :
134 1 : info_msg ("creating thread-one");
135 1 : rc = npth_create (&tid1, &tattr, thread_one, NULL);
136 1 : fail_if_err (rc);
137 1 : npth_setname_np (tid1, "thread-one");
138 :
139 1 : info_msg ("creating thread-two");
140 1 : rc = npth_create (&tid2, &tattr, thread_two, NULL);
141 1 : fail_if_err (rc);
142 1 : npth_setname_np (tid2, "thread-two");
143 :
144 1 : rc = npth_attr_destroy (&tattr);
145 1 : fail_if_err (rc);
146 :
147 1 : info_msg ("waiting for thread-one to terminate");
148 1 : rc = npth_join (tid1, &retval);
149 1 : fail_if_err (rc);
150 1 : if (retval != (void*)4711)
151 0 : fail_msg ("thread-one returned an unexpected value");
152 :
153 1 : info_msg ("waiting for thread-two to terminate");
154 1 : rc = npth_join (tid2, &retval);
155 1 : fail_if_err (rc);
156 1 : if (retval != (void*)4722)
157 0 : fail_msg ("thread-two returned an unexpected value");
158 :
159 1 : if (counter != 100)
160 0 : fail_msg ("counter value not as expected");
161 :
162 1 : return 0;
163 : }
|