+2015-12-14 Ilya Verbin <ilya.verbin@intel.com>
+
+ * libgomp.h (gomp_device_state): New enum.
+ (struct gomp_device_descr): Replace is_initialized with state.
+ (gomp_fini_device): Remove declaration.
+ * oacc-host.c (host_dispatch): Use state instead of is_initialized.
+ * oacc-init.c (acc_init_1): Use state instead of is_initialized.
+ (acc_shutdown_1): Likewise. Inline gomp_fini_device.
+ (acc_set_device_type): Use state instead of is_initialized.
+ (acc_set_device_num): Likewise.
+ * target.c (resolve_device): Use state instead of is_initialized.
+ Do not initialize finalized device.
+ (gomp_map_vars): Do nothing if device is finalized.
+ (gomp_unmap_vars): Likewise.
+ (gomp_update): Likewise.
+ (GOMP_offload_register_ver): Use state instead of is_initialized.
+ (GOMP_offload_unregister_ver): Likewise.
+ (gomp_init_device): Likewise.
+ (gomp_unload_device): Likewise.
+ (gomp_fini_device): Remove.
+ (gomp_get_target_fn_addr): Do nothing if device is finalized.
+ (GOMP_target): Go to host fallback if device is finalized.
+ (GOMP_target_ext): Likewise.
+ (gomp_exit_data): Do nothing if device is finalized.
+ (gomp_target_task_fn): Go to host fallback if device is finalized.
+ (gomp_target_fini): New static function.
+ (gomp_target_init): Use state instead of is_initialized.
+ Call gomp_target_fini at exit.
+
2015-12-09 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68716
acc_dev = &base_dev[goacc_device_num];
gomp_mutex_lock (&acc_dev->lock);
- if (acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_INITIALIZED)
{
gomp_mutex_unlock (&acc_dev->lock);
gomp_fatal ("device already active");
{
struct gomp_device_descr *acc_dev = &base_dev[i];
gomp_mutex_lock (&acc_dev->lock);
- if (acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_INITIALIZED)
{
devices_active = true;
- gomp_fini_device (acc_dev);
+ acc_dev->fini_device_func (acc_dev->target_id);
+ acc_dev->state = GOMP_DEVICE_UNINITIALIZED;
}
gomp_mutex_unlock (&acc_dev->lock);
}
acc_dev = &base_dev[goacc_device_num];
gomp_mutex_lock (&acc_dev->lock);
- if (!acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_UNINITIALIZED)
gomp_init_device (acc_dev);
gomp_mutex_unlock (&acc_dev->lock);
acc_dev = &base_dev[ord];
gomp_mutex_lock (&acc_dev->lock);
- if (!acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_UNINITIALIZED)
gomp_init_device (acc_dev);
gomp_mutex_unlock (&acc_dev->lock);
return NULL;
gomp_mutex_lock (&devices[device_id].lock);
- if (!devices[device_id].is_initialized)
+ if (devices[device_id].state == GOMP_DEVICE_UNINITIALIZED)
gomp_init_device (&devices[device_id]);
+ else if (devices[device_id].state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devices[device_id].lock);
+ return NULL;
+ }
gomp_mutex_unlock (&devices[device_id].lock);
return &devices[device_id];
}
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ free (tgt);
+ return NULL;
+ }
for (i = 0; i < mapnum; i++)
{
}
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ free (tgt->array);
+ free (tgt);
+ return;
+ }
size_t i;
for (i = 0; i < tgt->list_count; i++)
return;
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ return;
+ }
+
for (i = 0; i < mapnum; i++)
if (sizes[i])
{
{
struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock);
- if (devicep->type == target_type && devicep->is_initialized)
+ if (devicep->type == target_type
+ && devicep->state == GOMP_DEVICE_INITIALIZED)
gomp_load_image_to_device (devicep, version,
host_table, target_data, true);
gomp_mutex_unlock (&devicep->lock);
{
struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock);
- if (devicep->type == target_type && devicep->is_initialized)
+ if (devicep->type == target_type
+ && devicep->state == GOMP_DEVICE_INITIALIZED)
gomp_unload_image_from_device (devicep, version,
host_table, target_data);
gomp_mutex_unlock (&devicep->lock);
false);
}
- devicep->is_initialized = true;
+ devicep->state = GOMP_DEVICE_INITIALIZED;
}
attribute_hidden void
gomp_unload_device (struct gomp_device_descr *devicep)
{
- if (devicep->is_initialized)
+ if (devicep->state == GOMP_DEVICE_INITIALIZED)
{
unsigned i;
}
}
-/* This function de-initializes the target device, specified by DEVICEP.
- DEVICEP must be locked on entry, and remains locked on return. */
-
-attribute_hidden void
-gomp_fini_device (struct gomp_device_descr *devicep)
-{
- if (devicep->is_initialized)
- devicep->fini_device_func (devicep->target_id);
-
- devicep->is_initialized = false;
-}
-
/* Host fallback for GOMP_target{,_ext} routines. */
static void
else
{
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ return NULL;
+ }
+
struct splay_tree_key_s k;
k.host_start = (uintptr_t) host_fn;
k.host_end = k.host_start + 1;
{
struct gomp_device_descr *devicep = resolve_device (device);
+ void *fn_addr;
if (devicep == NULL
- || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
+ || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
+ || !(fn_addr = gomp_get_target_fn_addr (devicep, fn)))
return gomp_target_fallback (fn, hostaddrs);
- void *fn_addr = gomp_get_target_fn_addr (devicep, fn);
-
struct target_mem_desc *tgt_vars
= gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, false,
GOMP_MAP_VARS_TARGET);
gomp_task_maybe_wait_for_dependencies (depend);
}
+ void *fn_addr;
if (devicep == NULL
- || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
+ || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
+ || !(fn_addr = gomp_get_target_fn_addr (devicep, fn)))
{
gomp_target_fallback_firstprivate (fn, mapnum, hostaddrs, sizes, kinds);
return;
}
- void *fn_addr = gomp_get_target_fn_addr (devicep, fn);
-
struct target_mem_desc *tgt_vars
= gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, true,
GOMP_MAP_VARS_TARGET);
const int typemask = 0xff;
size_t i;
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ return;
+ }
+
for (i = 0; i < mapnum; i++)
{
struct splay_tree_key_s cur_node;
if (ttask->fn != NULL)
{
+ void *fn_addr;
if (devicep == NULL
- || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
+ || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
+ || !(fn_addr = gomp_get_target_fn_addr (devicep, ttask->fn)))
{
ttask->state = GOMP_TARGET_TASK_FALLBACK;
gomp_target_fallback_firstprivate (ttask->fn, ttask->mapnum,
return false;
}
- void *fn_addr = gomp_get_target_fn_addr (devicep, ttask->fn);
ttask->tgt
= gomp_map_vars (devicep, ttask->mapnum, ttask->hostaddrs, NULL,
ttask->sizes, ttask->kinds, true,
return 0;
}
+/* This function finalizes all initialized devices. */
+
+static void
+gomp_target_fini (void)
+{
+ int i;
+ for (i = 0; i < num_devices; i++)
+ {
+ struct gomp_device_descr *devicep = &devices[i];
+ gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_INITIALIZED)
+ {
+ devicep->fini_device_func (devicep->target_id);
+ devicep->state = GOMP_DEVICE_FINALIZED;
+ }
+ gomp_mutex_unlock (&devicep->lock);
+ }
+}
+
/* This function initializes the runtime needed for offloading.
It parses the list of offload targets and tries to load the plugins for
these targets. On return, the variables NUM_DEVICES and NUM_DEVICES_OPENMP
/* current_device.capabilities has already been set. */
current_device.type = current_device.get_type_func ();
current_device.mem_map.root = NULL;
- current_device.is_initialized = false;
+ current_device.state = GOMP_DEVICE_UNINITIALIZED;
current_device.openacc.data_environ = NULL;
for (i = 0; i < new_num_devices; i++)
{
if (devices[i].capabilities & GOMP_OFFLOAD_CAP_OPENACC_200)
goacc_register (&devices[i]);
}
+
+ if (atexit (gomp_target_fini) != 0)
+ gomp_fatal ("atexit failed");
}
#else /* PLUGIN_SUPPORT */