]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.threads/omp-par-scope.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.threads / omp-par-scope.c
CommitLineData
4c12d936
KB
1/* This testcase is part of GDB, the GNU debugger.
2
213516ef 3 Copyright 2017-2023 Free Software Foundation, Inc.
4c12d936
KB
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#include <stdio.h>
19#include <omp.h>
20
b243ba58
TV
21omp_lock_t lock;
22omp_lock_t lock2;
23
24/* Enforce execution order between two threads using a lock. */
25
26static void
27omp_set_lock_in_order (int num, omp_lock_t *lock)
28{
29 /* Ensure that thread num 0 first sets the lock. */
30 if (num == 0)
31 omp_set_lock (lock);
32 #pragma omp barrier
33
34 /* Block thread num 1 until it can set the lock. */
35 if (num == 1)
36 omp_set_lock (lock);
37
38 /* This bit here is guaranteed to be executed first by thread num 0, and
39 once thread num 0 unsets the lock, to be executed by thread num 1. */
40 ;
41}
42
4c12d936
KB
43/* Testcase for checking access to variables in a single / outer scope.
44 Make sure that variables not referred to in the parallel section are
45 accessible from the debugger. */
46
47void
48single_scope (void)
49{
50 static int s1 = -41, s2 = -42, s3 = -43;
51 int i1 = 11, i2 = 12, i3 = 13;
52
53#pragma omp parallel num_threads (2) shared (s1, i1) private (s2, i2)
54 {
55 int thread_num = omp_get_thread_num ();
b243ba58 56 omp_set_lock_in_order (thread_num, &lock);
4c12d936
KB
57
58 s2 = 100 * (thread_num + 1) + 2;
59 i2 = s2 + 10;
60
61 #pragma omp critical
62 printf ("single_scope: thread_num=%d, s1=%d, i1=%d, s2=%d, i2=%d\n",
63 thread_num, s1, i1, s2, i2);
b243ba58
TV
64
65 omp_unset_lock (&lock);
4c12d936
KB
66 }
67
68 printf ("single_scope: s1=%d, s2=%d, s3=%d, i1=%d, i2=%d, i3=%d\n",
69 s1, s2, s3, i1, i2, i3);
70}
71
72static int file_scope_var = 9876;
73
74/* Testcase for checking access to variables from parallel region
75 nested within more than one lexical scope. Of particular interest
76 are variables which are not referenced in the parallel section. */
77
78void
79multi_scope (void)
80{
81 int i01 = 1, i02 = 2;
82
83 {
84 int i11 = 11, i12 = 12;
85
86 {
87 int i21 = -21, i22 = 22;
88
89#pragma omp parallel num_threads (2) \
90 firstprivate (i01) \
91 shared (i11) \
92 private (i21)
93 {
94 int thread_num = omp_get_thread_num ();
b243ba58
TV
95 omp_set_lock_in_order (thread_num, &lock);
96
4c12d936
KB
97 i21 = 100 * (thread_num + 1) + 21;
98
99 #pragma omp critical
100 printf ("multi_scope: thread_num=%d, i01=%d, i11=%d, i21=%d\n",
101 thread_num, i01, i11, i21);
b243ba58
TV
102
103 omp_unset_lock (&lock);
4c12d936
KB
104 }
105
106 printf ("multi_scope: i01=%d, i02=%d, i11=%d, "
107 "i12=%d, i21=%d, i22=%d\n",
108 i01, i02, i11, i12, i21, i22);
109 }
110 }
111}
112
113/* Nested functions in C is a GNU extension. Some non-GNU compilers
114 define __GNUC__, but they don't support nested functions. So,
115 unfortunately, we can't use that for our test. */
116#if HAVE_NESTED_FUNCTION_SUPPORT
117
118/* Testcase for checking access of variables from within parallel
119 region in a lexically nested function. */
120
121void
122nested_func (void)
123{
124 static int s1 = -42;
125 int i = 1, j = 2, k = 3;
126
127 void
128 foo (int p, int q, int r)
129 {
130 int x = 4;
131
132 {
133 int y = 5, z = 6;
134#pragma omp parallel num_threads (2) shared (i, p, x) private (j, q, y)
135 {
136 int tn = omp_get_thread_num ();
b243ba58 137 omp_set_lock_in_order (tn, &lock);
4c12d936
KB
138
139 j = 1000 * (tn + 1);
140 q = j + 1;
141 y = q + 1;
142 #pragma omp critical
143 printf ("nested_func: tn=%d: i=%d, p=%d, x=%d, j=%d, q=%d, y=%d\n",
144 tn, i, p, x, j, q, y);
b243ba58
TV
145
146 omp_unset_lock (&lock);
4c12d936
KB
147 }
148 }
149 }
150
151 foo (10, 11, 12);
152
153 i = 101; j = 102; k = 103;
154 foo (20, 21, 22);
155}
156#endif
157
158/* Testcase for checking access to variables from within a nested parallel
159 region. */
160
161void
162nested_parallel (void)
163{
164 int i = 1, j = 2;
165 int l = -1;
166
167 omp_set_nested (1);
168 omp_set_dynamic (0);
169#pragma omp parallel num_threads (2) private (l)
170 {
171 int num = omp_get_thread_num ();
b243ba58
TV
172 omp_set_lock_in_order (num, &lock);
173
4c12d936
KB
174 int nthr = omp_get_num_threads ();
175 int off = num * nthr;
176 int k = off + 101;
177 l = off + 102;
178#pragma omp parallel num_threads (2) shared (num)
179 {
180 int inner_num = omp_get_thread_num ();
b243ba58
TV
181 omp_set_lock_in_order (inner_num, &lock2);
182
4c12d936
KB
183 #pragma omp critical
184 printf ("nested_parallel (inner threads): outer thread num = %d, thread num = %d\n", num, inner_num);
b243ba58
TV
185
186 omp_unset_lock (&lock2);
4c12d936
KB
187 }
188 #pragma omp critical
189 printf ("nested_parallel (outer threads) %d: k = %d, l = %d\n", num, k, l);
b243ba58
TV
190
191 omp_unset_lock (&lock);
4c12d936
KB
192 }
193}
194
195int
196main (int argc, char **argv)
197{
b243ba58
TV
198 omp_init_lock (&lock);
199 omp_init_lock (&lock2);
200
4c12d936
KB
201 single_scope ();
202 multi_scope ();
203#if HAVE_NESTED_FUNCTION_SUPPORT
204 nested_func ();
205#endif
206 nested_parallel ();
b243ba58
TV
207
208 omp_destroy_lock (&lock);
209 omp_destroy_lock (&lock2);
210
4c12d936
KB
211 return 0;
212}
213