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>
|
2015-07-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
PR middle-end/66915
|
PR middle-end/66915
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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++)
|
||||||
|
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.
|
/* 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 (®ister_lock);
|
gomp_mutex_lock (®ister_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. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user