tizen 2.4 release
[framework/uifw/xorg/lib/libxshmfence.git] / test / xshmfence_test.c
1 /*
2  * Copyright © 2013 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <stddef.h>
26 #include <stdlib.h>
27 #include <xshmfence.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32
33 #define NCHILD  5               /* number of child processes to fork */
34 #define NCHECK  10              /* number of times to signal the fence */
35
36 /* Catch an alarm and bail
37  */
38 static void
39 sigalrm(int sig)
40 {
41     write(2, "caught alarm\n", 13);
42     exit(1);
43 }
44
45 int
46 main(int argc, char **argv)
47 {
48     int                 fd;
49     struct xshmfence    *x;
50     int                 i;
51     int                 c;
52     int                 pid;
53     int                 status;
54     int                 failed = 0;
55
56     /* Allocate a fence
57      */
58     fd = xshmfence_alloc_shm();
59     if (fd < 0) {
60         perror("xshmfence_alloc_shm");
61         exit(1);
62     }
63
64     /* fork NCHILD processes to wait for the fence
65      */
66     for (c = 0; c < NCHILD; c++) {
67         switch (fork()) {
68         case -1:
69             perror("fork");
70             exit(1);
71         case 0:
72
73             /* Set an alarm to limit how long
74              * to wait
75              */
76             signal(SIGALRM, sigalrm);
77             alarm(10);
78     
79             /* Map the fence
80              */
81             x = xshmfence_map_shm(fd);
82             if (!x) {
83                 fprintf(stderr, "%6d: ", c);
84                 perror("xshmfence_map_shm");
85                 exit(1);
86             }
87
88             for (i = 0; i < NCHECK; i++) {
89
90                 /* Verify that the fence is currently reset
91                  */
92                 if (xshmfence_query(x) != 0) {
93                     fprintf(stderr, "%6d: query reset failed\n", c);
94                     exit(1);
95                 }
96
97                 /* Wait for the fence
98                  */
99                 fprintf(stderr, "%6d: waiting\n", c);
100                 if (xshmfence_await(x) < 0) {
101                     fprintf(stderr, "%6d: ", c);
102                     perror("xshmfence_await");
103                     exit(1);
104                 }
105
106                 fprintf(stderr, "%6d: awoken\n", c);
107
108                 /* Verify that the fence is currently triggered
109                  */
110                 if (xshmfence_query(x) == 0) {
111                     fprintf(stderr, "%6d: query triggered failed\n", c);
112                     exit(1);
113                 }
114
115                 usleep(10 * 1000);
116
117                 /* Reset the fence
118                  */
119                 if (c == 0)
120                     xshmfence_reset(x);
121
122                 usleep(10 * 1000);
123             }
124             fprintf(stderr, "%6d: done\n", c);
125             exit(0);
126         }
127     }
128
129     /* Map the fence into the parent process
130      */
131     x = xshmfence_map_shm(fd);
132     if (!x) {
133         perror("xshmfence_map_shm");
134         exit(1);
135     }
136
137     for (i = 0; i < NCHECK; i++) {
138         usleep(100 * 1000);
139         fprintf(stderr, "trigger\n");
140
141         /* Verify that the fence is reset
142          */
143         if (xshmfence_query(x) != 0) {
144             fprintf(stderr, "query reset failed\n");
145             exit(1);
146         }
147
148         /* Trigger the fence
149          */
150         if (xshmfence_trigger(x) < 0) {
151             perror("xshmfence_trigger");
152             exit(1);
153         }
154
155         /* Verify that the fence is triggered
156          */
157         if (xshmfence_query(x) == 0) {
158             fprintf (stderr, "query triggered failed\n");
159             exit(1);
160         }
161
162         fprintf(stderr, "trigger done\n");
163     }
164
165     /* Reap all of the child processes
166      */
167     for (c = 0; c < NCHILD; c++) {
168         pid = wait(&status);
169         if (pid < 0) {
170             perror("wait");
171             exit(1);
172         }
173         fprintf(stderr, "child %d done %d\n", pid, status);
174         if (status)
175             failed++;
176     }
177     exit(failed);
178 }