xref: /rockchip-linux_mpp/osal/test/mpp_runtime_test.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_rt_test"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <stdio.h>
9*437bfbebSnyanmisaka #include <pthread.h>
10*437bfbebSnyanmisaka #include <time.h>
11*437bfbebSnyanmisaka #include <errno.h>
12*437bfbebSnyanmisaka 
13*437bfbebSnyanmisaka #ifdef __GLIBC__
14*437bfbebSnyanmisaka #include <gnu/libc-version.h>
15*437bfbebSnyanmisaka #endif
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #ifdef __ANDROID__
18*437bfbebSnyanmisaka #include <android/api-level.h>
19*437bfbebSnyanmisaka #include <sys/system_properties.h>
20*437bfbebSnyanmisaka #endif
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #if defined(__USE_XOPEN2K) || (defined(__ANDROID__) && __ANDROID_API__ >= 21)
23*437bfbebSnyanmisaka #define COND_USE_CLOCK_MONOTONIC
24*437bfbebSnyanmisaka #endif
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #include "mpp_log.h"
27*437bfbebSnyanmisaka #include "mpp_runtime.h"
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka clockid_t clock_id = CLOCK_REALTIME;
30*437bfbebSnyanmisaka 
allocator_check()31*437bfbebSnyanmisaka rk_s32 allocator_check()
32*437bfbebSnyanmisaka {
33*437bfbebSnyanmisaka     if (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION))
34*437bfbebSnyanmisaka         mpp_logi("mpp found ion buffer is valid\n");
35*437bfbebSnyanmisaka     else
36*437bfbebSnyanmisaka         mpp_logi("mpp found ion buffer is invalid\n");
37*437bfbebSnyanmisaka 
38*437bfbebSnyanmisaka     if (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM))
39*437bfbebSnyanmisaka         mpp_logi("mpp found drm buffer is valid\n");
40*437bfbebSnyanmisaka     else
41*437bfbebSnyanmisaka         mpp_logi("mpp found drm buffer is invalid\n");
42*437bfbebSnyanmisaka 
43*437bfbebSnyanmisaka     return MPP_OK;
44*437bfbebSnyanmisaka }
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka #if defined(__ANDROID__)
47*437bfbebSnyanmisaka // Android OS
os_check()48*437bfbebSnyanmisaka int os_check()
49*437bfbebSnyanmisaka {
50*437bfbebSnyanmisaka     char version_str[PROP_VALUE_MAX];
51*437bfbebSnyanmisaka     char sdk_str[PROP_VALUE_MAX];
52*437bfbebSnyanmisaka     rk_u32 sdk_api_level = 0;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     mpp_logi("Compiled for Android System.\n");
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka     __system_property_get("ro.build.version.sdk", sdk_str);
57*437bfbebSnyanmisaka     __system_property_get("ro.build.version.release", version_str);
58*437bfbebSnyanmisaka     sdk_api_level = atoi(sdk_str);
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     mpp_logi("Running on Android %s, api level %d, program compiled with api level %d.\n",
61*437bfbebSnyanmisaka              version_str, sdk_api_level, __ANDROID_API__);
62*437bfbebSnyanmisaka 
63*437bfbebSnyanmisaka     if (sdk_api_level < __ANDROID_API__)
64*437bfbebSnyanmisaka         mpp_logi("Warning!!! Target is compiled for a higher api level than current system.\n");
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     // check libc
67*437bfbebSnyanmisaka #if defined(__BIONIC__)
68*437bfbebSnyanmisaka     mpp_logi("Using bionic libc.\n");
69*437bfbebSnyanmisaka #else
70*437bfbebSnyanmisaka     mpp_logi("Unknown libc.\n");
71*437bfbebSnyanmisaka #endif // __BIONIC__
72*437bfbebSnyanmisaka 
73*437bfbebSnyanmisaka // POSIX C compatibility test
74*437bfbebSnyanmisaka     if (__ANDROID_API__ >= 21) {
75*437bfbebSnyanmisaka         clock_id = CLOCK_MONOTONIC;
76*437bfbebSnyanmisaka         mpp_logi("pthread_condattr_setclock is defined.\n");
77*437bfbebSnyanmisaka 
78*437bfbebSnyanmisaka         if (__ANDROID_API__ >= 30)
79*437bfbebSnyanmisaka             mpp_logi("pthread_cond_clockwait is defined.\n");
80*437bfbebSnyanmisaka         else
81*437bfbebSnyanmisaka             mpp_logi("pthread_cond_clockwait is not defined.\n");
82*437bfbebSnyanmisaka     } else {
83*437bfbebSnyanmisaka         mpp_logi("pthread_condattr_setclock is not defined.\n");
84*437bfbebSnyanmisaka     }
85*437bfbebSnyanmisaka 
86*437bfbebSnyanmisaka     return 0;
87*437bfbebSnyanmisaka }
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka #else
90*437bfbebSnyanmisaka 
91*437bfbebSnyanmisaka // Linux OS
os_check()92*437bfbebSnyanmisaka int os_check()
93*437bfbebSnyanmisaka {
94*437bfbebSnyanmisaka #if defined(linux) && !defined(__ANDROID__)
95*437bfbebSnyanmisaka     mpp_logi("Compiled for Linux.\n");
96*437bfbebSnyanmisaka #else
97*437bfbebSnyanmisaka     mpp_logi("Compiled for Unknown OS.\n");
98*437bfbebSnyanmisaka #endif // OS check
99*437bfbebSnyanmisaka 
100*437bfbebSnyanmisaka     // check libc
101*437bfbebSnyanmisaka #if defined(__GLIBC__)
102*437bfbebSnyanmisaka     mpp_logi("Compiled with glibc %d-%d, running with glibc %s.\n", __GLIBC__, __GLIBC_MINOR__, gnu_get_libc_version());
103*437bfbebSnyanmisaka #elif defined(__UCLIBC__)
104*437bfbebSnyanmisaka     mpp_logi("Using uClibc.\n");
105*437bfbebSnyanmisaka #if defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) && defined(__UCLIBC_SUBLEVEL__)
106*437bfbebSnyanmisaka     mpp_logi("Compiled with uClibc version: %d.%d.%d.\n",
107*437bfbebSnyanmisaka              __UCLIBC_MAJOR__, __UCLIBC_MINOR__, __UCLIBC_SUBLEVEL__);
108*437bfbebSnyanmisaka #else
109*437bfbebSnyanmisaka     mpp_logi("uClibc version macros not available.\n");
110*437bfbebSnyanmisaka #endif
111*437bfbebSnyanmisaka     mpp_logi("pthread_cond_clockwait is not defined.\n");
112*437bfbebSnyanmisaka #elif defined(__MUSL__)
113*437bfbebSnyanmisaka     mpp_logi("Using musl libc.\n");
114*437bfbebSnyanmisaka #else
115*437bfbebSnyanmisaka     mpp_logi("Unknown libc.\n");
116*437bfbebSnyanmisaka #endif // LIBC check
117*437bfbebSnyanmisaka 
118*437bfbebSnyanmisaka // POSIX C compatibility test
119*437bfbebSnyanmisaka #if defined(__USE_XOPEN2K)
120*437bfbebSnyanmisaka     clock_id = CLOCK_MONOTONIC;
121*437bfbebSnyanmisaka     mpp_logi("XPG6 is supported.\n");
122*437bfbebSnyanmisaka     mpp_logi("pthread_condattr_setclock is defined.\n");
123*437bfbebSnyanmisaka #else
124*437bfbebSnyanmisaka     mpp_logi("XPG6 is not supported.\n");
125*437bfbebSnyanmisaka     mpp_logi("pthread_condattr_setclock is not defined.\n");
126*437bfbebSnyanmisaka #endif // __USE_XOPEN2K
127*437bfbebSnyanmisaka 
128*437bfbebSnyanmisaka     return 0;
129*437bfbebSnyanmisaka }
130*437bfbebSnyanmisaka #endif // USE_XOPEN2K
131*437bfbebSnyanmisaka 
132*437bfbebSnyanmisaka #ifdef COND_USE_CLOCK_MONOTONIC
133*437bfbebSnyanmisaka pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
134*437bfbebSnyanmisaka pthread_cond_t cond;
135*437bfbebSnyanmisaka rk_u32 condition = 0;
136*437bfbebSnyanmisaka 
wait_thread()137*437bfbebSnyanmisaka void *wait_thread()
138*437bfbebSnyanmisaka {
139*437bfbebSnyanmisaka     int ret;
140*437bfbebSnyanmisaka     struct timespec ts, ts_s, ts_e;
141*437bfbebSnyanmisaka     char time_str[64];
142*437bfbebSnyanmisaka     struct tm *tm_info;
143*437bfbebSnyanmisaka 
144*437bfbebSnyanmisaka     pthread_mutex_lock(&mutex);
145*437bfbebSnyanmisaka 
146*437bfbebSnyanmisaka     clock_gettime(CLOCK_MONOTONIC, &ts);
147*437bfbebSnyanmisaka     clock_gettime(CLOCK_REALTIME, &ts_s);
148*437bfbebSnyanmisaka 
149*437bfbebSnyanmisaka     ts.tv_sec += 1; // timeout after 1 sec
150*437bfbebSnyanmisaka     tm_info = localtime(&ts_s.tv_sec);
151*437bfbebSnyanmisaka     strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     mpp_logi("Current time is: %s.%08ld.\n", time_str, ts_s.tv_nsec);
154*437bfbebSnyanmisaka     mpp_logi("Thread is waiting at monotonic time: %ld sec %ld nsec, will be timeout after 1 sec.\n",
155*437bfbebSnyanmisaka              ts.tv_sec, ts.tv_nsec);
156*437bfbebSnyanmisaka 
157*437bfbebSnyanmisaka     while (!condition) {
158*437bfbebSnyanmisaka         ret = pthread_cond_timedwait(&cond, &mutex, &ts);
159*437bfbebSnyanmisaka 
160*437bfbebSnyanmisaka         if (ret == ETIMEDOUT) {
161*437bfbebSnyanmisaka             clock_gettime(CLOCK_REALTIME, &ts_e);
162*437bfbebSnyanmisaka             tm_info = localtime(&ts_e.tv_sec);
163*437bfbebSnyanmisaka             strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka             mpp_logi("Timeout expired at %s.%09ld.\n", time_str, ts_e.tv_nsec);
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka             if ((ts_e.tv_sec - ts_s.tv_sec) != 1)
168*437bfbebSnyanmisaka                 mpp_loge("Error! Timeout expired too soon or too late.\n");
169*437bfbebSnyanmisaka             else
170*437bfbebSnyanmisaka                 mpp_logi("pthrad_cond_timedwait is reliable when using CLOCK_MONOTONIC\n");
171*437bfbebSnyanmisaka 
172*437bfbebSnyanmisaka             pthread_mutex_unlock(&mutex);
173*437bfbebSnyanmisaka             return NULL;
174*437bfbebSnyanmisaka         }
175*437bfbebSnyanmisaka     }
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka     mpp_logi("Thread is waked up.");
178*437bfbebSnyanmisaka     pthread_mutex_unlock(&mutex);
179*437bfbebSnyanmisaka     return NULL;
180*437bfbebSnyanmisaka }
181*437bfbebSnyanmisaka 
check_pthread_clock()182*437bfbebSnyanmisaka int check_pthread_clock()
183*437bfbebSnyanmisaka {
184*437bfbebSnyanmisaka     pthread_condattr_t cond_attr;
185*437bfbebSnyanmisaka     pthread_t thread;
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka     pthread_condattr_init(&cond_attr);
188*437bfbebSnyanmisaka     if (pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC)) {
189*437bfbebSnyanmisaka         mpp_loge("pthread is not supported with CLOCK_MONOTONIC\n");
190*437bfbebSnyanmisaka         pthread_condattr_destroy(&cond_attr);
191*437bfbebSnyanmisaka         pthread_mutex_destroy(&mutex);
192*437bfbebSnyanmisaka         return -1;
193*437bfbebSnyanmisaka     }
194*437bfbebSnyanmisaka     pthread_cond_init(&cond, &cond_attr);
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka     pthread_create(&thread, NULL, wait_thread, NULL);
197*437bfbebSnyanmisaka     pthread_join(thread, NULL);
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka     pthread_mutex_destroy(&mutex);
200*437bfbebSnyanmisaka     pthread_cond_destroy(&cond);
201*437bfbebSnyanmisaka     pthread_condattr_destroy(&cond_attr);
202*437bfbebSnyanmisaka 
203*437bfbebSnyanmisaka     return 0;
204*437bfbebSnyanmisaka }
205*437bfbebSnyanmisaka #endif // COND_USE_CLOCK_MONOTONIC
206*437bfbebSnyanmisaka 
main()207*437bfbebSnyanmisaka int main()
208*437bfbebSnyanmisaka {
209*437bfbebSnyanmisaka     allocator_check();
210*437bfbebSnyanmisaka     // system compatibility test
211*437bfbebSnyanmisaka #if defined(__LP64__)
212*437bfbebSnyanmisaka     mpp_logi("This is 64-bit program.\n");
213*437bfbebSnyanmisaka #else
214*437bfbebSnyanmisaka     mpp_logi("This is 32-bit program.\n");
215*437bfbebSnyanmisaka #endif // __LP64__
216*437bfbebSnyanmisaka 
217*437bfbebSnyanmisaka     os_check();
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka #ifdef COND_USE_CLOCK_MONOTONIC
220*437bfbebSnyanmisaka     if (check_pthread_clock())
221*437bfbebSnyanmisaka         mpp_loge("Warning! pthread_cond_timedwait will not be reliable!\n");
222*437bfbebSnyanmisaka #else
223*437bfbebSnyanmisaka     mpp_logi("pthread clock compatibility checking is skipped.\n");
224*437bfbebSnyanmisaka     mpp_loge("Warning! pthread_cond_timedwait will not be reliable!\n");
225*437bfbebSnyanmisaka #endif // COND_USE_CLOCK_MONOTONIC
226*437bfbebSnyanmisaka 
227*437bfbebSnyanmisaka     return 0;
228*437bfbebSnyanmisaka }
229