New upstream version 18.02
[deb_dpdk.git] / test / test / test_rwlock.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <unistd.h>
8 #include <sys/queue.h>
9
10 #include <rte_common.h>
11 #include <rte_memory.h>
12 #include <rte_per_lcore.h>
13 #include <rte_launch.h>
14 #include <rte_atomic.h>
15 #include <rte_rwlock.h>
16 #include <rte_eal.h>
17 #include <rte_lcore.h>
18 #include <rte_cycles.h>
19
20 #include "test.h"
21
22 /*
23  * rwlock test
24  * ===========
25  *
26  * - There is a global rwlock and a table of rwlocks (one per lcore).
27  *
28  * - The test function takes all of these locks and launches the
29  *   ``test_rwlock_per_core()`` function on each core (except the master).
30  *
31  *   - The function takes the global write lock, display something,
32  *     then releases the global lock.
33  *   - Then, it takes the per-lcore write lock, display something, and
34  *     releases the per-core lock.
35  *   - Finally, a read lock is taken during 100 ms, then released.
36  *
37  * - The main function unlocks the per-lcore locks sequentially and
38  *   waits between each lock. This triggers the display of a message
39  *   for each core, in the correct order.
40  *
41  *   Then, it tries to take the global write lock and display the last
42  *   message. The autotest script checks that the message order is correct.
43  */
44
45 static rte_rwlock_t sl;
46 static rte_rwlock_t sl_tab[RTE_MAX_LCORE];
47
48 static int
49 test_rwlock_per_core(__attribute__((unused)) void *arg)
50 {
51         rte_rwlock_write_lock(&sl);
52         printf("Global write lock taken on core %u\n", rte_lcore_id());
53         rte_rwlock_write_unlock(&sl);
54
55         rte_rwlock_write_lock(&sl_tab[rte_lcore_id()]);
56         printf("Hello from core %u !\n", rte_lcore_id());
57         rte_rwlock_write_unlock(&sl_tab[rte_lcore_id()]);
58
59         rte_rwlock_read_lock(&sl);
60         printf("Global read lock taken on core %u\n", rte_lcore_id());
61         rte_delay_ms(100);
62         printf("Release global read lock on core %u\n", rte_lcore_id());
63         rte_rwlock_read_unlock(&sl);
64
65         return 0;
66 }
67
68 static int
69 test_rwlock(void)
70 {
71         int i;
72
73         rte_rwlock_init(&sl);
74         for (i=0; i<RTE_MAX_LCORE; i++)
75                 rte_rwlock_init(&sl_tab[i]);
76
77         rte_rwlock_write_lock(&sl);
78
79         RTE_LCORE_FOREACH_SLAVE(i) {
80                 rte_rwlock_write_lock(&sl_tab[i]);
81                 rte_eal_remote_launch(test_rwlock_per_core, NULL, i);
82         }
83
84         rte_rwlock_write_unlock(&sl);
85
86         RTE_LCORE_FOREACH_SLAVE(i) {
87                 rte_rwlock_write_unlock(&sl_tab[i]);
88                 rte_delay_ms(100);
89         }
90
91         rte_rwlock_write_lock(&sl);
92         /* this message should be the last message of test */
93         printf("Global write lock taken on master core %u\n", rte_lcore_id());
94         rte_rwlock_write_unlock(&sl);
95
96         rte_eal_mp_wait_lcore();
97
98         return 0;
99 }
100
101 REGISTER_TEST_COMMAND(rwlock_autotest, test_rwlock);