| /* Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "apr_thread_proc.h" |
| #include "apr_thread_mutex.h" |
| #include "apr_thread_rwlock.h" |
| #include "apr_file_io.h" |
| #include "apr_errno.h" |
| #include "apr_general.h" |
| #include "apr_getopt.h" |
| #include "errno.h" |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include "testutil.h" |
| |
| #if !APR_HAS_THREADS |
| int main(void) |
| { |
| printf("This program won't work on this platform because there is no " |
| "support for threads.\n"); |
| return 0; |
| } |
| #else /* !APR_HAS_THREADS */ |
| |
| #define MAX_COUNTER 1000000 |
| #define MAX_THREADS 6 |
| |
| static int verbose = 0; |
| static long mutex_counter; |
| |
| static apr_thread_mutex_t *thread_lock; |
| void * APR_THREAD_FUNC thread_mutex_func(apr_thread_t *thd, void *data); |
| apr_status_t test_thread_mutex(int num_threads); /* apr_thread_mutex_t */ |
| |
| static apr_thread_rwlock_t *thread_rwlock; |
| void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data); |
| apr_status_t test_thread_rwlock(int num_threads); /* apr_thread_rwlock_t */ |
| |
| int test_thread_mutex_nested(int num_threads); |
| |
| apr_pool_t *pool; |
| int i = 0, x = 0; |
| |
| void * APR_THREAD_FUNC thread_mutex_func(apr_thread_t *thd, void *data) |
| { |
| int i; |
| |
| for (i = 0; i < MAX_COUNTER; i++) { |
| apr_thread_mutex_lock(thread_lock); |
| mutex_counter++; |
| apr_thread_mutex_unlock(thread_lock); |
| } |
| return NULL; |
| } |
| |
| void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data) |
| { |
| int i; |
| |
| for (i = 0; i < MAX_COUNTER; i++) { |
| apr_thread_rwlock_wrlock(thread_rwlock); |
| mutex_counter++; |
| apr_thread_rwlock_unlock(thread_rwlock); |
| } |
| return NULL; |
| } |
| |
| int test_thread_mutex(int num_threads) |
| { |
| apr_thread_t *t[MAX_THREADS]; |
| apr_status_t s[MAX_THREADS]; |
| apr_time_t time_start, time_stop; |
| int i; |
| |
| mutex_counter = 0; |
| |
| printf("apr_thread_mutex_t Tests\n"); |
| printf("%-60s", " Initializing the apr_thread_mutex_t (UNNESTED)"); |
| s[0] = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_UNNESTED, pool); |
| if (s[0] != APR_SUCCESS) { |
| printf("Failed!\n"); |
| return s[0]; |
| } |
| printf("OK\n"); |
| |
| apr_thread_mutex_lock(thread_lock); |
| /* set_concurrency(4)? -aaron */ |
| printf(" Starting %d threads ", num_threads); |
| for (i = 0; i < num_threads; ++i) { |
| s[i] = apr_thread_create(&t[i], NULL, thread_mutex_func, NULL, pool); |
| if (s[i] != APR_SUCCESS) { |
| printf("Failed!\n"); |
| return s[i]; |
| } |
| } |
| printf("OK\n"); |
| |
| time_start = apr_time_now(); |
| apr_thread_mutex_unlock(thread_lock); |
| |
| /* printf("%-60s", " Waiting for threads to exit"); */ |
| for (i = 0; i < num_threads; ++i) { |
| apr_thread_join(&s[i], t[i]); |
| } |
| /* printf("OK\n"); */ |
| |
| time_stop = apr_time_now(); |
| printf("microseconds: %" APR_INT64_T_FMT " usec\n", |
| (time_stop - time_start)); |
| if (mutex_counter != MAX_COUNTER * num_threads) |
| printf("error: counter = %ld\n", mutex_counter); |
| |
| return APR_SUCCESS; |
| } |
| |
| int test_thread_mutex_nested(int num_threads) |
| { |
| apr_thread_t *t[MAX_THREADS]; |
| apr_status_t s[MAX_THREADS]; |
| apr_time_t time_start, time_stop; |
| int i; |
| |
| mutex_counter = 0; |
| |
| printf("apr_thread_mutex_t Tests\n"); |
| printf("%-60s", " Initializing the apr_thread_mutex_t (NESTED)"); |
| s[0] = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_NESTED, pool); |
| if (s[0] != APR_SUCCESS) { |
| printf("Failed!\n"); |
| return s[0]; |
| } |
| printf("OK\n"); |
| |
| apr_thread_mutex_lock(thread_lock); |
| /* set_concurrency(4)? -aaron */ |
| printf(" Starting %d threads ", num_threads); |
| for (i = 0; i < num_threads; ++i) { |
| s[i] = apr_thread_create(&t[i], NULL, thread_mutex_func, NULL, pool); |
| if (s[i] != APR_SUCCESS) { |
| printf("Failed!\n"); |
| return s[i]; |
| } |
| } |
| printf("OK\n"); |
| |
| time_start = apr_time_now(); |
| apr_thread_mutex_unlock(thread_lock); |
| |
| /* printf("%-60s", " Waiting for threads to exit"); */ |
| for (i = 0; i < num_threads; ++i) { |
| apr_thread_join(&s[i], t[i]); |
| } |
| /* printf("OK\n"); */ |
| |
| time_stop = apr_time_now(); |
| printf("microseconds: %" APR_INT64_T_FMT " usec\n", |
| (time_stop - time_start)); |
| if (mutex_counter != MAX_COUNTER * num_threads) |
| printf("error: counter = %ld\n", mutex_counter); |
| |
| return APR_SUCCESS; |
| } |
| |
| int test_thread_rwlock(int num_threads) |
| { |
| apr_thread_t *t[MAX_THREADS]; |
| apr_status_t s[MAX_THREADS]; |
| apr_time_t time_start, time_stop; |
| int i; |
| |
| mutex_counter = 0; |
| |
| printf("apr_thread_rwlock_t Tests\n"); |
| printf("%-60s", " Initializing the apr_thread_rwlock_t"); |
| s[0] = apr_thread_rwlock_create(&thread_rwlock, pool); |
| if (s[0] != APR_SUCCESS) { |
| printf("Failed!\n"); |
| return s[0]; |
| } |
| printf("OK\n"); |
| |
| apr_thread_rwlock_wrlock(thread_rwlock); |
| /* set_concurrency(4)? -aaron */ |
| printf(" Starting %d threads ", num_threads); |
| for (i = 0; i < num_threads; ++i) { |
| s[i] = apr_thread_create(&t[i], NULL, thread_rwlock_func, NULL, pool); |
| if (s[i] != APR_SUCCESS) { |
| printf("Failed!\n"); |
| return s[i]; |
| } |
| } |
| printf("OK\n"); |
| |
| time_start = apr_time_now(); |
| apr_thread_rwlock_unlock(thread_rwlock); |
| |
| /* printf("%-60s", " Waiting for threads to exit"); */ |
| for (i = 0; i < num_threads; ++i) { |
| apr_thread_join(&s[i], t[i]); |
| } |
| /* printf("OK\n"); */ |
| |
| time_stop = apr_time_now(); |
| printf("microseconds: %" APR_INT64_T_FMT " usec\n", |
| (time_stop - time_start)); |
| if (mutex_counter != MAX_COUNTER * num_threads) |
| printf("error: counter = %ld\n", mutex_counter); |
| |
| return APR_SUCCESS; |
| } |
| |
| int main(int argc, const char * const *argv) |
| { |
| apr_status_t rv; |
| char errmsg[200]; |
| const char *lockname = "multi.lock"; |
| apr_getopt_t *opt; |
| char optchar; |
| const char *optarg; |
| |
| printf("APR Lock Performance Test\n==============\n\n"); |
| |
| apr_initialize(); |
| atexit(apr_terminate); |
| |
| if (apr_pool_create(&pool, NULL) != APR_SUCCESS) |
| exit(-1); |
| |
| if ((rv = apr_getopt_init(&opt, pool, argc, argv)) != APR_SUCCESS) { |
| fprintf(stderr, "Could not set up to parse options: [%d] %s\n", |
| rv, apr_strerror(rv, errmsg, sizeof errmsg)); |
| exit(-1); |
| } |
| |
| while ((rv = apr_getopt(opt, "vf:", &optchar, &optarg)) == APR_SUCCESS) { |
| if (optchar == 'v') { |
| verbose = 1; |
| } |
| if (optchar == 'f') { |
| lockname = optarg; |
| } |
| } |
| |
| if (rv != APR_SUCCESS && rv != APR_EOF) { |
| fprintf(stderr, "Could not parse options: [%d] %s\n", |
| rv, apr_strerror(rv, errmsg, sizeof errmsg)); |
| exit(-1); |
| } |
| |
| for (i = 1; i <= MAX_THREADS; ++i) { |
| if ((rv = test_thread_mutex(i)) != APR_SUCCESS) { |
| fprintf(stderr,"thread_mutex test failed : [%d] %s\n", |
| rv, apr_strerror(rv, (char*)errmsg, 200)); |
| exit(-3); |
| } |
| |
| if ((rv = test_thread_mutex_nested(i)) != APR_SUCCESS) { |
| fprintf(stderr,"thread_mutex (NESTED) test failed : [%d] %s\n", |
| rv, apr_strerror(rv, (char*)errmsg, 200)); |
| exit(-4); |
| } |
| |
| if ((rv = test_thread_rwlock(i)) != APR_SUCCESS) { |
| fprintf(stderr,"thread_rwlock test failed : [%d] %s\n", |
| rv, apr_strerror(rv, (char*)errmsg, 200)); |
| exit(-6); |
| } |
| } |
| |
| return 0; |
| } |
| |
| #endif /* !APR_HAS_THREADS */ |