]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgomp/config/accel/target-indirect.c
Update copyright years.
[thirdparty/gcc.git] / libgomp / config / accel / target-indirect.c
1 /* Copyright (C) 2023-2024 Free Software Foundation, Inc.
2
3 Contributed by Siemens.
4
5 This file is part of the GNU Offloading and Multi Processing Library
6 (libgomp).
7
8 Libgomp is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
26
27 #include <assert.h>
28 #include "libgomp.h"
29
30 #define splay_tree_prefix indirect
31 #define splay_tree_c
32 #include "splay-tree.h"
33
34 volatile void **GOMP_INDIRECT_ADDR_MAP = NULL;
35
36 /* Use a splay tree to lookup the target address instead of using a
37 linear search. */
38 #define USE_SPLAY_TREE_LOOKUP
39
40 #ifdef USE_SPLAY_TREE_LOOKUP
41
42 static struct indirect_splay_tree_s indirect_map;
43 static indirect_splay_tree_node indirect_array = NULL;
44
45 /* Build the splay tree used for host->target address lookups. */
46
47 void
48 build_indirect_map (void)
49 {
50 size_t num_ind_funcs = 0;
51 volatile void **map_entry;
52 static int lock = 0; /* == gomp_mutex_t lock; gomp_mutex_init (&lock); */
53
54 if (!GOMP_INDIRECT_ADDR_MAP)
55 return;
56
57 gomp_mutex_lock (&lock);
58
59 if (!indirect_array)
60 {
61 /* Count the number of entries in the NULL-terminated address map. */
62 for (map_entry = GOMP_INDIRECT_ADDR_MAP; *map_entry;
63 map_entry += 2, num_ind_funcs++);
64
65 /* Build splay tree for address lookup. */
66 indirect_array = gomp_malloc (num_ind_funcs * sizeof (*indirect_array));
67 indirect_splay_tree_node array = indirect_array;
68 map_entry = GOMP_INDIRECT_ADDR_MAP;
69
70 for (int i = 0; i < num_ind_funcs; i++, array++)
71 {
72 indirect_splay_tree_key k = &array->key;
73 k->host_addr = (uint64_t) *map_entry++;
74 k->target_addr = (uint64_t) *map_entry++;
75 array->left = NULL;
76 array->right = NULL;
77 indirect_splay_tree_insert (&indirect_map, array);
78 }
79 }
80
81 gomp_mutex_unlock (&lock);
82 }
83
84 void *
85 GOMP_target_map_indirect_ptr (void *ptr)
86 {
87 /* NULL pointers always resolve to NULL. */
88 if (!ptr)
89 return ptr;
90
91 assert (indirect_array);
92
93 struct indirect_splay_tree_key_s k;
94 indirect_splay_tree_key node = NULL;
95
96 k.host_addr = (uint64_t) ptr;
97 node = indirect_splay_tree_lookup (&indirect_map, &k);
98
99 return node ? (void *) node->target_addr : ptr;
100 }
101
102 #else
103
104 void
105 build_indirect_map (void)
106 {
107 }
108
109 void *
110 GOMP_target_map_indirect_ptr (void *ptr)
111 {
112 /* NULL pointers always resolve to NULL. */
113 if (!ptr)
114 return ptr;
115
116 assert (GOMP_INDIRECT_ADDR_MAP);
117
118 for (volatile void **map_entry = GOMP_INDIRECT_ADDR_MAP; *map_entry;
119 map_entry += 2)
120 if (*map_entry == ptr)
121 return (void *) *(map_entry + 1);
122
123 return ptr;
124 }
125
126 #endif