1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
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
17 #define MODULE_TAG "mpp_thread_test"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "rk_type.h"
24
25 #include "mpp_debug.h"
26 #include "mpp_thread.h"
27 #include "mpp_time.h"
28
29 // TODO: add thread mutex and condition test case
30
31 #define MAX_THREAD_NUM 10
32 #define MAX_LOCK_LOOP 10000
33
34 static RK_S32 thread_debug = 0;
35 #define thread_dbg(fmt, ...) _mpp_dbg(thread_debug, 1, fmt, ## __VA_ARGS__)
36
37 static pthread_mutex_t mutex_0;
38 static pthread_mutex_t mutex_1;
39 static pthread_cond_t cond_0;
40 static pthread_cond_t cond_1;
41 static volatile RK_S32 flag_0 = 1;
42 static volatile RK_S32 flag_1 = 1;
43
thread_test(void * pdata)44 void *thread_test(void *pdata)
45 {
46 int idx = *((int*)pdata);
47 mpp_log("thread %d is running\n", idx);
48 sleep(1);
49 mpp_log("thread %d done\n", idx);
50 return NULL;
51 }
52
mutex_performance_test_loop_0(void * arg)53 void* mutex_performance_test_loop_0(void *arg)
54 {
55 RK_S32 i = 0;
56
57 for (i = 0; i < MAX_LOCK_LOOP; i++) {
58 thread_dbg("0 %5d lock\n", i);
59 pthread_mutex_lock(&mutex_0);
60
61 thread_dbg("0 %5d wait flag %d\n", i, flag_0);
62 if (flag_0) {
63 pthread_cond_wait(&cond_0, &mutex_0);
64 }
65
66 thread_dbg("0 %5d signal\n", i);
67 pthread_mutex_lock(&mutex_1);
68 flag_1 = 0;
69 pthread_cond_signal(&cond_1);
70 pthread_mutex_unlock(&mutex_1);
71
72 thread_dbg("0 %5d unlock\n", i);
73 flag_0 = 1;
74 pthread_mutex_unlock(&mutex_0);
75 }
76 (void)arg;
77 return NULL;
78 }
79
mutex_performance_test_loop_1(void * arg)80 void *mutex_performance_test_loop_1(void *arg)
81 {
82 RK_S32 i = 0;
83
84 for (i = 0; i < MAX_LOCK_LOOP; i++) {
85 thread_dbg("1 %5d lock\n", i);
86 pthread_mutex_lock(&mutex_1);
87
88 thread_dbg("1 %5d wait flag %d\n", i, flag_1);
89 if (flag_1) {
90 pthread_cond_wait(&cond_1, &mutex_1);
91 }
92
93 thread_dbg("1 %5d signal\n", i);
94 pthread_mutex_lock(&mutex_0);
95 flag_0 = 0;
96 pthread_cond_signal(&cond_0);
97 pthread_mutex_unlock(&mutex_0);
98
99 thread_dbg("1 %5d unlock\n", i);
100 flag_1 = 1;
101 pthread_mutex_unlock(&mutex_1);
102 }
103 (void)arg;
104 return NULL;
105 }
106
mutex_performance_test_once(void)107 void mutex_performance_test_once(void)
108 {
109 pthread_mutexattr_t attr;
110 pthread_mutex_t mutex;
111
112 pthread_mutexattr_init(&attr);
113 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
114
115 pthread_mutex_init(&mutex, &attr);
116 pthread_mutexattr_destroy(&attr);
117
118 pthread_mutex_lock(&mutex);
119 pthread_mutex_unlock(&mutex);
120
121 pthread_mutex_lock(&mutex);
122 pthread_mutex_unlock(&mutex);
123
124 pthread_mutex_lock(&mutex);
125 pthread_mutex_unlock(&mutex);
126
127 pthread_mutex_lock(&mutex);
128 pthread_mutex_unlock(&mutex);
129
130 pthread_mutex_destroy(&mutex);
131 }
132
main()133 int main()
134 {
135 int i;
136 int pdata[MAX_THREAD_NUM];
137 pthread_t threads[MAX_THREAD_NUM];
138 pthread_attr_t attr;
139 pthread_mutexattr_t mutex_attr;
140 void *dummy;
141 RK_S64 time_start, time_end;
142
143 mpp_log("vpu test start\n");
144 pthread_attr_init(&attr);
145 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
146
147 for (i = 0; i < MAX_THREAD_NUM; i++) {
148 pdata[i] = i;
149 pthread_create(&threads[i], &attr, thread_test, &pdata[i]);
150 }
151
152 sleep(2);
153
154 for (i = 0; i < MAX_THREAD_NUM; i++) {
155 pthread_join(threads[i], &dummy);
156 }
157
158 mpp_debug = MPP_DBG_TIMING;
159 time_start = mpp_time();
160
161 for (i = 0; i < MAX_LOCK_LOOP; i++)
162 mutex_performance_test_once();
163
164 time_end = mpp_time();
165 mpp_time_diff(time_start, time_end, 0, "lock unlock test");
166
167 pthread_mutexattr_init(&mutex_attr);
168 pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
169
170 pthread_mutex_init(&mutex_0, &mutex_attr);
171 pthread_mutex_init(&mutex_1, &mutex_attr);
172 pthread_cond_init(&cond_0, NULL);
173 pthread_cond_init(&cond_1, NULL);
174 pthread_mutexattr_destroy(&mutex_attr);
175
176 time_start = mpp_time();
177 pthread_create(&threads[0], &attr, mutex_performance_test_loop_0, NULL);
178 flag_0 = 0;
179 pthread_create(&threads[1], &attr, mutex_performance_test_loop_1, NULL);
180
181 pthread_join(threads[0], &dummy);
182 pthread_join(threads[1], &dummy);
183 time_end = mpp_time();
184 mpp_time_diff(time_start, time_end, 0, "lock and signal test");
185
186 pthread_cond_destroy(&cond_0);
187 pthread_cond_destroy(&cond_1);
188
189 pthread_attr_destroy(&attr);
190
191 mpp_debug = 0;
192 mpp_log("vpu test end\n");
193 return 0;
194 }
195
196