xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testlockperf.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  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 #include "apr_thread_proc.h"
18 #include "apr_thread_mutex.h"
19 #include "apr_thread_rwlock.h"
20 #include "apr_file_io.h"
21 #include "apr_errno.h"
22 #include "apr_general.h"
23 #include "apr_getopt.h"
24 #include "errno.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include "testutil.h"
28 
29 #if !APR_HAS_THREADS
main(void)30 int main(void)
31 {
32     printf("This program won't work on this platform because there is no "
33            "support for threads.\n");
34     return 0;
35 }
36 #else /* !APR_HAS_THREADS */
37 
38 #define DEFAULT_MAX_COUNTER 1000000
39 #define MAX_THREADS 6
40 
41 static int verbose = 0;
42 static long mutex_counter;
43 static long max_counter = DEFAULT_MAX_COUNTER;
44 
45 static apr_thread_mutex_t *thread_lock;
46 void * APR_THREAD_FUNC thread_mutex_func(apr_thread_t *thd, void *data);
47 apr_status_t test_thread_mutex(int num_threads); /* apr_thread_mutex_t */
48 
49 static apr_thread_rwlock_t *thread_rwlock;
50 void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data);
51 apr_status_t test_thread_rwlock(int num_threads); /* apr_thread_rwlock_t */
52 
53 int test_thread_mutex_nested(int num_threads);
54 
55 apr_pool_t *pool;
56 int i = 0, x = 0;
57 
thread_mutex_func(apr_thread_t * thd,void * data)58 void * APR_THREAD_FUNC thread_mutex_func(apr_thread_t *thd, void *data)
59 {
60     int i;
61 
62     for (i = 0; i < max_counter; i++) {
63         apr_thread_mutex_lock(thread_lock);
64         mutex_counter++;
65         apr_thread_mutex_unlock(thread_lock);
66     }
67     return NULL;
68 }
69 
thread_rwlock_func(apr_thread_t * thd,void * data)70 void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data)
71 {
72     int i;
73 
74     for (i = 0; i < max_counter; i++) {
75         apr_thread_rwlock_wrlock(thread_rwlock);
76         mutex_counter++;
77         apr_thread_rwlock_unlock(thread_rwlock);
78     }
79     return NULL;
80 }
81 
test_thread_mutex(int num_threads)82 int test_thread_mutex(int num_threads)
83 {
84     apr_thread_t *t[MAX_THREADS];
85     apr_status_t s[MAX_THREADS];
86     apr_time_t time_start, time_stop;
87     int i;
88 
89     mutex_counter = 0;
90 
91     printf("apr_thread_mutex_t Tests\n");
92     printf("%-60s", "    Initializing the apr_thread_mutex_t (UNNESTED)");
93     s[0] = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_UNNESTED, pool);
94     if (s[0] != APR_SUCCESS) {
95         printf("Failed!\n");
96         return s[0];
97     }
98     printf("OK\n");
99 
100     apr_thread_mutex_lock(thread_lock);
101     /* set_concurrency(4)? -aaron */
102     printf("    Starting %d threads    ", num_threads);
103     for (i = 0; i < num_threads; ++i) {
104         s[i] = apr_thread_create(&t[i], NULL, thread_mutex_func, NULL, pool);
105         if (s[i] != APR_SUCCESS) {
106             printf("Failed!\n");
107             return s[i];
108         }
109     }
110     printf("OK\n");
111 
112     time_start = apr_time_now();
113     apr_thread_mutex_unlock(thread_lock);
114 
115     /* printf("%-60s", "    Waiting for threads to exit"); */
116     for (i = 0; i < num_threads; ++i) {
117         apr_thread_join(&s[i], t[i]);
118     }
119     /* printf("OK\n"); */
120 
121     time_stop = apr_time_now();
122     printf("microseconds: %" APR_INT64_T_FMT " usec\n",
123            (time_stop - time_start));
124     if (mutex_counter != max_counter * num_threads)
125         printf("error: counter = %ld\n", mutex_counter);
126 
127     return APR_SUCCESS;
128 }
129 
test_thread_mutex_nested(int num_threads)130 int test_thread_mutex_nested(int num_threads)
131 {
132     apr_thread_t *t[MAX_THREADS];
133     apr_status_t s[MAX_THREADS];
134     apr_time_t time_start, time_stop;
135     int i;
136 
137     mutex_counter = 0;
138 
139     printf("apr_thread_mutex_t Tests\n");
140     printf("%-60s", "    Initializing the apr_thread_mutex_t (NESTED)");
141     s[0] = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_NESTED, pool);
142     if (s[0] != APR_SUCCESS) {
143         printf("Failed!\n");
144         return s[0];
145     }
146     printf("OK\n");
147 
148     apr_thread_mutex_lock(thread_lock);
149     /* set_concurrency(4)? -aaron */
150     printf("    Starting %d threads    ", num_threads);
151     for (i = 0; i < num_threads; ++i) {
152         s[i] = apr_thread_create(&t[i], NULL, thread_mutex_func, NULL, pool);
153         if (s[i] != APR_SUCCESS) {
154             printf("Failed!\n");
155             return s[i];
156         }
157     }
158     printf("OK\n");
159 
160     time_start = apr_time_now();
161     apr_thread_mutex_unlock(thread_lock);
162 
163     /* printf("%-60s", "    Waiting for threads to exit"); */
164     for (i = 0; i < num_threads; ++i) {
165         apr_thread_join(&s[i], t[i]);
166     }
167     /* printf("OK\n"); */
168 
169     time_stop = apr_time_now();
170     printf("microseconds: %" APR_INT64_T_FMT " usec\n",
171            (time_stop - time_start));
172     if (mutex_counter != max_counter * num_threads)
173         printf("error: counter = %ld\n", mutex_counter);
174 
175     return APR_SUCCESS;
176 }
177 
test_thread_rwlock(int num_threads)178 int test_thread_rwlock(int num_threads)
179 {
180     apr_thread_t *t[MAX_THREADS];
181     apr_status_t s[MAX_THREADS];
182     apr_time_t time_start, time_stop;
183     int i;
184 
185     mutex_counter = 0;
186 
187     printf("apr_thread_rwlock_t Tests\n");
188     printf("%-60s", "    Initializing the apr_thread_rwlock_t");
189     s[0] = apr_thread_rwlock_create(&thread_rwlock, pool);
190     if (s[0] != APR_SUCCESS) {
191         printf("Failed!\n");
192         return s[0];
193     }
194     printf("OK\n");
195 
196     apr_thread_rwlock_wrlock(thread_rwlock);
197     /* set_concurrency(4)? -aaron */
198     printf("    Starting %d threads    ", num_threads);
199     for (i = 0; i < num_threads; ++i) {
200         s[i] = apr_thread_create(&t[i], NULL, thread_rwlock_func, NULL, pool);
201         if (s[i] != APR_SUCCESS) {
202             printf("Failed!\n");
203             return s[i];
204         }
205     }
206     printf("OK\n");
207 
208     time_start = apr_time_now();
209     apr_thread_rwlock_unlock(thread_rwlock);
210 
211     /* printf("%-60s", "    Waiting for threads to exit"); */
212     for (i = 0; i < num_threads; ++i) {
213         apr_thread_join(&s[i], t[i]);
214     }
215     /* printf("OK\n"); */
216 
217     time_stop = apr_time_now();
218     printf("microseconds: %" APR_INT64_T_FMT " usec\n",
219            (time_stop - time_start));
220     if (mutex_counter != max_counter * num_threads)
221         printf("error: counter = %ld\n", mutex_counter);
222 
223     return APR_SUCCESS;
224 }
225 
main(int argc,const char * const * argv)226 int main(int argc, const char * const *argv)
227 {
228     apr_status_t rv;
229     char errmsg[200];
230     apr_getopt_t *opt;
231     char optchar;
232     const char *optarg;
233 
234     printf("APR Lock Performance Test\n==============\n\n");
235 
236     apr_initialize();
237     atexit(apr_terminate);
238 
239     if (apr_pool_create(&pool, NULL) != APR_SUCCESS)
240         exit(-1);
241 
242     if ((rv = apr_getopt_init(&opt, pool, argc, argv)) != APR_SUCCESS) {
243         fprintf(stderr, "Could not set up to parse options: [%d] %s\n",
244                 rv, apr_strerror(rv, errmsg, sizeof errmsg));
245         exit(-1);
246     }
247 
248     while ((rv = apr_getopt(opt, "c:v", &optchar, &optarg)) == APR_SUCCESS) {
249         if (optchar == 'c') {
250             max_counter = atol(optarg);
251         }
252         else if (optchar == 'v') {
253             verbose = 1;
254         }
255     }
256 
257     if (rv != APR_SUCCESS && rv != APR_EOF) {
258         fprintf(stderr, "Could not parse options: [%d] %s\n",
259                 rv, apr_strerror(rv, errmsg, sizeof errmsg));
260         exit(-1);
261     }
262 
263     for (i = 1; i <= MAX_THREADS; ++i) {
264         if ((rv = test_thread_mutex(i)) != APR_SUCCESS) {
265             fprintf(stderr,"thread_mutex test failed : [%d] %s\n",
266                     rv, apr_strerror(rv, (char*)errmsg, 200));
267             exit(-3);
268         }
269 
270         if ((rv = test_thread_mutex_nested(i)) != APR_SUCCESS) {
271             fprintf(stderr,"thread_mutex (NESTED) test failed : [%d] %s\n",
272                     rv, apr_strerror(rv, (char*)errmsg, 200));
273             exit(-4);
274         }
275 
276         if ((rv = test_thread_rwlock(i)) != APR_SUCCESS) {
277             fprintf(stderr,"thread_rwlock test failed : [%d] %s\n",
278                     rv, apr_strerror(rv, (char*)errmsg, 200));
279             exit(-6);
280         }
281     }
282 
283     return 0;
284 }
285 
286 #endif /* !APR_HAS_THREADS */
287