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:
Nathan Sidwell 2015-07-21 13:30:06 +00:00 committed by Nathan Sidwell
parent c5189d8e67
commit 22be23495a
6 changed files with 130 additions and 68 deletions

View File

@ -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> 2015-07-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR middle-end/66915 PR middle-end/66915

View File

@ -880,18 +880,29 @@ process (FILE *in, FILE *out)
fprintf (out, "#ifdef __cplusplus\n" fprintf (out, "#ifdef __cplusplus\n"
"extern \"C\" {\n" "extern \"C\" {\n"
"#endif\n"); "#endif\n");
fprintf (out, "extern void GOMP_offload_register" fprintf (out, "extern void GOMP_offload_register"
" (const void *, int, const void *);\n"); " (const void *, int, const void *);\n");
fprintf (out, "extern void GOMP_offload_unregister"
" (const void *, int, const void *);\n");
fprintf (out, "#ifdef __cplusplus\n" fprintf (out, "#ifdef __cplusplus\n"
"}\n" "}\n"
"#endif\n"); "#endif\n");
fprintf (out, "extern const void *const __OFFLOAD_TABLE__[];\n\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", fprintf (out, "static __attribute__((constructor)) void init (void)\n"
GOMP_DEVICE_NVIDIA_PTX); "{\n"
fprintf (out, " &target_data);\n"); " GOMP_offload_register (__OFFLOAD_TABLE__, %d/*NVIDIA_PTX*/,\n"
fprintf (out, "};\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 static void

View File

@ -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> 2015-07-20 Nathan Sidwell <nathan@codesourcery.com>
* oacc-parallel.c (GOACC_parallel): Move variadic handling into * oacc-parallel.c (GOACC_parallel): Move variadic handling into

View File

@ -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_init_device (struct gomp_device_descr *);
extern void gomp_free_memmap (struct splay_tree_s *); extern void gomp_free_memmap (struct splay_tree_s *);
extern void gomp_fini_device (struct gomp_device_descr *); extern void gomp_fini_device (struct gomp_device_descr *);
extern void gomp_unload_device (struct gomp_device_descr *);
/* work.c */ /* work.c */

View File

@ -252,6 +252,18 @@ acc_shutdown_1 (acc_device_t d)
/* Get the base device for this device type. */ /* Get the base device for this device type. */
base_dev = resolve_device (d, true); 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); gomp_mutex_lock (&goacc_thread_lock);
/* Free target-specific TLS data and close all devices. */ /* 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); gomp_mutex_unlock (&goacc_thread_lock);
ndevs = base_dev->get_num_devices_func ();
/* Close all the devices of this type that have been opened. */ /* Close all the devices of this type that have been opened. */
for (i = 0; i < ndevs; i++) for (i = 0; i < ndevs; i++)

View File

@ -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. /* 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 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 static void
gomp_offload_image_to_device (struct gomp_device_descr *devicep, gomp_load_image_to_device (struct gomp_device_descr *devicep,
const void *host_table, const void *target_data, const void *host_table, const void *target_data,
bool is_register_lock) bool is_register_lock)
{ {
void **host_func_table = ((void ***) host_table)[0]; void **host_func_table = ((void ***) host_table)[0];
void **host_funcs_end = ((void ***) host_table)[1]; 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. */ /* Load image to device and get target addresses for the image. */
struct addr_pair *target_table = NULL; struct addr_pair *target_table = NULL;
int i, num_target_entries 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) 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); 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. /* 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 It gets the descriptor of the host func and var tables HOST_TABLE, TYPE of
the target, and TARGET_DATA needed by target plugin. */ 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]; struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock); gomp_mutex_lock (&devicep->lock);
if (devicep->type == target_type && devicep->is_initialized) 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); gomp_mutex_unlock (&devicep->lock);
} }
@ -767,69 +823,17 @@ void
GOMP_offload_unregister (const void *host_table, int target_type, GOMP_offload_unregister (const void *host_table, int target_type,
const void *target_data) 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; 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 (&register_lock); gomp_mutex_lock (&register_lock);
/* Unload image from all initialized devices. */ /* Unload image from all initialized devices. */
for (i = 0; i < num_devices; i++) for (i = 0; i < num_devices; i++)
{ {
int j;
struct gomp_device_descr *devicep = &devices[i]; struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock); gomp_mutex_lock (&devicep->lock);
if (devicep->type != target_type || !devicep->is_initialized) if (devicep->type == target_type && devicep->is_initialized)
{ gomp_unload_image_from_device (devicep, host_table, target_data);
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);
}
gomp_mutex_unlock (&devicep->lock); 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]; struct offload_image_descr *image = &offload_images[i];
if (image->type == devicep->type) if (image->type == devicep->type)
gomp_offload_image_to_device (devicep, image->host_table, gomp_load_image_to_device (devicep, image->host_table,
image->target_data, false); image->target_data, false);
} }
devicep->is_initialized = true; 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 /* Free address mapping tables. MM must be locked on entry, and remains locked
on return. */ on return. */