diff options
Diffstat (limited to 'subversion/tests/libsvn_subr/named_atomic-test-common.h')
-rw-r--r-- | subversion/tests/libsvn_subr/named_atomic-test-common.h | 245 |
1 files changed, 0 insertions, 245 deletions
diff --git a/subversion/tests/libsvn_subr/named_atomic-test-common.h b/subversion/tests/libsvn_subr/named_atomic-test-common.h deleted file mode 100644 index 2ada4ee..0000000 --- a/subversion/tests/libsvn_subr/named_atomic-test-common.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * named_atomic-test-common.h: shared function implementations for - * named_atomic-test - * - * ==================================================================== - * 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 "../svn_test.h" -#include "svn_pools.h" -#include "private/svn_named_atomic.h" - -/* Some constants that we will use in our tests */ - -/* All our atomics start with that name */ -#define ATOMIC_NAME "MyTestAtomic" - -/* Factor used to create non-trivial 64 bit numbers */ -#define HUGE_VALUE 1234567890123456ll - -/* to separate this code from any production environment */ -const char *name_namespace = NULL; -const char *name_namespace1 = NULL; -const char *name_namespace2 = NULL; - -/* data structure containing all information we need to check for - * a) passing some deadline - * b) reaching the maximum iteration number - */ -typedef struct watchdog_t -{ - apr_time_t deadline; - svn_named_atomic__t *atomic_counter; - int iterations; - int call_count; /* don't call apr_time_now() too often '*/ -} watchdog_t; - -/* init the WATCHDOG data structure for checking ATOMIC_COUNTER to reach - * ITERATIONS and for the system time to pass a deadline MAX_DURATION - * microsecs in the future. - */ -static void -init_watchdog(watchdog_t *watchdog, - svn_named_atomic__t *atomic_counter, - int iterations, - apr_time_t max_duration) -{ - watchdog->deadline = apr_time_now() + max_duration; - watchdog->atomic_counter = atomic_counter; - watchdog->iterations = iterations; - watchdog->call_count = 0; -} - -/* test for watchdog conditions */ -static svn_error_t * -check_watchdog(watchdog_t *watchdog, svn_boolean_t *done) -{ - apr_int64_t counter = 0; - - /* check for normal end of loop. - * We are a watchdog, so don't check for errors. */ - *done = FALSE; - svn_error_clear(svn_named_atomic__read(&counter, - watchdog->atomic_counter)); - if (counter >= watchdog->iterations) - { - *done = TRUE; - return SVN_NO_ERROR; - } - - /* Check the system time and indicate when deadline has passed */ - if (++watchdog->call_count > 100) - { - watchdog->call_count = 100; - if (apr_time_now() > watchdog->deadline) - return svn_error_createf(SVN_ERR_TEST_FAILED, - 0, - "Deadline has passed at iteration %d/%d", - (int)counter, watchdog->iterations); - } - - /* no problem so far */ - return SVN_NO_ERROR; -} - -/* "pipeline" test: initialization code executed by the worker with ID 0. - * Pushes COUNT tokens into ATOMIC_OUT and checks for ATOMIC_COUNTER not to - * exceed ITERATIONS (early termination). - */ -static svn_error_t * -test_pipeline_prepare(svn_named_atomic__t *atomic_out, - int count, - watchdog_t *watchdog) -{ - apr_int64_t value = 0; - int i; - svn_boolean_t done = FALSE; - - /* Initialize values in thread 0, pass them along in other threads */ - - for (i = 1; i <= count; ++i) - do - { - /* Generate new token (once the old one has been removed)*/ - SVN_ERR(svn_named_atomic__cmpxchg(&value, - i, - 0, - atomic_out)); - SVN_ERR(check_watchdog(watchdog, &done)); - if (done) return SVN_NO_ERROR; - } - while (value != 0); - - return SVN_NO_ERROR; -} - -/* "pipeline" test: the main loop. Each one of the COUNT workers receives - * data in its ATOMIC_IN and passes it on to ATOMIC_OUT until ATOMIC_COUNTER - * exceeds ITERATIONS. - */ -static svn_error_t * -test_pipeline_loop(svn_named_atomic__t *atomic_in, - svn_named_atomic__t *atomic_out, - svn_named_atomic__t *atomic_counter, - int count, - int iterations, - watchdog_t *watchdog) -{ - apr_int64_t value = 0, old_value, last_value = 0; - apr_int64_t counter; - svn_boolean_t done = FALSE; - - /* Pass the tokens along */ - - do - { - /* Wait for and consume incoming token. */ - do - { - SVN_ERR(svn_named_atomic__write(&value, 0, atomic_in)); - SVN_ERR(check_watchdog(watchdog, &done)); - if (done) return SVN_NO_ERROR; - } - while (value == 0); - - /* All tokes must come in in the same order */ - SVN_TEST_ASSERT((last_value % count) == (value - 1)); - last_value = value; - - /* Wait for the target atomic to become vacant and write the token */ - do - { - SVN_ERR(svn_named_atomic__cmpxchg(&old_value, - value, - 0, - atomic_out)); - SVN_ERR(check_watchdog(watchdog, &done)); - if (done) return SVN_NO_ERROR; - } - while (old_value != 0); - - /* Count the number of operations */ - SVN_ERR(svn_named_atomic__add(&counter, 1, atomic_counter)); - } - while (counter < iterations); - - /* done */ - - return SVN_NO_ERROR; -} - -/* "pipeline" test: worker with ID 0 initializes the data; all workers - * (COUNT in total) have one input and one output bucket that form a ring - * spanning all workers. Each worker passes the value along ITERATIONS times. - */ -static svn_error_t * -test_pipeline(int id, int count, int iterations, apr_pool_t *pool) -{ - svn_atomic_namespace__t *ns; - svn_named_atomic__t *atomic_in; - svn_named_atomic__t *atomic_out; - svn_named_atomic__t *atomic_counter; - svn_error_t *err = SVN_NO_ERROR; - watchdog_t watchdog; - - /* get the two I/O atomics for this thread */ - SVN_ERR(svn_atomic_namespace__create(&ns, name_namespace, pool)); - SVN_ERR(svn_named_atomic__get(&atomic_in, - ns, - apr_pstrcat(pool, - ATOMIC_NAME, - apr_itoa(pool, - id), - NULL), - FALSE)); - SVN_ERR(svn_named_atomic__get(&atomic_out, - ns, - apr_pstrcat(pool, - ATOMIC_NAME, - apr_itoa(pool, - (id + 1) % count), - NULL), - FALSE)); - - /* our iteration counter */ - SVN_ERR(svn_named_atomic__get(&atomic_counter, ns, "counter", FALSE)); - - /* safeguard our execution time. Limit it to 20s */ - init_watchdog(&watchdog, atomic_counter, iterations, 20000000); - - /* fill pipeline */ - if (id == 0) - err = test_pipeline_prepare(atomic_out, count, &watchdog); - - /* Pass the tokens along */ - if (!err) - err = test_pipeline_loop(atomic_in, atomic_out, atomic_counter, - count, iterations, &watchdog); - - /* if we experienced an error, cause everybody to exit */ - if (err) - svn_error_clear(svn_named_atomic__write(NULL, iterations, atomic_counter)); - - /* done */ - - return err; -} |