target.c (gomp_offload_image_to_device): Rename to ...
libgomp/ * target.c (gomp_offload_image_to_device): Rename to ... (gomp_load_image_to_device): ... here. (GOMP_offload_register): Adjust call. (gomp_init_device): Likewise. (gomp_unload_image_from_device): New. Broken out of ... (GOMP_offload_unregister): ... here. Call it. (gomp_unload_device): New. * libgomp.h (gomp_unload_device): Declare. * oacc-init.c (acc_shutdown_1): Unload from device before deleting mem maps. gcc/ * config/nvptx/mkoffload.c (process): Add static destructor call. From-SVN: r226039
This commit is contained in:
parent
c5189d8e67
commit
22be23495a
@ -1,3 +1,7 @@
|
||||
2015-07-21 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/nvptx/mkoffload.c (process): Add static destructor call.
|
||||
|
||||
2015-07-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
PR middle-end/66915
|
||||
|
@ -880,18 +880,29 @@ process (FILE *in, FILE *out)
|
||||
fprintf (out, "#ifdef __cplusplus\n"
|
||||
"extern \"C\" {\n"
|
||||
"#endif\n");
|
||||
|
||||
fprintf (out, "extern void GOMP_offload_register"
|
||||
" (const void *, int, const void *);\n");
|
||||
fprintf (out, "extern void GOMP_offload_unregister"
|
||||
" (const void *, int, const void *);\n");
|
||||
|
||||
fprintf (out, "#ifdef __cplusplus\n"
|
||||
"}\n"
|
||||
"#endif\n");
|
||||
|
||||
fprintf (out, "extern const void *const __OFFLOAD_TABLE__[];\n\n");
|
||||
fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
|
||||
fprintf (out, " GOMP_offload_register (__OFFLOAD_TABLE__, %d,\n",
|
||||
GOMP_DEVICE_NVIDIA_PTX);
|
||||
fprintf (out, " &target_data);\n");
|
||||
fprintf (out, "};\n");
|
||||
|
||||
fprintf (out, "static __attribute__((constructor)) void init (void)\n"
|
||||
"{\n"
|
||||
" GOMP_offload_register (__OFFLOAD_TABLE__, %d/*NVIDIA_PTX*/,\n"
|
||||
" &target_data);\n"
|
||||
"};\n", GOMP_DEVICE_NVIDIA_PTX);
|
||||
|
||||
fprintf (out, "static __attribute__((destructor)) void fini (void)\n"
|
||||
"{\n"
|
||||
" GOMP_offload_unregister (__OFFLOAD_TABLE__, %d/*NVIDIA_PTX*/,\n"
|
||||
" &target_data);\n"
|
||||
"};\n", GOMP_DEVICE_NVIDIA_PTX);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1,3 +1,16 @@
|
||||
2015-07-21 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* target.c (gomp_offload_image_to_device): Rename to ...
|
||||
(gomp_load_image_to_device): ... here.
|
||||
(GOMP_offload_register): Adjust call.
|
||||
(gomp_init_device): Likewise.
|
||||
(gomp_unload_image_from_device): New. Broken out of ...
|
||||
(GOMP_offload_unregister): ... here. Call it.
|
||||
(gomp_unload_device): New.
|
||||
* libgomp.h (gomp_unload_device): Declare.
|
||||
* oacc-init.c (acc_shutdown_1): Unload from device before deleting
|
||||
mem maps.
|
||||
|
||||
2015-07-20 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* oacc-parallel.c (GOACC_parallel): Move variadic handling into
|
||||
|
@ -782,6 +782,7 @@ extern void gomp_unmap_vars (struct target_mem_desc *, bool);
|
||||
extern void gomp_init_device (struct gomp_device_descr *);
|
||||
extern void gomp_free_memmap (struct splay_tree_s *);
|
||||
extern void gomp_fini_device (struct gomp_device_descr *);
|
||||
extern void gomp_unload_device (struct gomp_device_descr *);
|
||||
|
||||
/* work.c */
|
||||
|
||||
|
@ -252,6 +252,18 @@ acc_shutdown_1 (acc_device_t d)
|
||||
/* Get the base device for this device type. */
|
||||
base_dev = resolve_device (d, true);
|
||||
|
||||
ndevs = base_dev->get_num_devices_func ();
|
||||
|
||||
/* Unload all the devices of this type that have been opened. */
|
||||
for (i = 0; i < ndevs; i++)
|
||||
{
|
||||
struct gomp_device_descr *acc_dev = &base_dev[i];
|
||||
|
||||
gomp_mutex_lock (&acc_dev->lock);
|
||||
gomp_unload_device (acc_dev);
|
||||
gomp_mutex_unlock (&acc_dev->lock);
|
||||
}
|
||||
|
||||
gomp_mutex_lock (&goacc_thread_lock);
|
||||
|
||||
/* Free target-specific TLS data and close all devices. */
|
||||
@ -290,7 +302,6 @@ acc_shutdown_1 (acc_device_t d)
|
||||
|
||||
gomp_mutex_unlock (&goacc_thread_lock);
|
||||
|
||||
ndevs = base_dev->get_num_devices_func ();
|
||||
|
||||
/* Close all the devices of this type that have been opened. */
|
||||
for (i = 0; i < ndevs; i++)
|
||||
|
146
libgomp/target.c
146
libgomp/target.c
@ -638,12 +638,13 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs,
|
||||
|
||||
/* Load image pointed by TARGET_DATA to the device, specified by DEVICEP.
|
||||
And insert to splay tree the mapping between addresses from HOST_TABLE and
|
||||
from loaded target image. */
|
||||
from loaded target image. We rely in the host and device compiler
|
||||
emitting variable and functions in the same order. */
|
||||
|
||||
static void
|
||||
gomp_offload_image_to_device (struct gomp_device_descr *devicep,
|
||||
const void *host_table, const void *target_data,
|
||||
bool is_register_lock)
|
||||
gomp_load_image_to_device (struct gomp_device_descr *devicep,
|
||||
const void *host_table, const void *target_data,
|
||||
bool is_register_lock)
|
||||
{
|
||||
void **host_func_table = ((void ***) host_table)[0];
|
||||
void **host_funcs_end = ((void ***) host_table)[1];
|
||||
@ -658,7 +659,8 @@ gomp_offload_image_to_device (struct gomp_device_descr *devicep,
|
||||
/* Load image to device and get target addresses for the image. */
|
||||
struct addr_pair *target_table = NULL;
|
||||
int i, num_target_entries
|
||||
= devicep->load_image_func (devicep->target_id, target_data, &target_table);
|
||||
= devicep->load_image_func (devicep->target_id, target_data,
|
||||
&target_table);
|
||||
|
||||
if (num_target_entries != num_funcs + num_vars)
|
||||
{
|
||||
@ -725,6 +727,60 @@ gomp_offload_image_to_device (struct gomp_device_descr *devicep,
|
||||
free (target_table);
|
||||
}
|
||||
|
||||
/* Unload the mappings described by target_data from device DEVICE_P.
|
||||
The device must be locked. */
|
||||
|
||||
static void
|
||||
gomp_unload_image_from_device (struct gomp_device_descr *devicep,
|
||||
const void *host_table, const void *target_data)
|
||||
{
|
||||
void **host_func_table = ((void ***) host_table)[0];
|
||||
void **host_funcs_end = ((void ***) host_table)[1];
|
||||
void **host_var_table = ((void ***) host_table)[2];
|
||||
void **host_vars_end = ((void ***) host_table)[3];
|
||||
|
||||
/* The func table contains only addresses, the var table contains addresses
|
||||
and corresponding sizes. */
|
||||
int num_funcs = host_funcs_end - host_func_table;
|
||||
int num_vars = (host_vars_end - host_var_table) / 2;
|
||||
|
||||
unsigned j;
|
||||
struct splay_tree_key_s k;
|
||||
splay_tree_key node = NULL;
|
||||
|
||||
/* Find mapping at start of node array */
|
||||
if (num_funcs || num_vars)
|
||||
{
|
||||
k.host_start = (num_funcs ? (uintptr_t) host_func_table[0]
|
||||
: (uintptr_t) host_var_table[0]);
|
||||
k.host_end = k.host_start + 1;
|
||||
node = splay_tree_lookup (&devicep->mem_map, &k);
|
||||
}
|
||||
|
||||
devicep->unload_image_func (devicep->target_id, target_data);
|
||||
|
||||
/* Remove mappings from splay tree. */
|
||||
for (j = 0; j < num_funcs; j++)
|
||||
{
|
||||
k.host_start = (uintptr_t) host_func_table[j];
|
||||
k.host_end = k.host_start + 1;
|
||||
splay_tree_remove (&devicep->mem_map, &k);
|
||||
}
|
||||
|
||||
for (j = 0; j < num_vars; j++)
|
||||
{
|
||||
k.host_start = (uintptr_t) host_var_table[j * 2];
|
||||
k.host_end = k.host_start + (uintptr_t) host_var_table[j * 2 + 1];
|
||||
splay_tree_remove (&devicep->mem_map, &k);
|
||||
}
|
||||
|
||||
if (node)
|
||||
{
|
||||
free (node->tgt);
|
||||
free (node);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function should be called from every offload image while loading.
|
||||
It gets the descriptor of the host func and var tables HOST_TABLE, TYPE of
|
||||
the target, and TARGET_DATA needed by target plugin. */
|
||||
@ -742,7 +798,7 @@ GOMP_offload_register (const void *host_table, int target_type,
|
||||
struct gomp_device_descr *devicep = &devices[i];
|
||||
gomp_mutex_lock (&devicep->lock);
|
||||
if (devicep->type == target_type && devicep->is_initialized)
|
||||
gomp_offload_image_to_device (devicep, host_table, target_data, true);
|
||||
gomp_load_image_to_device (devicep, host_table, target_data, true);
|
||||
gomp_mutex_unlock (&devicep->lock);
|
||||
}
|
||||
|
||||
@ -767,69 +823,17 @@ void
|
||||
GOMP_offload_unregister (const void *host_table, int target_type,
|
||||
const void *target_data)
|
||||
{
|
||||
void **host_func_table = ((void ***) host_table)[0];
|
||||
void **host_funcs_end = ((void ***) host_table)[1];
|
||||
void **host_var_table = ((void ***) host_table)[2];
|
||||
void **host_vars_end = ((void ***) host_table)[3];
|
||||
int i;
|
||||
|
||||
/* The func table contains only addresses, the var table contains addresses
|
||||
and corresponding sizes. */
|
||||
int num_funcs = host_funcs_end - host_func_table;
|
||||
int num_vars = (host_vars_end - host_var_table) / 2;
|
||||
|
||||
gomp_mutex_lock (®ister_lock);
|
||||
|
||||
/* Unload image from all initialized devices. */
|
||||
for (i = 0; i < num_devices; i++)
|
||||
{
|
||||
int j;
|
||||
struct gomp_device_descr *devicep = &devices[i];
|
||||
gomp_mutex_lock (&devicep->lock);
|
||||
if (devicep->type != target_type || !devicep->is_initialized)
|
||||
{
|
||||
gomp_mutex_unlock (&devicep->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
devicep->unload_image_func (devicep->target_id, target_data);
|
||||
|
||||
/* Remove mapping from splay tree. */
|
||||
struct splay_tree_key_s k;
|
||||
splay_tree_key node = NULL;
|
||||
if (num_funcs > 0)
|
||||
{
|
||||
k.host_start = (uintptr_t) host_func_table[0];
|
||||
k.host_end = k.host_start + 1;
|
||||
node = splay_tree_lookup (&devicep->mem_map, &k);
|
||||
}
|
||||
else if (num_vars > 0)
|
||||
{
|
||||
k.host_start = (uintptr_t) host_var_table[0];
|
||||
k.host_end = k.host_start + (uintptr_t) host_var_table[1];
|
||||
node = splay_tree_lookup (&devicep->mem_map, &k);
|
||||
}
|
||||
|
||||
for (j = 0; j < num_funcs; j++)
|
||||
{
|
||||
k.host_start = (uintptr_t) host_func_table[j];
|
||||
k.host_end = k.host_start + 1;
|
||||
splay_tree_remove (&devicep->mem_map, &k);
|
||||
}
|
||||
|
||||
for (j = 0; j < num_vars; j++)
|
||||
{
|
||||
k.host_start = (uintptr_t) host_var_table[j * 2];
|
||||
k.host_end = k.host_start + (uintptr_t) host_var_table[j * 2 + 1];
|
||||
splay_tree_remove (&devicep->mem_map, &k);
|
||||
}
|
||||
|
||||
if (node)
|
||||
{
|
||||
free (node->tgt);
|
||||
free (node);
|
||||
}
|
||||
|
||||
if (devicep->type == target_type && devicep->is_initialized)
|
||||
gomp_unload_image_from_device (devicep, host_table, target_data);
|
||||
gomp_mutex_unlock (&devicep->lock);
|
||||
}
|
||||
|
||||
@ -858,13 +862,31 @@ gomp_init_device (struct gomp_device_descr *devicep)
|
||||
{
|
||||
struct offload_image_descr *image = &offload_images[i];
|
||||
if (image->type == devicep->type)
|
||||
gomp_offload_image_to_device (devicep, image->host_table,
|
||||
image->target_data, false);
|
||||
gomp_load_image_to_device (devicep, image->host_table,
|
||||
image->target_data, false);
|
||||
}
|
||||
|
||||
devicep->is_initialized = true;
|
||||
}
|
||||
|
||||
attribute_hidden void
|
||||
gomp_unload_device (struct gomp_device_descr *devicep)
|
||||
{
|
||||
if (devicep->is_initialized)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Unload from device all images registered at the moment. */
|
||||
for (i = 0; i < num_offload_images; i++)
|
||||
{
|
||||
struct offload_image_descr *image = &offload_images[i];
|
||||
if (image->type == devicep->type)
|
||||
gomp_unload_image_from_device (devicep, image->host_table,
|
||||
image->target_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free address mapping tables. MM must be locked on entry, and remains locked
|
||||
on return. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user