1/* { dg-do run } */
2
3#include <stdio.h>
4#include <pthread.h>
5#include <string.h>
6#include <stdlib.h>
7#include <errno.h>
8#include <ctype.h>
9#include <openacc.h>
10
11unsigned char **x;
12void **d_x;
13const int N = 16;
14const int NTHREADS = 32;
15
16static void *
17test (void *arg)
18{
19  int i;
20  int tid;
21  unsigned char *p;
22  int devnum;
23
24  tid = (int) (long) arg;
25
26  devnum = acc_get_device_num (acc_device_nvidia);
27  acc_set_device_num (devnum, acc_device_nvidia);
28
29  if (acc_get_current_cuda_context () == NULL)
30    abort ();
31
32  p = (unsigned char *) malloc (N);
33
34  for (i = 0; i < N; i++)
35    {
36      p[i] = tid;
37    }
38
39  x[tid] = p;
40
41  d_x[tid] = acc_copyin (p, N);
42
43  return 0;
44}
45
46int
47main (int argc, char **argv)
48{
49  int i;
50  pthread_attr_t attr;
51  pthread_t *tid;
52
53  if (acc_get_num_devices (acc_device_nvidia) == 0)
54    return 0;
55
56  acc_init (acc_device_nvidia);
57
58  x = (unsigned char **) malloc (NTHREADS * N);
59  d_x = (void **) malloc (NTHREADS * N);
60
61  if (pthread_attr_init (&attr) != 0)
62    perror ("pthread_attr_init failed");
63
64  tid = (pthread_t *) malloc (NTHREADS * sizeof (pthread_t));
65
66  for (i = 0; i < NTHREADS; i++)
67    {
68      if (pthread_create (&tid[i], &attr, &test, (void *) (unsigned long) (i))
69	  != 0)
70	perror ("pthread_create failed");
71    }
72
73  if (pthread_attr_destroy (&attr) != 0)
74    perror ("pthread_attr_destroy failed");
75
76  for (i = 0; i < NTHREADS; i++)
77    {
78      void *res;
79
80      if (pthread_join (tid[i], &res) != 0)
81	perror ("pthread join failed");
82    }
83
84  for (i = 0; i < NTHREADS; i++)
85    {
86      if (acc_is_present (x[i], N) != 1)
87	abort ();
88    }
89
90  for (i = 0; i < NTHREADS; i++)
91    {
92      memset (x[i], 0, N);
93      acc_copyout (x[i], N);
94    }
95
96  for (i = 0; i < NTHREADS; i++)
97    {
98      unsigned char *p;
99      int j;
100
101      p = x[i];
102
103      for (j = 0; j < N; j++)
104	{
105	  if (p[j] != i)
106	    abort ();
107	}
108
109      if (acc_is_present (x[i], N) != 0)
110	abort ();
111    }
112
113  acc_shutdown (acc_device_nvidia);
114
115  return 0;
116}
117
118/* { dg-output "" } */
119