xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testthread.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_errno.h"
19 #include "apr_general.h"
20 #include "apr_time.h"
21 #include "testutil.h"
22 
23 #if APR_HAS_THREADS
24 
25 static apr_thread_mutex_t *thread_lock;
26 static apr_thread_once_t *control = NULL;
27 static int x = 0;
28 static int value = 0;
29 
30 static apr_thread_t *t1;
31 static apr_thread_t *t2;
32 static apr_thread_t *t3;
33 static apr_thread_t *t4;
34 
35 /* just some made up number to check on later */
36 static apr_status_t exit_ret_val = 123;
37 
init_func(void)38 static void init_func(void)
39 {
40     value++;
41 }
42 
thread_func1(apr_thread_t * thd,void * data)43 static void * APR_THREAD_FUNC thread_func1(apr_thread_t *thd, void *data)
44 {
45     int i;
46 
47     apr_thread_once(control, init_func);
48 
49     for (i = 0; i < 10000; i++) {
50         apr_thread_mutex_lock(thread_lock);
51         x++;
52         apr_thread_mutex_unlock(thread_lock);
53     }
54     apr_thread_exit(thd, exit_ret_val);
55     return NULL;
56 }
57 
thread_init(abts_case * tc,void * data)58 static void thread_init(abts_case *tc, void *data)
59 {
60     apr_status_t rv;
61 
62     rv = apr_thread_once_init(&control, p);
63     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
64 
65     rv = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_DEFAULT, p);
66     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
67 }
68 
create_threads(abts_case * tc,void * data)69 static void create_threads(abts_case *tc, void *data)
70 {
71     apr_status_t rv;
72 
73     rv = apr_thread_create(&t1, NULL, thread_func1, NULL, p);
74     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
75     rv = apr_thread_create(&t2, NULL, thread_func1, NULL, p);
76     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
77     rv = apr_thread_create(&t3, NULL, thread_func1, NULL, p);
78     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
79     rv = apr_thread_create(&t4, NULL, thread_func1, NULL, p);
80     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
81 }
82 
join_threads(abts_case * tc,void * data)83 static void join_threads(abts_case *tc, void *data)
84 {
85     apr_status_t s;
86 
87     apr_thread_join(&s, t1);
88     ABTS_INT_EQUAL(tc, exit_ret_val, s);
89     apr_thread_join(&s, t2);
90     ABTS_INT_EQUAL(tc, exit_ret_val, s);
91     apr_thread_join(&s, t3);
92     ABTS_INT_EQUAL(tc, exit_ret_val, s);
93     apr_thread_join(&s, t4);
94     ABTS_INT_EQUAL(tc, exit_ret_val, s);
95 }
96 
check_locks(abts_case * tc,void * data)97 static void check_locks(abts_case *tc, void *data)
98 {
99     ABTS_INT_EQUAL(tc, 40000, x);
100 }
101 
check_thread_once(abts_case * tc,void * data)102 static void check_thread_once(abts_case *tc, void *data)
103 {
104     ABTS_INT_EQUAL(tc, 1, value);
105 }
106 
107 #else
108 
threads_not_impl(abts_case * tc,void * data)109 static void threads_not_impl(abts_case *tc, void *data)
110 {
111     ABTS_NOT_IMPL(tc, "Threads not implemented on this platform");
112 }
113 
114 #endif
115 
testthread(abts_suite * suite)116 abts_suite *testthread(abts_suite *suite)
117 {
118     suite = ADD_SUITE(suite)
119 
120 #if !APR_HAS_THREADS
121     abts_run_test(suite, threads_not_impl, NULL);
122 #else
123     abts_run_test(suite, thread_init, NULL);
124     abts_run_test(suite, create_threads, NULL);
125     abts_run_test(suite, join_threads, NULL);
126     abts_run_test(suite, check_locks, NULL);
127     abts_run_test(suite, check_thread_once, NULL);
128 #endif
129 
130     return suite;
131 }
132 
133