[dpdk-dev] [PATCH v5] pflock: implementation of phase-fair reader writer locks
Honnappa Nagarahalli
Honnappa.Nagarahalli at arm.com
Tue Apr 6 23:56:05 CEST 2021
<snip>
>
> This is a new type of reader-writer lock that provides better fairness
> guarantees which better suited for typical DPDK applications.
> A pflock has two ticket pools, one for readers and one for writers.
>
> Phase fair reader writer locks ensure that neither reader nor writer will be
> starved. Neither reader or writer are preferred, they execute in alternating
> phases. All operations of the same type (reader or writer) that acquire the
> lock are handled in FIFO order. Write operations are exclusive, and multiple
> read operations can be run together (until a write arrives).
>
> A similar implementation is in Concurrency Kit package in FreeBSD.
> For more information see:
> "Reader-Writer Synchronization for Shared-Memory Multiprocessor
> Real-Time Systems",
> http://www.cs.unc.edu/~anderson/papers/ecrts09b.pdf
>
> Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
Looks good.
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli at arm.com>
One question below
> ---
> v5 - cleanup typos in the lock code comments
> minor revision to unit test.
> Note: the unit test is intentionally the same as other locking tests.
>
> app/test/meson.build | 2 +
> app/test/test_pflock.c | 197 +++++++++++++++++++
> lib/librte_eal/arm/include/meson.build | 1 +
> lib/librte_eal/arm/include/rte_pflock.h | 18 ++
> lib/librte_eal/include/generic/rte_pflock.h | 205 ++++++++++++++++++++
> lib/librte_eal/ppc/include/meson.build | 1 +
> lib/librte_eal/ppc/include/rte_pflock.h | 17 ++
> lib/librte_eal/x86/include/meson.build | 1 +
> lib/librte_eal/x86/include/rte_pflock.h | 18 ++
> 9 files changed, 460 insertions(+)
> create mode 100644 app/test/test_pflock.c create mode 100644
> lib/librte_eal/arm/include/rte_pflock.h
> create mode 100644 lib/librte_eal/include/generic/rte_pflock.h
> create mode 100644 lib/librte_eal/ppc/include/rte_pflock.h
> create mode 100644 lib/librte_eal/x86/include/rte_pflock.h
>
<snip>
> diff --git a/app/test/test_pflock.c b/app/test/test_pflock.c new file mode
> 100644 index 000000000000..6922bbc2f813
> --- /dev/null
> +++ b/app/test/test_pflock.c
> @@ -0,0 +1,197 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2021 Microsoft Corporation */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <unistd.h>
> +#include <sys/queue.h>
> +#include <string.h>
> +
> +#include <rte_common.h>
> +#include <rte_memory.h>
> +#include <rte_per_lcore.h>
> +#include <rte_launch.h>
> +#include <rte_pause.h>
> +#include <rte_pflock.h>
> +#include <rte_eal.h>
> +#include <rte_lcore.h>
> +#include <rte_cycles.h>
> +
> +#include "test.h"
> +
<snip>
> +
> +/*
> + * - There is a global pflock and a table of pflocks (one per lcore).
> + *
> + * - The test function takes all of these locks and launches the
> + * ``test_pflock_per_core()`` function on each core (except the main).
> + *
> + * - The function takes the global write lock, display something,
> + * then releases the global lock.
> + * - Then, it takes the per-lcore write lock, display something, and
> + * releases the per-core lock.
> + * - Finally, a read lock is taken during 100 ms, then released.
> + *
> + * - 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.
> + *
> + * Then, it tries to take the global write lock and display the last
> + * message. The autotest script checks that the message order is correct.
How does the autotest script does this?
> + */
> +static int
> +test_pflock(void)
> +{
> + int i;
> +
> + rte_pflock_init(&sl);
> + for (i = 0; i < RTE_MAX_LCORE; i++)
> + rte_pflock_init(&sl_tab[i]);
> +
> + rte_pflock_write_lock(&sl);
> +
> + RTE_LCORE_FOREACH_WORKER(i) {
> + rte_pflock_write_lock(&sl_tab[i]);
> + rte_eal_remote_launch(test_pflock_per_core, NULL, i);
> + }
> +
> + rte_pflock_write_unlock(&sl);
> +
> + RTE_LCORE_FOREACH_WORKER(i) {
> + rte_pflock_write_unlock(&sl_tab[i]);
> + rte_delay_ms(100);
> + }
> +
> + rte_pflock_write_lock(&sl);
> + /* this message should be the last message of test */
> + printf("Global write lock taken on main core %u\n", rte_lcore_id());
> + rte_pflock_write_unlock(&sl);
> +
> + rte_eal_mp_wait_lcore();
> +
> + if (test_pflock_perf() < 0)
> + return -1;
> +
> + return 0;
> +}
> +
> +REGISTER_TEST_COMMAND(pflock_autotest, test_pflock);
<snip>
More information about the dev
mailing list