static void acc_shutdown_1 (acc_device_t d) { struct goacc_thread *walk; /* We don't check whether d matches the actual device found, because OpenACC 2.0 (3.2.12) says the parameters to the init and this call must match (for the shutdown call anyway, it's silent on others). */ if (!base_dev) gomp_fatal ("no device initialized"); if (d != init_key) gomp_fatal ("device %u(%u) is initialized", (unsigned) init_key, (unsigned) base_dev->type); gomp_mutex_lock (&goacc_thread_lock); /* Free target-specific TLS data and close all devices. */ for (walk = goacc_threads; walk != NULL; walk = walk->next) { if (walk->target_tls) base_dev->openacc.destroy_thread_data_func (walk->target_tls); walk->target_tls = NULL; /* This would mean the user is shutting down OpenACC in the middle of an "acc data" pragma. Likely not intentional. */ if (walk->mapped_data) gomp_fatal ("shutdown in 'acc data' region"); if (walk->dev) { void *target_data = walk->dev->openacc.target_data; if (walk->dev->openacc.close_device_func (target_data) < 0) gomp_fatal ("failed to close device"); walk->dev->openacc.target_data = target_data = NULL; struct gomp_memory_mapping *mem_map = &walk->dev->mem_map; gomp_mutex_lock (&mem_map->lock); gomp_free_memmap (mem_map); gomp_mutex_unlock (&mem_map->lock); walk->dev = NULL; } } gomp_mutex_unlock (&goacc_thread_lock); gomp_fini_device (base_dev); base_dev = NULL; }
static void acc_shutdown_1 (acc_device_t d) { struct gomp_device_descr *base_dev; struct goacc_thread *walk; int ndevs, i; bool devices_active = false; /* Get the base device for this device type. */ base_dev = resolve_device (d); if (!base_dev) gomp_fatal ("device %s not supported", name_of_acc_device_t (d)); gomp_mutex_lock (&goacc_thread_lock); /* Free target-specific TLS data and close all devices. */ for (walk = goacc_threads; walk != NULL; walk = walk->next) { if (walk->target_tls) base_dev->openacc.destroy_thread_data_func (walk->target_tls); walk->target_tls = NULL; /* This would mean the user is shutting down OpenACC in the middle of an "acc data" pragma. Likely not intentional. */ if (walk->mapped_data) { gomp_mutex_unlock (&goacc_thread_lock); gomp_fatal ("shutdown in 'acc data' region"); } /* Similarly, if this happens then user code has done something weird. */ if (walk->saved_bound_dev) { gomp_mutex_unlock (&goacc_thread_lock); gomp_fatal ("shutdown during host fallback"); } if (walk->dev) { gomp_mutex_lock (&walk->dev->lock); gomp_free_memmap (&walk->dev->mem_map); gomp_mutex_unlock (&walk->dev->lock); walk->dev = NULL; walk->base_dev = NULL; } } 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++) { struct gomp_device_descr *acc_dev = &base_dev[i]; gomp_mutex_lock (&acc_dev->lock); if (acc_dev->is_initialized) { devices_active = true; gomp_fini_device (acc_dev); } gomp_mutex_unlock (&acc_dev->lock); } if (!devices_active) gomp_fatal ("no device initialized"); }