<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 <step...@networkplumber.org> Looks good. Acked-by: Honnappa Nagarahalli <honnappa.nagaraha...@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>