1 /* Copyright (C) 2018 Free Software Foundation, Inc.
2 Contributed by Jakub Jelinek <jakub@redhat.com>.
4 This file is part of the GNU Offloading and Multi Processing Library
7 Libgomp is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
33 #ifdef HAVE_INTTYPES_H
34 # include <inttypes.h> /* For PRIx64. */
37 #include <sys/utsname.h>
41 gomp_set_affinity_format (const char *format
, size_t len
)
43 if (len
< gomp_affinity_format_len
)
44 memcpy (gomp_affinity_format_var
, format
, len
);
48 if (gomp_affinity_format_len
)
49 p
= gomp_realloc (gomp_affinity_format_var
, len
+ 1);
51 p
= gomp_malloc (len
+ 1);
52 memcpy (p
, format
, len
);
53 gomp_affinity_format_var
= p
;
54 gomp_affinity_format_len
= len
+ 1;
56 gomp_affinity_format_var
[len
] = '\0';
60 omp_set_affinity_format (const char *format
)
62 gomp_set_affinity_format (format
, strlen (format
));
66 omp_get_affinity_format (char *buffer
, size_t size
)
68 size_t len
= strlen (gomp_affinity_format_var
);
72 memcpy (buffer
, gomp_affinity_format_var
, len
+ 1);
75 memcpy (buffer
, gomp_affinity_format_var
, size
- 1);
76 buffer
[size
- 1] = '\0';
83 gomp_display_string (char *buffer
, size_t size
, size_t *ret
,
84 const char *str
, size_t len
)
92 memcpy (buffer
+ r
, str
, l
);
95 if (__builtin_expect (r
> *ret
, 0))
96 gomp_fatal ("overflow in omp_capture_affinity");
100 gomp_display_repeat (char *buffer
, size_t size
, size_t *ret
,
104 if (size
&& r
< size
)
109 memset (buffer
+ r
, c
, l
);
112 if (__builtin_expect (r
> *ret
, 0))
113 gomp_fatal ("overflow in omp_capture_affinity");
117 gomp_display_num (char *buffer
, size_t size
, size_t *ret
,
118 bool zero
, bool right
, size_t sz
, char *buf
)
120 size_t l
= strlen (buf
);
121 if (sz
== (size_t) -1 || l
>= sz
)
123 gomp_display_string (buffer
, size
, ret
, buf
, l
);
129 gomp_display_string (buffer
, size
, ret
, buf
, 1);
130 else if (buf
[0] == '0' && buf
[1] == 'x')
131 gomp_display_string (buffer
, size
, ret
, buf
, 2);
132 gomp_display_repeat (buffer
, size
, ret
, '0', sz
- l
);
134 gomp_display_string (buffer
, size
, ret
, buf
+ 1, l
- 1);
135 else if (buf
[0] == '0' && buf
[1] == 'x')
136 gomp_display_string (buffer
, size
, ret
, buf
+ 2, l
- 2);
138 gomp_display_string (buffer
, size
, ret
, buf
, l
);
142 gomp_display_repeat (buffer
, size
, ret
, ' ', sz
- l
);
143 gomp_display_string (buffer
, size
, ret
, buf
, l
);
147 gomp_display_string (buffer
, size
, ret
, buf
, l
);
148 gomp_display_repeat (buffer
, size
, ret
, ' ', sz
- l
);
153 gomp_display_int (char *buffer
, size_t size
, size_t *ret
,
154 bool zero
, bool right
, size_t sz
, int num
)
156 char buf
[3 * sizeof (int) + 2];
157 sprintf (buf
, "%d", num
);
158 gomp_display_num (buffer
, size
, ret
, zero
, right
, sz
, buf
);
162 gomp_display_string_len (char *buffer
, size_t size
, size_t *ret
,
163 bool right
, size_t sz
, char *str
, size_t len
)
165 if (sz
== (size_t) -1 || len
>= sz
)
167 gomp_display_string (buffer
, size
, ret
, str
, len
);
173 gomp_display_repeat (buffer
, size
, ret
, ' ', sz
- len
);
174 gomp_display_string (buffer
, size
, ret
, str
, len
);
178 gomp_display_string (buffer
, size
, ret
, str
, len
);
179 gomp_display_repeat (buffer
, size
, ret
, ' ', sz
- len
);
184 gomp_display_hostname (char *buffer
, size_t size
, size_t *ret
,
185 bool right
, size_t sz
)
187 #ifdef HAVE_GETHOSTNAME
195 if (gethostname (b
, len
- 1) == 0)
197 size_t l
= strlen (b
);
200 gomp_display_string_len (buffer
, size
, ret
,
211 b
= gomp_malloc (len
);
213 b
= gomp_realloc (b
, len
);
223 if (uname (&buf
) == 0)
225 gomp_display_string_len (buffer
, size
, ret
, right
, sz
,
226 buf
.nodename
, strlen (buf
.nodename
));
231 gomp_display_string_len (buffer
, size
, ret
, right
, sz
, "node", 4);
234 struct affinity_types_struct
{
239 static struct affinity_types_struct affinity_types
[] =
241 #define AFFINITY_TYPE(l, s) \
242 { #l, sizeof (#l) - 1, s }
243 AFFINITY_TYPE (team_num
, 't'),
244 AFFINITY_TYPE (num_teams
, 'T'),
245 AFFINITY_TYPE (nesting_level
, 'L'),
246 AFFINITY_TYPE (thread_num
, 'n'),
247 AFFINITY_TYPE (num_threads
, 'N'),
248 AFFINITY_TYPE (ancestor_tnum
, 'a'),
249 AFFINITY_TYPE (host
, 'H'),
250 AFFINITY_TYPE (process_id
, 'P'),
251 AFFINITY_TYPE (native_thread_id
, 'i'),
252 AFFINITY_TYPE (thread_affinity
, 'A')
257 gomp_display_affinity (char *buffer
, size_t size
,
258 const char *format
, gomp_thread_handle handle
,
259 struct gomp_team_state
*ts
, unsigned int place
)
264 const char *p
= strchr (format
, '%');
271 p
= strchr (format
, '\0');
273 gomp_display_string (buffer
, size
, &ret
,
280 gomp_display_string (buffer
, size
, &ret
, "%", 1);
289 gomp_fatal ("leading zero not followed by dot in affinity format");
296 if (*p
>= '1' && *p
<= '9')
299 sz
= strtoul (p
, &end
, 10);
302 else if (zero
|| right
)
303 gomp_fatal ("leading zero or right justification in affinity format "
310 i
< sizeof (affinity_types
) / sizeof (affinity_types
[0]); ++i
)
311 if (strncmp (p
+ 1, affinity_types
[i
].long_str
,
312 affinity_types
[i
].long_len
) == 0
313 && p
[affinity_types
[i
].long_len
+ 1] == '}')
315 c
= affinity_types
[i
].short_c
;
316 p
+= affinity_types
[i
].long_len
+ 1;
321 char *q
= strchr (p
+ 1, '}');
323 gomp_fatal ("unsupported long type name '%.*s' in affinity "
324 "format", (int) (q
- (p
+ 1)), p
+ 1);
326 gomp_fatal ("unterminated long type name '%s' in affinity "
333 val
= omp_get_team_num ();
336 val
= omp_get_num_teams ();
345 val
= ts
->team
? ts
->team
->nthreads
: 1;
348 val
= ts
->team
? ts
->team
->prev_ts
.team_id
: -1;
351 gomp_display_hostname (buffer
, size
, &ret
, right
, sz
);
361 #if defined(LIBGOMP_USE_PTHREADS) && defined(__GNUC__)
363 char buf
[3 * (sizeof (handle
) + sizeof (uintptr_t) + sizeof (int))
365 /* This macro returns expr unmodified for integral or pointer
366 types and 0 for anything else (e.g. aggregates). */
367 #define gomp_nonaggregate(expr) \
368 __builtin_choose_expr (__builtin_classify_type (expr) == 1 \
369 || __builtin_classify_type (expr) == 5, expr, 0)
370 /* This macro returns expr unmodified for integral types,
371 (uintptr_t) (expr) for pointer types and 0 for anything else
372 (e.g. aggregates). */
373 #define gomp_integral(expr) \
374 __builtin_choose_expr (__builtin_classify_type (expr) == 5, \
375 (uintptr_t) gomp_nonaggregate (expr), \
376 gomp_nonaggregate (expr))
378 if (sizeof (gomp_integral (handle
)) == sizeof (unsigned long))
379 sprintf (buf
, "0x%lx", (unsigned long) gomp_integral (handle
));
380 #if defined (HAVE_INTTYPES_H) && defined (PRIx64)
381 else if (sizeof (gomp_integral (handle
)) == sizeof (uint64_t))
382 sprintf (buf
, "0x%" PRIx64
, (uint64_t) gomp_integral (handle
));
384 else if (sizeof (gomp_integral (handle
))
385 == sizeof (unsigned long long))
386 sprintf (buf
, "0x%llx",
387 (unsigned long long) gomp_integral (handle
));
390 sprintf (buf
, "0x%x", (unsigned int) gomp_integral (handle
));
391 gomp_display_num (buffer
, size
, &ret
, zero
, right
, sz
, buf
);
399 if (sz
== (size_t) -1)
400 gomp_display_affinity_place (buffer
, size
, &ret
,
405 gomp_display_affinity_place (NULL
, 0, &len
, place
- 1);
407 gomp_display_repeat (buffer
, size
, &ret
, ' ', sz
- len
);
408 gomp_display_affinity_place (buffer
, size
, &ret
, place
- 1);
413 gomp_display_affinity_place (buffer
, size
, &ret
, place
- 1);
414 if (ret
- start
< sz
)
415 gomp_display_repeat (buffer
, size
, &ret
, ' ', sz
- (ret
- start
));
419 gomp_display_int (buffer
, size
, &ret
, zero
, right
, sz
, val
);
422 gomp_fatal ("unsupported type %c in affinity format", c
);
431 omp_capture_affinity (char *buffer
, size_t size
, const char *format
)
433 struct gomp_thread
*thr
= gomp_thread ();
435 = gomp_display_affinity (buffer
, size
,
437 ? format
: gomp_affinity_format_var
,
438 gomp_thread_self (), &thr
->ts
, thr
->place
);
442 buffer
[size
- 1] = '\0';
448 ialias (omp_capture_affinity
)
451 omp_display_affinity (const char *format
)
455 size_t ret
= ialias_call (omp_capture_affinity
) (buf
, sizeof buf
, format
);
456 if (ret
< sizeof buf
)
459 fwrite (buf
, 1, ret
+ 1, stderr
);
462 b
= gomp_malloc (ret
+ 1);
463 ialias_call (omp_capture_affinity
) (b
, ret
+ 1, format
);
465 fwrite (b
, 1, ret
+ 1, stderr
);
470 gomp_display_affinity_thread (gomp_thread_handle handle
,
471 struct gomp_team_state
*ts
, unsigned int place
)
475 size_t ret
= gomp_display_affinity (buf
, sizeof buf
, gomp_affinity_format_var
,
477 if (ret
< sizeof buf
)
480 fwrite (buf
, 1, ret
+ 1, stderr
);
483 b
= gomp_malloc (ret
+ 1);
484 gomp_display_affinity (b
, ret
+ 1, gomp_affinity_format_var
,
487 fwrite (b
, 1, ret
+ 1, stderr
);