summaryrefslogtreecommitdiffstats
path: root/app/test/test_spinlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/test/test_spinlock.c')
-rw-r--r--app/test/test_spinlock.c336
1 files changed, 0 insertions, 336 deletions
diff --git a/app/test/test_spinlock.c b/app/test/test_spinlock.c
deleted file mode 100644
index 2d94eecc..00000000
--- a/app/test/test_spinlock.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/queue.h>
-
-#include <rte_common.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_cycles.h>
-#include <rte_spinlock.h>
-#include <rte_atomic.h>
-
-#include "test.h"
-
-/*
- * Spinlock test
- * =============
- *
- * - There is a global spinlock and a table of spinlocks (one per lcore).
- *
- * - The test function takes all of these locks and launches the
- * ``test_spinlock_per_core()`` function on each core (except the master).
- *
- * - The function takes the global lock, display something, then releases
- * the global lock.
- * - The function takes the per-lcore lock, display something, then releases
- * the per-core lock.
- *
- * - The main function unlocks the per-lcore locks sequentially and
- * waits between each lock. This triggers the display of a message
- * for each core, in the correct order. The autotest script checks that
- * this order is correct.
- *
- * - A load test is carried out, with all cores attempting to lock a single lock
- * multiple times
- */
-
-static rte_spinlock_t sl, sl_try;
-static rte_spinlock_t sl_tab[RTE_MAX_LCORE];
-static rte_spinlock_recursive_t slr;
-static unsigned count = 0;
-
-static rte_atomic32_t synchro;
-
-static int
-test_spinlock_per_core(__attribute__((unused)) void *arg)
-{
- rte_spinlock_lock(&sl);
- printf("Global lock taken on core %u\n", rte_lcore_id());
- rte_spinlock_unlock(&sl);
-
- rte_spinlock_lock(&sl_tab[rte_lcore_id()]);
- printf("Hello from core %u !\n", rte_lcore_id());
- rte_spinlock_unlock(&sl_tab[rte_lcore_id()]);
-
- return 0;
-}
-
-static int
-test_spinlock_recursive_per_core(__attribute__((unused)) void *arg)
-{
- unsigned id = rte_lcore_id();
-
- rte_spinlock_recursive_lock(&slr);
- printf("Global recursive lock taken on core %u - count = %d\n",
- id, slr.count);
- rte_spinlock_recursive_lock(&slr);
- printf("Global recursive lock taken on core %u - count = %d\n",
- id, slr.count);
- rte_spinlock_recursive_lock(&slr);
- printf("Global recursive lock taken on core %u - count = %d\n",
- id, slr.count);
-
- printf("Hello from within recursive locks from core %u !\n", id);
-
- rte_spinlock_recursive_unlock(&slr);
- printf("Global recursive lock released on core %u - count = %d\n",
- id, slr.count);
- rte_spinlock_recursive_unlock(&slr);
- printf("Global recursive lock released on core %u - count = %d\n",
- id, slr.count);
- rte_spinlock_recursive_unlock(&slr);
- printf("Global recursive lock released on core %u - count = %d\n",
- id, slr.count);
-
- return 0;
-}
-
-static rte_spinlock_t lk = RTE_SPINLOCK_INITIALIZER;
-static uint64_t lock_count[RTE_MAX_LCORE] = {0};
-
-#define TIME_MS 100
-
-static int
-load_loop_fn(void *func_param)
-{
- uint64_t time_diff = 0, begin;
- uint64_t hz = rte_get_timer_hz();
- uint64_t lcount = 0;
- const int use_lock = *(int*)func_param;
- const unsigned lcore = rte_lcore_id();
-
- /* wait synchro for slaves */
- if (lcore != rte_get_master_lcore())
- while (rte_atomic32_read(&synchro) == 0);
-
- begin = rte_get_timer_cycles();
- while (time_diff < hz * TIME_MS / 1000) {
- if (use_lock)
- rte_spinlock_lock(&lk);
- lcount++;
- if (use_lock)
- rte_spinlock_unlock(&lk);
- /* delay to make lock duty cycle slighlty realistic */
- rte_delay_us(1);
- time_diff = rte_get_timer_cycles() - begin;
- }
- lock_count[lcore] = lcount;
- return 0;
-}
-
-static int
-test_spinlock_perf(void)
-{
- unsigned int i;
- uint64_t total = 0;
- int lock = 0;
- const unsigned lcore = rte_lcore_id();
-
- printf("\nTest with no lock on single core...\n");
- load_loop_fn(&lock);
- printf("Core [%u] count = %"PRIu64"\n", lcore, lock_count[lcore]);
- memset(lock_count, 0, sizeof(lock_count));
-
- printf("\nTest with lock on single core...\n");
- lock = 1;
- load_loop_fn(&lock);
- printf("Core [%u] count = %"PRIu64"\n", lcore, lock_count[lcore]);
- memset(lock_count, 0, sizeof(lock_count));
-
- printf("\nTest with lock on %u cores...\n", rte_lcore_count());
-
- /* Clear synchro and start slaves */
- rte_atomic32_set(&synchro, 0);
- rte_eal_mp_remote_launch(load_loop_fn, &lock, SKIP_MASTER);
-
- /* start synchro and launch test on master */
- rte_atomic32_set(&synchro, 1);
- load_loop_fn(&lock);
-
- rte_eal_mp_wait_lcore();
-
- RTE_LCORE_FOREACH(i) {
- printf("Core [%u] count = %"PRIu64"\n", i, lock_count[i]);
- total += lock_count[i];
- }
-
- printf("Total count = %"PRIu64"\n", total);
-
- return 0;
-}
-
-/*
- * Use rte_spinlock_trylock() to trylock a spinlock object,
- * If it could not lock the object sucessfully, it would
- * return immediately and the variable of "count" would be
- * increased by one per times. the value of "count" could be
- * checked as the result later.
- */
-static int
-test_spinlock_try(__attribute__((unused)) void *arg)
-{
- if (rte_spinlock_trylock(&sl_try) == 0) {
- rte_spinlock_lock(&sl);
- count ++;
- rte_spinlock_unlock(&sl);
- }
-
- return 0;
-}
-
-
-/*
- * Test rte_eal_get_lcore_state() in addition to spinlocks
- * as we have "waiting" then "running" lcores.
- */
-static int
-test_spinlock(void)
-{
- int ret = 0;
- int i;
-
- /* slave cores should be waiting: print it */
- RTE_LCORE_FOREACH_SLAVE(i) {
- printf("lcore %d state: %d\n", i,
- (int) rte_eal_get_lcore_state(i));
- }
-
- rte_spinlock_init(&sl);
- rte_spinlock_init(&sl_try);
- rte_spinlock_recursive_init(&slr);
- for (i=0; i<RTE_MAX_LCORE; i++)
- rte_spinlock_init(&sl_tab[i]);
-
- rte_spinlock_lock(&sl);
-
- RTE_LCORE_FOREACH_SLAVE(i) {
- rte_spinlock_lock(&sl_tab[i]);
- rte_eal_remote_launch(test_spinlock_per_core, NULL, i);
- }
-
- /* slave cores should be busy: print it */
- RTE_LCORE_FOREACH_SLAVE(i) {
- printf("lcore %d state: %d\n", i,
- (int) rte_eal_get_lcore_state(i));
- }
- rte_spinlock_unlock(&sl);
-
- RTE_LCORE_FOREACH_SLAVE(i) {
- rte_spinlock_unlock(&sl_tab[i]);
- rte_delay_ms(10);
- }
-
- rte_eal_mp_wait_lcore();
-
- rte_spinlock_recursive_lock(&slr);
-
- /*
- * Try to acquire a lock that we already own
- */
- if(!rte_spinlock_recursive_trylock(&slr)) {
- printf("rte_spinlock_recursive_trylock failed on a lock that "
- "we already own\n");
- ret = -1;
- } else
- rte_spinlock_recursive_unlock(&slr);
-
- RTE_LCORE_FOREACH_SLAVE(i) {
- rte_eal_remote_launch(test_spinlock_recursive_per_core, NULL, i);
- }
- rte_spinlock_recursive_unlock(&slr);
- rte_eal_mp_wait_lcore();
-
- /*
- * Test if it could return immediately from try-locking a locked object.
- * Here it will lock the spinlock object first, then launch all the slave
- * lcores to trylock the same spinlock object.
- * All the slave lcores should give up try-locking a locked object and
- * return immediately, and then increase the "count" initialized with zero
- * by one per times.
- * We can check if the "count" is finally equal to the number of all slave
- * lcores to see if the behavior of try-locking a locked spinlock object
- * is correct.
- */
- if (rte_spinlock_trylock(&sl_try) == 0) {
- return -1;
- }
- count = 0;
- RTE_LCORE_FOREACH_SLAVE(i) {
- rte_eal_remote_launch(test_spinlock_try, NULL, i);
- }
- rte_eal_mp_wait_lcore();
- rte_spinlock_unlock(&sl_try);
- if (rte_spinlock_is_locked(&sl)) {
- printf("spinlock is locked but it should not be\n");
- return -1;
- }
- rte_spinlock_lock(&sl);
- if (count != ( rte_lcore_count() - 1)) {
- ret = -1;
- }
- rte_spinlock_unlock(&sl);
-
- /*
- * Test if it can trylock recursively.
- * Use rte_spinlock_recursive_trylock() to check if it can lock a spinlock
- * object recursively. Here it will try to lock a spinlock object twice.
- */
- if (rte_spinlock_recursive_trylock(&slr) == 0) {
- printf("It failed to do the first spinlock_recursive_trylock but it should able to do\n");
- return -1;
- }
- if (rte_spinlock_recursive_trylock(&slr) == 0) {
- printf("It failed to do the second spinlock_recursive_trylock but it should able to do\n");
- return -1;
- }
- rte_spinlock_recursive_unlock(&slr);
- rte_spinlock_recursive_unlock(&slr);
-
- if (test_spinlock_perf() < 0)
- return -1;
-
- return ret;
-}
-
-REGISTER_TEST_COMMAND(spinlock_autotest, test_spinlock);