1 /* Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 Contributed by Siemens.
5 This file is part of the GNU Offloading and Multi Processing Library
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)
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
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.
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/>. */
30 #define splay_tree_prefix indirect
32 #include "splay-tree.h"
34 volatile void **GOMP_INDIRECT_ADDR_MAP
= NULL
;
36 /* Use a splay tree to lookup the target address instead of using a
38 #define USE_SPLAY_TREE_LOOKUP
40 #ifdef USE_SPLAY_TREE_LOOKUP
42 static struct indirect_splay_tree_s indirect_map
;
43 static indirect_splay_tree_node indirect_array
= NULL
;
45 /* Build the splay tree used for host->target address lookups. */
48 build_indirect_map (void)
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); */
54 if (!GOMP_INDIRECT_ADDR_MAP
)
57 gomp_mutex_lock (&lock
);
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
++);
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
;
70 for (int i
= 0; i
< num_ind_funcs
; i
++, array
++)
72 indirect_splay_tree_key k
= &array
->key
;
73 k
->host_addr
= (uint64_t) *map_entry
++;
74 k
->target_addr
= (uint64_t) *map_entry
++;
77 indirect_splay_tree_insert (&indirect_map
, array
);
81 gomp_mutex_unlock (&lock
);
85 GOMP_target_map_indirect_ptr (void *ptr
)
87 /* NULL pointers always resolve to NULL. */
91 assert (indirect_array
);
93 struct indirect_splay_tree_key_s k
;
94 indirect_splay_tree_key node
= NULL
;
96 k
.host_addr
= (uint64_t) ptr
;
97 node
= indirect_splay_tree_lookup (&indirect_map
, &k
);
99 return node
? (void *) node
->target_addr
: ptr
;
105 build_indirect_map (void)
110 GOMP_target_map_indirect_ptr (void *ptr
)
112 /* NULL pointers always resolve to NULL. */
116 assert (GOMP_INDIRECT_ADDR_MAP
);
118 for (volatile void **map_entry
= GOMP_INDIRECT_ADDR_MAP
; *map_entry
;
120 if (*map_entry
== ptr
)
121 return (void *) *(map_entry
+ 1);