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 30int 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 MAX_COUNTER 1000000 39#define MAX_THREADS 6 40 41static int verbose = 0; 42static long mutex_counter; 43 44static apr_thread_mutex_t *thread_lock; 45void * APR_THREAD_FUNC thread_mutex_func(apr_thread_t *thd, void *data); 46apr_status_t test_thread_mutex(int num_threads); /* apr_thread_mutex_t */ 47 48static apr_thread_rwlock_t *thread_rwlock; 49void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data); 50apr_status_t test_thread_rwlock(int num_threads); /* apr_thread_rwlock_t */ 51 52int test_thread_mutex_nested(int num_threads); 53 54apr_pool_t *pool; 55int i = 0, x = 0; 56 57void * APR_THREAD_FUNC thread_mutex_func(apr_thread_t *thd, void *data) 58{ 59 int i; 60 61 for (i = 0; i < MAX_COUNTER; i++) { 62 apr_thread_mutex_lock(thread_lock); 63 mutex_counter++; 64 apr_thread_mutex_unlock(thread_lock); 65 } 66 return NULL; 67} 68 69void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data) 70{ 71 int i; 72 73 for (i = 0; i < MAX_COUNTER; i++) { 74 apr_thread_rwlock_wrlock(thread_rwlock); 75 mutex_counter++; 76 apr_thread_rwlock_unlock(thread_rwlock); 77 } 78 return NULL; 79} 80 81int test_thread_mutex(int num_threads) 82{ 83 apr_thread_t *t[MAX_THREADS]; 84 apr_status_t s[MAX_THREADS]; 85 apr_time_t time_start, time_stop; 86 int i; 87 88 mutex_counter = 0; 89 90 printf("apr_thread_mutex_t Tests\n"); 91 printf("%-60s", " Initializing the apr_thread_mutex_t (UNNESTED)"); 92 s[0] = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_UNNESTED, pool); 93 if (s[0] != APR_SUCCESS) { 94 printf("Failed!\n"); 95 return s[0]; 96 } 97 printf("OK\n"); 98 99 apr_thread_mutex_lock(thread_lock); 100 /* set_concurrency(4)? -aaron */ 101 printf(" Starting %d threads ", num_threads); 102 for (i = 0; i < num_threads; ++i) { 103 s[i] = apr_thread_create(&t[i], NULL, thread_mutex_func, NULL, pool); 104 if (s[i] != APR_SUCCESS) { 105 printf("Failed!\n"); 106 return s[i]; 107 } 108 } 109 printf("OK\n"); 110 111 time_start = apr_time_now(); 112 apr_thread_mutex_unlock(thread_lock); 113 114 /* printf("%-60s", " Waiting for threads to exit"); */ 115 for (i = 0; i < num_threads; ++i) { 116 apr_thread_join(&s[i], t[i]); 117 } 118 /* printf("OK\n"); */ 119 120 time_stop = apr_time_now(); 121 printf("microseconds: %" APR_INT64_T_FMT " usec\n", 122 (time_stop - time_start)); 123 if (mutex_counter != MAX_COUNTER * num_threads) 124 printf("error: counter = %ld\n", mutex_counter); 125 126 return APR_SUCCESS; 127} 128 129int test_thread_mutex_nested(int num_threads) 130{ 131 apr_thread_t *t[MAX_THREADS]; 132 apr_status_t s[MAX_THREADS]; 133 apr_time_t time_start, time_stop; 134 int i; 135 136 mutex_counter = 0; 137 138 printf("apr_thread_mutex_t Tests\n"); 139 printf("%-60s", " Initializing the apr_thread_mutex_t (NESTED)"); 140 s[0] = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_NESTED, pool); 141 if (s[0] != APR_SUCCESS) { 142 printf("Failed!\n"); 143 return s[0]; 144 } 145 printf("OK\n"); 146 147 apr_thread_mutex_lock(thread_lock); 148 /* set_concurrency(4)? -aaron */ 149 printf(" Starting %d threads ", num_threads); 150 for (i = 0; i < num_threads; ++i) { 151 s[i] = apr_thread_create(&t[i], NULL, thread_mutex_func, NULL, pool); 152 if (s[i] != APR_SUCCESS) { 153 printf("Failed!\n"); 154 return s[i]; 155 } 156 } 157 printf("OK\n"); 158 159 time_start = apr_time_now(); 160 apr_thread_mutex_unlock(thread_lock); 161 162 /* printf("%-60s", " Waiting for threads to exit"); */ 163 for (i = 0; i < num_threads; ++i) { 164 apr_thread_join(&s[i], t[i]); 165 } 166 /* printf("OK\n"); */ 167 168 time_stop = apr_time_now(); 169 printf("microseconds: %" APR_INT64_T_FMT " usec\n", 170 (time_stop - time_start)); 171 if (mutex_counter != MAX_COUNTER * num_threads) 172 printf("error: counter = %ld\n", mutex_counter); 173 174 return APR_SUCCESS; 175} 176 177int test_thread_rwlock(int num_threads) 178{ 179 apr_thread_t *t[MAX_THREADS]; 180 apr_status_t s[MAX_THREADS]; 181 apr_time_t time_start, time_stop; 182 int i; 183 184 mutex_counter = 0; 185 186 printf("apr_thread_rwlock_t Tests\n"); 187 printf("%-60s", " Initializing the apr_thread_rwlock_t"); 188 s[0] = apr_thread_rwlock_create(&thread_rwlock, pool); 189 if (s[0] != APR_SUCCESS) { 190 printf("Failed!\n"); 191 return s[0]; 192 } 193 printf("OK\n"); 194 195 apr_thread_rwlock_wrlock(thread_rwlock); 196 /* set_concurrency(4)? -aaron */ 197 printf(" Starting %d threads ", num_threads); 198 for (i = 0; i < num_threads; ++i) { 199 s[i] = apr_thread_create(&t[i], NULL, thread_rwlock_func, NULL, pool); 200 if (s[i] != APR_SUCCESS) { 201 printf("Failed!\n"); 202 return s[i]; 203 } 204 } 205 printf("OK\n"); 206 207 time_start = apr_time_now(); 208 apr_thread_rwlock_unlock(thread_rwlock); 209 210 /* printf("%-60s", " Waiting for threads to exit"); */ 211 for (i = 0; i < num_threads; ++i) { 212 apr_thread_join(&s[i], t[i]); 213 } 214 /* printf("OK\n"); */ 215 216 time_stop = apr_time_now(); 217 printf("microseconds: %" APR_INT64_T_FMT " usec\n", 218 (time_stop - time_start)); 219 if (mutex_counter != MAX_COUNTER * num_threads) 220 printf("error: counter = %ld\n", mutex_counter); 221 222 return APR_SUCCESS; 223} 224 225int main(int argc, const char * const *argv) 226{ 227 apr_status_t rv; 228 char errmsg[200]; 229 apr_getopt_t *opt; 230 char optchar; 231 const char *optarg; 232 233 printf("APR Lock Performance Test\n==============\n\n"); 234 235 apr_initialize(); 236 atexit(apr_terminate); 237 238 if (apr_pool_create(&pool, NULL) != APR_SUCCESS) 239 exit(-1); 240 241 if ((rv = apr_getopt_init(&opt, pool, argc, argv)) != APR_SUCCESS) { 242 fprintf(stderr, "Could not set up to parse options: [%d] %s\n", 243 rv, apr_strerror(rv, errmsg, sizeof errmsg)); 244 exit(-1); 245 } 246 247 while ((rv = apr_getopt(opt, "v", &optchar, &optarg)) == APR_SUCCESS) { 248 if (optchar == 'v') { 249 verbose = 1; 250 } 251 } 252 253 if (rv != APR_SUCCESS && rv != APR_EOF) { 254 fprintf(stderr, "Could not parse options: [%d] %s\n", 255 rv, apr_strerror(rv, errmsg, sizeof errmsg)); 256 exit(-1); 257 } 258 259 for (i = 1; i <= MAX_THREADS; ++i) { 260 if ((rv = test_thread_mutex(i)) != APR_SUCCESS) { 261 fprintf(stderr,"thread_mutex test failed : [%d] %s\n", 262 rv, apr_strerror(rv, (char*)errmsg, 200)); 263 exit(-3); 264 } 265 266 if ((rv = test_thread_mutex_nested(i)) != APR_SUCCESS) { 267 fprintf(stderr,"thread_mutex (NESTED) test failed : [%d] %s\n", 268 rv, apr_strerror(rv, (char*)errmsg, 200)); 269 exit(-4); 270 } 271 272 if ((rv = test_thread_rwlock(i)) != APR_SUCCESS) { 273 fprintf(stderr,"thread_rwlock test failed : [%d] %s\n", 274 rv, apr_strerror(rv, (char*)errmsg, 200)); 275 exit(-6); 276 } 277 } 278 279 return 0; 280} 281 282#endif /* !APR_HAS_THREADS */ 283