Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add thread-based RCU #12

Merged
merged 1 commit into from
Apr 29, 2022
Merged

Add thread-based RCU #12

merged 1 commit into from
Apr 29, 2022

Conversation

linD026
Copy link
Collaborator

@linD026 linD026 commented Apr 24, 2022

Add the Linux Kernel style thread-based simple RCU.
It supports sparse checking [1].

With sparse, it will report:

main.c: note: in included file:
thrd_rcu.h:95:42: warning: Using plain integer as NULL pointer
thrd_rcu.h:95:42: warning: Using plain integer as NULL pointer

It is from the pthread_mutex_t initializer, we can ignore it.

[1] https://www.kernel.org/doc/html/latest/dev-tools/sparse.html


From the ThreadSanitizer report, ignore the volatile type data race warning [1][2],
there still have the data race warning.

[reader 2835343104] 0
[reader 2826950400] 0
[reader 2818557696] 0
[reader 2810164992] 0
[reader 2801772288] 0
[updater 2793379584]
==================
WARNING: ThreadSanitizer: data race (pid=434539)
  Write of size 8 at 0x7b0400000000 by thread T6:
    #0 free ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:711 (libtsan.so.0+0x37ab8)
    #1 updater_side /home/xxxx/linux2021/concurrent-programs/thrd_rcu/main.c:41 (main+0x1a38)

  Previous read of size 4 at 0x7b0400000000 by thread T5:
    #0 reader_side /home/xxxx/linux2021/concurrent-programs/thrd_rcu/main.c:23 (main+0x1898)

  Thread T6 (tid=434546, running) created by main thread at:
    #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605f8)
    #1 main /home/xxxx/linux2021/concurrent-programs/thrd_rcu/main.c:59 (main+0x1429)

  Thread T5 (tid=434545, finished) created by main thread at:
    #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605f8)
    #1 main /home/xxxx/linux2021/concurrent-programs/thrd_rcu/main.c:56 (main+0x13fd)

SUMMARY: ThreadSanitizer: data race /home/xxxx/linux2021/concurrent-programs/thrd_rcu/main.c:41 in updater_side
==================
[reader 2784986880] 2793379584
[reader 2744121088] 2793379584
[reader 2735728384] 2793379584
[reader 2727335680] 2793379584
[reader 2718942976] 2793379584
ThreadSanitizer: reported 1 warnings

I try to debug it, but cannot figure out where the wrong is.
Not sure if it is a false positive or not.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547633.html
[2] https://gcc.gnu.org/gcc-11/changes.html

Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename the directory to "thread-rcu" and update README.md for high level description.

@linD026
Copy link
Collaborator Author

linD026 commented Apr 24, 2022

I change to C11 ( -std=c11 ), now the atomic operation and memory barrier are using stdatomic.h.
And the memory model is also tried to be compatible with C11.


But, there are still warnings:

[reader 801105664] 0
[reader 792712960] 0
[reader 784320256] 0
[reader 775927552] 0
[reader 767534848] 0
[updater 759142144]
==================
WARNING: ThreadSanitizer: data race (pid=477342)
  Write of size 8 at 0x7b0400000000 by thread T6:
    #0 free ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:711 (libtsan.so.0+0x37ab8)
    #1 updater_side /home/xxxx/linux2021/concurrent-programs/thread-rcu/main.c:43 (main+0x1d5f)

  Previous read of size 4 at 0x7b0400000000 by thread T5:
    #0 reader_side /home/xxxx/linux2021/concurrent-programs/thread-rcu/main.c:24 (main+0x1c32)

  Thread T6 (tid=477349, running) created by main thread at:
    #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605f8)
    #1 main /home/xxxx/linux2021/concurrent-programs/thread-rcu/main.c:60 (main+0x1e3f)

  Thread T5 (tid=477348, finished) created by main thread at:
    #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605f8)
    #1 main /home/xxxx/linux2021/concurrent-programs/thread-rcu/main.c:58 (main+0x1e18)

SUMMARY: ThreadSanitizer: data race /home/xxxx/linux2021/concurrent-programs/thread-rcu/main.c:43 in updater_side
==================
[reader 750749440] 759142144
[reader 711980800] 759142144
[reader 703588096] 759142144
[reader 695195392] 759142144
[reader 686802688] 759142144
ThreadSanitizer: reported 1 warnings

@jserv
Copy link
Contributor

jserv commented Apr 24, 2022

The program is not built with clang (version 10) because of various errors:

address argument to atomic operation must be a pointer to _Atomic type

@linD026
Copy link
Collaborator Author

linD026 commented Apr 25, 2022

It still has the warnings from ThreadSanitizer.


I combine the rcu_nesting with the next pointer (at the lowest 2 bit).
And make some changes to WRITE_ONCE() and READ_ONCE() to let the bitwise operation work.

But this kind of change will raise the warning from sparse.

sparse main.c -Wall -g -std=c11 -D'N_READERS=10' -fsanitize=thread -lpthread
main.c: note: in included file:
rcu.h:146:11: warning: Using plain integer as NULL pointer
rcu.h:146:11: warning: Using plain integer as NULL pointer
main.c:22:11: warning: incorrect type in argument 2 (different modifiers)
main.c:22:11:    expected void *
main.c:22:11:    got struct test [noderef] __rcu *volatile [atomic] *
main.c:40:12: warning: incorrect type in argument 2 (different modifiers)
main.c:40:12:    expected void *
main.c:40:12:    got struct test [noderef] __rcu *volatile [atomic] *
main.c:40:12: warning: incorrect type in argument 3 (different modifiers)
main.c:40:12:    expected void *
main.c:40:12:    got struct test [noderef] __rcu *volatile [atomic] *
rcu.h:167:12: warning: incorrect type in argument 2 (different modifiers)
rcu.h:167:12:    expected void *
rcu.h:167:12:    got struct rcu_node *volatile [atomic] *
rcu.h:168:13: warning: incorrect type in argument 2 (different modifiers)
rcu.h:168:13:    expected void *
rcu.h:168:13:    got struct rcu_node *volatile [atomic] *
rcu.h:173:42: warning: incorrect type in argument 2 (different modifiers)
rcu.h:173:42:    expected void *
rcu.h:173:42:    got struct rcu_node *volatile [atomic] *
rcu.h:223:5: warning: incorrect type in argument 2 (different modifiers)
rcu.h:223:5:    expected void *
rcu.h:223:5:    got unsigned long volatile [atomic] *
rcu.h:223:5: warning: incorrect type in argument 2 (different modifiers)
rcu.h:223:5:    expected void *
rcu.h:223:5:    got unsigned int volatile [atomic] *
rcu.h:223:5: warning: incorrect type in argument 2 (different modifiers)
rcu.h:223:5:    expected void *
rcu.h:223:5:    got unsigned long volatile [atomic] *
rcu.h:228:5: warning: incorrect type in argument 2 (different modifiers)
rcu.h:228:5:    expected void *
rcu.h:228:5:    got unsigned long volatile [atomic] *
rcu.h:228:5: warning: incorrect type in argument 2 (different modifiers)
rcu.h:228:5:    expected void *
rcu.h:228:5:    got unsigned long volatile [atomic] *
rcu.h:248:16: warning: incorrect type in argument 2 (different modifiers)
rcu.h:248:16:    expected void *
rcu.h:248:16:    got unsigned long volatile [atomic] *
rcu.h:247:45: warning: incorrect type in argument 2 (different modifiers)
rcu.h:247:45:    expected void *
rcu.h:247:45:    got unsigned long volatile [atomic] *
rcu.h:267:16: warning: incorrect type in argument 2 (different modifiers)
rcu.h:267:16:    expected void *
rcu.h:267:16:    got unsigned long volatile [atomic] *
rcu.h:266:45: warning: incorrect type in argument 2 (different modifiers)
rcu.h:266:45:    expected void *
rcu.h:266:45:    got unsigned long volatile [atomic] *

I will fix it a few days later since I have other stuff need to be done.
:(

@linD026
Copy link
Collaborator Author

linD026 commented Apr 28, 2022

Now, the ThreadSanitizer will not warn.
Sparse also not warn at ArchLinux v5.16.
But, it still warning on Ubuntu.

@linD026
Copy link
Collaborator Author

linD026 commented Apr 28, 2022

I fix up the warning raised by sparse.
It finally works well, now.

@linD026 linD026 force-pushed the master branch 2 times, most recently from 4dd92b3 to cf879f7 Compare April 28, 2022 10:50
@linD026
Copy link
Collaborator Author

linD026 commented Apr 28, 2022

I attempted to build thread-rcu on Apple M1 running macOS 12.3, and the compiler complained:

cc -o main main.c -Wall -g -std=c11 -D'N_READERS=10' -fsanitize=thread -lpthread
In file included from main.c:5:
./rcu.h:191:24: warning: cast to smaller integer type 'unsigned int' from 'pthread_t _Nonnull' (aka 'struct _opaque_pthread_t *') [-Wpointer-to-int-cast]
    unsigned int tid = current_tid();
                       ^~~~~~~~~~~~~
./rcu.h:42:23: note: expanded from macro 'current_tid'
#define current_tid() (unsigned int) pthread_self()
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:24:33: warning: cast to smaller integer type 'unsigned int' from 'pthread_t _Nonnull' (aka 'struct _opaque_pthread_t *') [-Wpointer-to-int-cast]
    printf("[reader #%u] %u\n", current_tid(), tmp->count);
                                ^~~~~~~~~~~~~
./rcu.h:42:23: note: expanded from macro 'current_tid'
#define current_tid() (unsigned int) pthread_self()
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:36:21: warning: cast to smaller integer type 'unsigned int' from 'pthread_t _Nonnull' (aka 'struct _opaque_pthread_t *') [-Wpointer-to-int-cast]
    newval->count = current_tid();
                    ^~~~~~~~~~~~~
./rcu.h:42:23: note: expanded from macro 'current_tid'
#define current_tid() (unsigned int) pthread_self()
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.

Fixed at cf879f7.

@linD026 linD026 force-pushed the master branch 5 times, most recently from 90f8ff8 to 8da1ad9 Compare April 29, 2022 05:06
Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add high level description in new file README.md

@linD026
Copy link
Collaborator Author

linD026 commented Apr 29, 2022

I change the test program.
Now, the new testing will be like:

100 reader(s), 5 update run(s), 2 grace period(s)
[grace period #0]   21 reader(s)
[grace period #1]   79 reader(s)

Add the Linux Kernel style thread-based simple RCU.
It supports sparse checking[1].

thread-rcu target to use Linux Kernel Memory Model (LKMM).
C11 memory model may no compatible to LKMM.
Check the paper[2] to see more detail.

[1] https://www.kernel.org/doc/html/latest/dev-tools/sparse.html
[2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0124r6.html
@jserv jserv merged commit 23c2dbb into sysprog21:master Apr 29, 2022
@jserv
Copy link
Contributor

jserv commented Apr 29, 2022

Thank @linD026 for the great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants