1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define _GNU_SOURCE
17 
18 #include <pthread.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include "local_poc.h"
27 
28 
29 int fd;
30 struct mdp_rotation_config config;
31 int id;
32 int status[10];
33 int cmd = 0;
34 
threadForConfig(void * arg)35 void *threadForConfig(void *arg)
36 {
37     int index = (int) (unsigned long)arg;
38 
39     status[index] = 1;
40 
41     while (cmd != 1) {
42         usleep(10);
43     }
44 
45     if (cmd == -1)
46         goto failed;
47 
48     usleep(5 * index);
49     ioctl(fd, MDSS_ROTATION_CONFIG, &config);
50 failed:
51     status[index] = 2;
52     return NULL;
53 
54 }
55 
threadForClose()56 void *threadForClose()
57 {
58     status[0] = 1;
59 
60     while (cmd != 1) {
61         usleep(10);
62     }
63 
64      if (cmd == -1)
65         goto failed;
66 
67     usleep(50);
68     ioctl(fd, MDSS_ROTATION_CLOSE, id);
69 failed:
70     status[0] = 2;
71     return NULL;
72 }
73 
main()74 int main()
75 {
76     int ret, i, count;
77     pthread_t tid[5];
78     int p = 5;
79 
80     count = 0;
81 retry:
82     if (p-- > 0){
83         fork();
84     }
85 
86     cmd = 0;
87     for (i = 0; i < 10; i++)
88         status[i] = 0;
89 
90     fd = open("/dev/mdss_rotator", O_RDONLY, 0);
91     if (fd < 0) {
92 	return -1;
93     }
94 
95     ret = ioctl(fd, MDSS_ROTATION_OPEN, &config);
96     if (ret < 0) {
97 	goto failed;
98     } else {
99         id = config.session_id;
100     }
101 
102     ret = pthread_create(&tid[0], NULL, threadForClose, NULL);
103     if (ret != 0) {
104         printf("thread failed! errno:%d err:%s\n",errno,strerror(errno));
105         goto failed;
106     }
107 
108     for (i = 1; i < 10; i++) {
109         ret = pthread_create(&tid[1], NULL, threadForConfig, (void *)(unsigned long)i);
110         if (ret != 0) {
111             cmd = -1;
112             goto failed;
113         }
114     }
115 
116     while (status[0] != 1 || status[1] != 1 || status[2] != 1
117         || status[3] != 1 || status[4] != 1 || status[5] != 1
118         || status[6] != 1 || status[7] != 1 || status[8] != 1
119         || status[9] != 1) {
120         usleep(50);
121     }
122 
123     cmd = 1;
124     usleep(10);
125     ioctl(fd, MDSS_ROTATION_CONFIG, &config);
126 
127     while (status[0] != 2 || status[1] != 2 || status[2] != 2
128         || status[3] != 2 || status[4] != 2 || status[5] != 2
129         || status[6] != 2 || status[7] != 2 || status[8] != 2
130         || status[9] != 2) {
131         usleep(50);
132     }
133 
134 
135 failed:
136     close(fd);
137     printf("[pid:%d] try %d again!\n", getpid(), ++count);
138     goto retry;
139 
140     return 0;
141 }
142