Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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");
}