diff options
Diffstat (limited to 'subversion/tests/libsvn_subr/named_atomic-test.c')
-rw-r--r-- | subversion/tests/libsvn_subr/named_atomic-test.c | 761 |
1 files changed, 0 insertions, 761 deletions
diff --git a/subversion/tests/libsvn_subr/named_atomic-test.c b/subversion/tests/libsvn_subr/named_atomic-test.c deleted file mode 100644 index 05604d2..0000000 --- a/subversion/tests/libsvn_subr/named_atomic-test.c +++ /dev/null @@ -1,761 +0,0 @@ -/* - * named_atomic-test.c: a collection of svn_named_atomic__t tests - * - * ==================================================================== - * 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. - * ==================================================================== - */ - -/* ==================================================================== - To add tests, look toward the bottom of this file. -*/ - - -#include <stdio.h> -#include <apr_file_io.h> - -#include "svn_io.h" - -/* shared test implementation */ -#include "named_atomic-test-common.h" - -/* Name of the worker process executable */ -#define TEST_PROC "named_atomic-proc-test" - -/* number of hardware threads (logical cores) that we may use. - * Will be set to at least 2 - even on unicore machines. */ -static int hw_thread_count = 0; - -/* number of iterations that we should perform on concurrency tests - * (will be calibrated to about 1s runtime)*/ -static int suggested_iterations = 0; - -/* If possible, translate PROC to a global path and set DIRECTORY to - * the current directory. - */ -static svn_error_t * -adjust_proc_path(const char **proc, const char **directory, apr_pool_t *pool) -{ -#ifdef WIN32 - /* Under Windows, the test will not be in the current directory - * and neither will be PROC. Therefore, determine its full path */ - char path [MAX_PATH] = { 0 }; - GetModuleFileNameA(NULL, path, sizeof(path)); - *(strrchr(path, '\\') + 1) = 0; - *proc = apr_pstrcat(pool, path, *proc, ".exe", NULL); - - /* And we need to set the working dir to our working dir to make - * our sub-processes find all DLLs. */ - GetCurrentDirectoryA(sizeof(path), path); - *directory = apr_pstrdup(pool, path); -#endif - - return SVN_NO_ERROR; -} - -/* Returns true if PROC can be found and executed. - */ -static svn_boolean_t -proc_found(const char *proc, apr_pool_t *pool) -{ - static svn_tristate_t result = svn_tristate_unknown; - - if (result == svn_tristate_unknown) - { - svn_error_t *error = SVN_NO_ERROR; - const char * directory = NULL; - - /* all processes and their I/O data */ - apr_proc_t process; - const char * args[2]; - - args[0] = proc; - args[1] = NULL; - svn_error_clear(adjust_proc_path(&args[0], &directory, pool)); - - /* try to start the process */ - error = svn_io_start_cmd3(&process, - directory, /* working directory */ - args[0], - args, - NULL, /* environment */ - FALSE, /* no handle inheritance */ - FALSE, /* no STDIN pipe */ - NULL, - FALSE, /* no STDOUT pipe */ - NULL, - FALSE, /* no STDERR pipe */ - NULL, - pool); - if (!error) - error = svn_io_wait_for_cmd(&process, proc, NULL, NULL, pool); - - result = error ? svn_tristate_false : svn_tristate_true; - svn_error_clear(error); - } - - return result == svn_tristate_true; -} - -/* Remove temporary files from disk. - */ -static apr_status_t -cleanup_test_shm(void *arg) -{ - apr_pool_t *pool = arg; - - svn_error_clear(svn_atomic_namespace__cleanup(name_namespace, pool)); - svn_error_clear(svn_atomic_namespace__cleanup(name_namespace1, pool)); - svn_error_clear(svn_atomic_namespace__cleanup(name_namespace2, pool)); - - return 0; -} - -/* Bring shared memory to a defined state. This is very useful in case of - * lingering problems from previous tests or test runs. - */ -static svn_error_t * -init_test_shm(apr_pool_t *pool) -{ - svn_atomic_namespace__t *ns; - svn_named_atomic__t *atomic; - apr_pool_t *scratch = svn_pool_create(pool); - - if (name_namespace == NULL) - { - apr_pool_t *global_pool = svn_pool_create(NULL); - SVN_ERR(svn_io_open_unique_file3(NULL, - &name_namespace, - NULL, - svn_io_file_del_on_pool_cleanup, - global_pool, - pool)); - SVN_ERR(svn_io_open_unique_file3(NULL, - &name_namespace1, - NULL, - svn_io_file_del_on_pool_cleanup, - global_pool, - pool)); - SVN_ERR(svn_io_open_unique_file3(NULL, - &name_namespace2, - NULL, - svn_io_file_del_on_pool_cleanup, - global_pool, - pool)); - } - - /* skip tests if the current user does not have the required privileges */ - if (!svn_named_atomic__is_supported()) - return svn_error_wrap_apr(SVN_ERR_TEST_SKIPPED, - "user has insufficient privileges"); - - /* destroy temp files after usage */ - - apr_pool_cleanup_register(pool, pool, - cleanup_test_shm, apr_pool_cleanup_null); - - /* get the two I/O atomics for this thread */ - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace, scratch)); - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME, TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME "1", TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME "2", TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - - svn_pool_clear(scratch); - - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace1, scratch)); - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME, TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - svn_pool_clear(scratch); - - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace2, scratch)); - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME, TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - svn_pool_clear(scratch); - - /* done */ - - return SVN_NO_ERROR; -} - -/* Prepare the shared memory for a run with COUNT workers. - */ -static svn_error_t * -init_concurrency_test_shm(apr_pool_t *pool, int count) -{ - svn_atomic_namespace__t *ns; - svn_named_atomic__t *atomic; - int i; - - /* get the two I/O atomics for this thread */ - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace, pool)); - - /* reset the I/O atomics for all threads */ - for (i = 0; i < count; ++i) - { - SVN_ERR(svn_named_atomic__get(&atomic, - ns, - apr_pstrcat(pool, - ATOMIC_NAME, - apr_itoa(pool, i), - NULL), - TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - } - - SVN_ERR(svn_named_atomic__get(&atomic, ns, "counter", TRUE)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - - return SVN_NO_ERROR; -} - -#if APR_HAS_THREADS - -/* our thread function type - */ -typedef svn_error_t *(*thread_func_t)(int, int, int, apr_pool_t *); - -/* Per-thread input and output data. - */ -struct thread_baton -{ - int thread_count; - int thread_no; - int iterations; - svn_error_t *result; - thread_func_t func; -}; - -/* APR thread function implementation: A wrapper around baton->func that - * handles the svn_error_t return value. - */ -static void * -APR_THREAD_FUNC test_thread(apr_thread_t *thread, void *baton) -{ - struct thread_baton *params = baton; - apr_pool_t *pool = svn_pool_create_ex(NULL, NULL); - - params->result = (*params->func)(params->thread_no, - params->thread_count, - params->iterations, - pool); - svn_pool_destroy(pool); - apr_thread_exit(thread, APR_SUCCESS); - - return NULL; -} - -/* Runs FUNC in COUNT concurrent threads ITERATION times and combines the - * results. - */ -static svn_error_t * -run_threads(apr_pool_t *pool, int count, int iterations, thread_func_t func) -{ - apr_status_t status; - int i; - svn_error_t *error = SVN_NO_ERROR; - - /* all threads and their I/O data */ - apr_thread_t **threads = apr_palloc(pool, count * sizeof(*threads)); - struct thread_baton *batons = apr_palloc(pool, count * sizeof(*batons)); - - /* start threads */ - for (i = 0; i < count; ++i) - { - batons[i].thread_count = count; - batons[i].thread_no = i; - batons[i].iterations = iterations; - batons[i].func = func; - - status = apr_thread_create(&threads[i], - NULL, - test_thread, - &batons[i], - pool); - if (status != APR_SUCCESS) - SVN_ERR(svn_error_wrap_apr(status, "could not create a thread")); - } - - /* Wait for threads to finish and return result. */ - for (i = 0; i < count; ++i) - { - apr_status_t retval; - status = apr_thread_join(&retval, threads[i]); - if (status != APR_SUCCESS) - SVN_ERR(svn_error_wrap_apr(status, "waiting for thread's end failed")); - - if (batons[i].result) - error = svn_error_compose_create (error, svn_error_quick_wrap - (batons[i].result, apr_psprintf(pool, "Thread %d failed", i))); - } - - return error; -} -#endif - -/* Runs PROC in COUNT concurrent worker processes and check the results. - */ -static svn_error_t * -run_procs(apr_pool_t *pool, const char *proc, int count, int iterations) -{ - int i, k; - svn_error_t *error = SVN_NO_ERROR; - const char * directory = NULL; - - /* all processes and their I/O data */ - apr_proc_t *process = apr_palloc(pool, count * sizeof(*process)); - apr_file_t *common_stdout = NULL; - apr_file_open_stdout(&common_stdout, pool); - - SVN_ERR(adjust_proc_path(&proc, &directory, pool)); - - /* start sub-processes */ - for (i = 0; i < count; ++i) - { - const char * args[6]; - - args[0] = proc; - args[1] = apr_itoa(pool, i); - args[2] = apr_itoa(pool, count); - args[3] = apr_itoa(pool, iterations); - args[4] = name_namespace; - args[5] = NULL; - - error = svn_io_start_cmd3(&process[i], - directory, /* working directory */ - args[0], - args, - NULL, /* environment */ - FALSE, /* no handle inheritance */ - FALSE, /* no STDIN pipe */ - NULL, - FALSE, /* consolidate into 1 STDOUT */ - common_stdout, - FALSE, /* no STDERR pipe */ - NULL, - pool); - if (error) - { - /* dump program name and parameters */ - for (k = 0; k < sizeof(args) / sizeof(args[0]); ++k) - if (args[k]) - printf(k == 0 ? "%s\n" : " %s\n", args[k]); - - if (directory) - printf("working folder %s:\n", directory); - - return error; - } - } - - /* Wait for sub-processes to finish and return result. */ - for (i = 0; i < count; ++i) - { - const char *cmd = apr_psprintf(pool, - "named_atomic-test-proc %d %d %d", - i, count, iterations); - error = svn_error_compose_create(error, - svn_io_wait_for_cmd(&process[i], - cmd, NULL, NULL, - pool)); - } - - return error; -} - -/* Set SUGGESTED_ITERATIONS to a value that COUNT workers will take - * about 1 second to execute. - */ -static svn_error_t * -calibrate_iterations(apr_pool_t *pool, int count) -{ - apr_time_t start; - int calib_iterations; - double taken = 0.0; - - /* increase iterations until we pass the 100ms mark */ - - for (calib_iterations = 10; taken < 100000.0; calib_iterations *= 2) - { - apr_pool_t *scratch = svn_pool_create(pool); - SVN_ERR(init_concurrency_test_shm(scratch, count)); - - start = apr_time_now(); - SVN_ERR(run_procs(pool, TEST_PROC, count, calib_iterations)); - - taken = (double)(apr_time_now() - start); - svn_pool_destroy(scratch); - } - - /* scale that to 1s */ - - suggested_iterations = (int)(1000000.0 / taken * calib_iterations); - - return SVN_NO_ERROR; -} - -/* Find out how far the system will scale, i.e. how many workers can be - * run concurrently without experiencing significant slowdowns. - * Sets HW_THREAD_COUNT to a value of 2 .. 32 (limit the system impact in - * case our heuristics fail) and determines the number of iterations. - * Can be called multiple times but will skip the calculations after the - * first successful run. - */ -static svn_error_t * -calibrate_concurrency(apr_pool_t *pool) -{ - if (hw_thread_count == 0) - { - /* these parameters should be ok even on very slow machines */ - hw_thread_count = 2; - suggested_iterations = 100; - - /* if we've got a proper machine and OS setup, let's prepare for - * some real testing */ - if (svn_named_atomic__is_efficient() && proc_found(TEST_PROC, pool)) - { - SVN_ERR(calibrate_iterations(pool, 2)); - for (; hw_thread_count < 32; hw_thread_count *= 2) - { - int saved_suggestion = suggested_iterations; - - /* run with an additional core to spare - * (even low CPU usage might cause heavy context switching) */ - SVN_ERR(calibrate_iterations(pool, hw_thread_count * 2 + 1)); - if (suggested_iterations < 100000) - { - /* Machines with only a small number of cores are prone - * to inconsistent performance due context switching. - * Reduce the number of iterations on those machines. */ - suggested_iterations = hw_thread_count > 2 - ? saved_suggestion - : saved_suggestion / 2; - break; - } - } - } - - printf("using %d cores for %d iterations\n", hw_thread_count, - suggested_iterations); - } - - return SVN_NO_ERROR; -} - -/* The individual tests */ - -static svn_error_t * -test_basics(apr_pool_t *pool) -{ - svn_atomic_namespace__t *ns; - svn_named_atomic__t *atomic; - apr_int64_t value; - - SVN_ERR(init_test_shm(pool)); - - /* Use a separate namespace for our tests isolate them from production */ - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace, pool)); - - /* Test a non-existing atomic */ - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME "x", FALSE)); - SVN_TEST_ASSERT(atomic == NULL); - - /* Now, we auto-create it */ - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME, TRUE)); - SVN_TEST_ASSERT(atomic != NULL); - - /* The default value should be 0 */ - SVN_TEST_ASSERT_ERROR(svn_named_atomic__read(&value, NULL), - SVN_ERR_BAD_ATOMIC); - value = 1; - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 0); - - /* Write should return the previous value. */ - SVN_TEST_ASSERT_ERROR(svn_named_atomic__write(&value, 0, NULL), - SVN_ERR_BAD_ATOMIC); - value = 1; - SVN_ERR(svn_named_atomic__write(&value, 21, atomic)); - SVN_TEST_ASSERT(value == 0); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 21); - - SVN_ERR(svn_named_atomic__write(&value, 42, atomic)); - SVN_TEST_ASSERT(value == 21); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 42); - - SVN_ERR(svn_named_atomic__write(NULL, 17, atomic)); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 17); - - /* Adding & subtracting values */ - SVN_TEST_ASSERT_ERROR(svn_named_atomic__add(&value, 0, NULL), - SVN_ERR_BAD_ATOMIC); - SVN_ERR(svn_named_atomic__add(&value, 25, atomic)); - SVN_TEST_ASSERT(value == 42); - SVN_ERR(svn_named_atomic__add(NULL, 47, atomic)); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 89); - - SVN_ERR(svn_named_atomic__add(&value, -25, atomic)); - SVN_TEST_ASSERT(value == 64); - SVN_ERR(svn_named_atomic__add(NULL, -22, atomic)); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 42); - - /* Compare-and-exchange */ - SVN_TEST_ASSERT_ERROR(svn_named_atomic__cmpxchg(&value, 0, 0, NULL), - SVN_ERR_BAD_ATOMIC); - value = 1; - SVN_ERR(svn_named_atomic__cmpxchg(&value, 99, 41, atomic)); - SVN_TEST_ASSERT(value == 42); - - value = 1; - SVN_ERR(svn_named_atomic__cmpxchg(&value, 98, 42, atomic)); - SVN_TEST_ASSERT(value == 42); - SVN_ERR(svn_named_atomic__cmpxchg(&value, 67, 98, atomic)); - SVN_TEST_ASSERT(value == 98); - - SVN_ERR(svn_named_atomic__cmpxchg(NULL, 42, 67, atomic)); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 42); - - return SVN_NO_ERROR; -} - -static svn_error_t * -test_bignums(apr_pool_t *pool) -{ - svn_atomic_namespace__t *ns; - svn_named_atomic__t *atomic; - apr_int64_t value; - - SVN_ERR(init_test_shm(pool)); - - /* Use a separate namespace for our tests isolate them from production */ - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace, pool)); - - /* Auto-create our atomic variable */ - SVN_ERR(svn_named_atomic__get(&atomic, ns, ATOMIC_NAME, TRUE)); - SVN_TEST_ASSERT(atomic != NULL); - - /* Write should return the previous value. */ - - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic)); - value = 1; - SVN_ERR(svn_named_atomic__write(&value, 21 * HUGE_VALUE, atomic)); - SVN_TEST_ASSERT(value == 0 * HUGE_VALUE); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 21 * HUGE_VALUE); - - SVN_ERR(svn_named_atomic__write(&value, 17 * HUGE_VALUE, atomic)); - SVN_TEST_ASSERT(value == 21 * HUGE_VALUE); - - /* Adding & subtracting values */ - SVN_ERR(svn_named_atomic__add(&value, 25 * HUGE_VALUE, atomic)); - SVN_TEST_ASSERT(value == 42 * HUGE_VALUE); - SVN_ERR(svn_named_atomic__add(&value, -25 * HUGE_VALUE, atomic)); - SVN_TEST_ASSERT(value == 17 * HUGE_VALUE); - - /* Compare-and-exchange */ - value = 1; - SVN_ERR(svn_named_atomic__cmpxchg(&value, 99 * HUGE_VALUE, 41 * HUGE_VALUE, atomic)); - SVN_TEST_ASSERT(value == 17 * HUGE_VALUE); - - value = 1; - SVN_ERR(svn_named_atomic__cmpxchg(&value, 98 * HUGE_VALUE, 17 * HUGE_VALUE, atomic)); - SVN_TEST_ASSERT(value == 17 * HUGE_VALUE); - SVN_ERR(svn_named_atomic__read(&value, atomic)); - SVN_TEST_ASSERT(value == 98 * HUGE_VALUE); - - return SVN_NO_ERROR; -} - -static svn_error_t * -test_multiple_atomics(apr_pool_t *pool) -{ - svn_atomic_namespace__t *ns; - svn_named_atomic__t *atomic1; - svn_named_atomic__t *atomic2; - svn_named_atomic__t *atomic1_alias; - svn_named_atomic__t *atomic2_alias; - apr_int64_t value1; - apr_int64_t value2; - - SVN_ERR(init_test_shm(pool)); - - /* Use a separate namespace for our tests isolate them from production */ - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace, pool)); - - /* Create two atomics */ - SVN_ERR(svn_named_atomic__get(&atomic1, ns, ATOMIC_NAME "1", TRUE)); - SVN_ERR(svn_named_atomic__get(&atomic2, ns, ATOMIC_NAME "2", TRUE)); - SVN_TEST_ASSERT(atomic1 != NULL); - SVN_TEST_ASSERT(atomic2 != NULL); - SVN_TEST_ASSERT(atomic1 != atomic2); - - /* Get aliases to those */ - SVN_ERR(svn_named_atomic__get(&atomic1_alias, ns, ATOMIC_NAME "1", TRUE)); - SVN_ERR(svn_named_atomic__get(&atomic2_alias, ns, ATOMIC_NAME "2", TRUE)); - SVN_TEST_ASSERT(atomic1 == atomic1_alias); - SVN_TEST_ASSERT(atomic2 == atomic2_alias); - - /* The atomics shall not overlap, i.e. changes to one do not affect the other */ - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic1)); - SVN_ERR(svn_named_atomic__write(NULL, 0, atomic2)); - SVN_ERR(svn_named_atomic__write(&value1, 21 * HUGE_VALUE, atomic1)); - SVN_ERR(svn_named_atomic__write(&value2, 42 * HUGE_VALUE, atomic2)); - SVN_TEST_ASSERT(value1 == 0); - SVN_TEST_ASSERT(value2 == 0); - - SVN_ERR(svn_named_atomic__read(&value1, atomic1)); - SVN_ERR(svn_named_atomic__read(&value2, atomic2)); - SVN_TEST_ASSERT(value1 == 21 * HUGE_VALUE); - SVN_TEST_ASSERT(value2 == 42 * HUGE_VALUE); - - SVN_ERR(svn_named_atomic__add(&value1, 25 * HUGE_VALUE, atomic1)); - SVN_ERR(svn_named_atomic__add(&value2, -25 * HUGE_VALUE, atomic2)); - SVN_TEST_ASSERT(value1 == 46 * HUGE_VALUE); - SVN_TEST_ASSERT(value2 == 17 * HUGE_VALUE); - - value1 = 1; - value2 = 1; - SVN_ERR(svn_named_atomic__cmpxchg(&value1, 4 * HUGE_VALUE, 46 * HUGE_VALUE, atomic1)); - SVN_ERR(svn_named_atomic__cmpxchg(&value2, 98 * HUGE_VALUE, 17 * HUGE_VALUE, atomic2)); - SVN_TEST_ASSERT(value1 == 46 * HUGE_VALUE); - SVN_TEST_ASSERT(value2 == 17 * HUGE_VALUE); - - SVN_ERR(svn_named_atomic__read(&value1, atomic1)); - SVN_ERR(svn_named_atomic__read(&value2, atomic2)); - SVN_TEST_ASSERT(value1 == 4 * HUGE_VALUE); - SVN_TEST_ASSERT(value2 == 98 * HUGE_VALUE); - - return SVN_NO_ERROR; -} - -static svn_error_t * -test_namespaces(apr_pool_t *pool) -{ - svn_atomic_namespace__t *test_namespace1; - svn_atomic_namespace__t *test_namespace1_alias; - svn_atomic_namespace__t *test_namespace2; - svn_atomic_namespace__t *test_namespace2_alias; - svn_named_atomic__t *atomic1; - svn_named_atomic__t *atomic2; - svn_named_atomic__t *atomic1_alias; - svn_named_atomic__t *atomic2_alias; - apr_int64_t value; - - SVN_ERR(init_test_shm(pool)); - - /* Use a separate namespace for our tests isolate them from production */ - SVN_ERR(svn_atomic_namespace__create(&test_namespace1, name_namespace1, pool)); - SVN_ERR(svn_atomic_namespace__create(&test_namespace1_alias, name_namespace1, pool)); - SVN_ERR(svn_atomic_namespace__create(&test_namespace2, name_namespace2, pool)); - SVN_ERR(svn_atomic_namespace__create(&test_namespace2_alias, name_namespace2, pool)); - - /* Create two atomics with the same name in different namespaces */ - SVN_ERR(svn_named_atomic__get(&atomic1, test_namespace1, ATOMIC_NAME, TRUE)); - SVN_ERR(svn_named_atomic__get(&atomic1_alias, test_namespace1_alias, ATOMIC_NAME, FALSE)); - SVN_ERR(svn_named_atomic__get(&atomic2, test_namespace2, ATOMIC_NAME, TRUE)); - SVN_ERR(svn_named_atomic__get(&atomic2_alias, test_namespace2_alias, ATOMIC_NAME, FALSE)); - SVN_TEST_ASSERT(atomic1 != atomic1_alias); - SVN_TEST_ASSERT(atomic1_alias != NULL); - SVN_TEST_ASSERT(atomic2 != atomic2_alias); - SVN_TEST_ASSERT(atomic2_alias != NULL); - - /* Write data to our atomics */ - SVN_ERR(svn_named_atomic__write(NULL, 21 * HUGE_VALUE, atomic1)); - SVN_ERR(svn_named_atomic__write(NULL, 42 * HUGE_VALUE, atomic2)); - - /* Now check who sees which value */ - SVN_ERR(svn_named_atomic__read(&value, atomic1)); - SVN_TEST_ASSERT(value == 21 * HUGE_VALUE); - SVN_ERR(svn_named_atomic__read(&value, atomic2)); - SVN_TEST_ASSERT(value == 42 * HUGE_VALUE); - - SVN_ERR(svn_named_atomic__read(&value, atomic1_alias)); - SVN_TEST_ASSERT(value == 21 * HUGE_VALUE); - SVN_ERR(svn_named_atomic__read(&value, atomic2_alias)); - SVN_TEST_ASSERT(value == 42 * HUGE_VALUE); - - return SVN_NO_ERROR; -} - -static svn_error_t * -test_multithreaded(apr_pool_t *pool) -{ -#if APR_HAS_THREADS - SVN_ERR(init_test_shm(pool)); - - SVN_ERR(calibrate_concurrency(pool)); - - SVN_ERR(init_concurrency_test_shm(pool, hw_thread_count)); - SVN_ERR(run_threads(pool, hw_thread_count, suggested_iterations, test_pipeline)); - - return SVN_NO_ERROR; -#else - return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL); -#endif -} - -static svn_error_t * -test_multiprocess(apr_pool_t *pool) -{ - if (!proc_found(TEST_PROC, pool)) - return svn_error_wrap_apr(SVN_ERR_TEST_SKIPPED, - "executable '%s' not found", TEST_PROC); - - SVN_ERR(init_test_shm(pool)); - - SVN_ERR(calibrate_concurrency(pool)); - - SVN_ERR(init_concurrency_test_shm(pool, hw_thread_count)); - SVN_ERR(run_procs(pool, TEST_PROC, hw_thread_count, suggested_iterations)); - - return SVN_NO_ERROR; -} - -/* - ==================================================================== - If you add a new test to this file, update this array. - - (These globals are required by our included main()) -*/ - -/* An array of all test functions */ -struct svn_test_descriptor_t test_funcs[] = - { - SVN_TEST_NULL, - SVN_TEST_PASS2(test_basics, - "basic r/w access to a single atomic"), - SVN_TEST_PASS2(test_bignums, - "atomics must be 64 bits"), - SVN_TEST_PASS2(test_multiple_atomics, - "basic r/w access to multiple atomics"), - SVN_TEST_PASS2(test_namespaces, - "use different namespaces"), - SVN_TEST_PASS2(test_multithreaded, - "multithreaded access to atomics"), - SVN_TEST_PASS2(test_multiprocess, - "multi-process access to atomics"), - SVN_TEST_NULL - }; |