[libcxx-commits] [PATCH] D145183: [libc++] Implement `stop_token`
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Fri May 19 09:58:42 PDT 2023
ldionne accepted this revision.
ldionne added a comment.
This revision is now accepted and ready to land.
I am extremely happy with the state of this patch! Thanks so much for all the iterations, I feel like we really have something good with great test coverage now. I'm especially happy about how things ended up after intrusive shared ptr and other generic bits were extracted, I think the code is really neat now.
Once the remaining comments have been addressed and the CI is passing, feel free to ship this. Thank you!
================
Comment at: libcxx/include/__stop_token/stop_callback.h:42
+public:
+ using callback_type = _Callback;
+
----------------
Do you have a test for this typedef?
================
Comment at: libcxx/include/__stop_token/stop_callback.h:84
+ __state_() {
+ if (__state) {
+ if (__state->__add_callback(this)) {
----------------
ldionne wrote:
> I might combine these two ifs into `if (__state && __state->__add_callback(this))`.
Do you have a test for the fact that the `stop_callback` won't get shared ownership of the `__stop_state` if the constructor runs the callback immediately (aka if a stop has been requested at the moment of calling this constructor).
Edit: I don't think there's a way to test that without poking into the library internals -- IOW I'm not sure this is user-observable.
================
Comment at: libcxx/include/__stop_token/stop_callback.h:84-85
+ __state_() {
+ if (__state) {
+ if (__state->__add_callback(this)) {
+ // st.stop_requested() was false and this is successfully added to the linked list
----------------
I might combine these two ifs into `if (__state && __state->__add_callback(this))`.
================
Comment at: libcxx/include/__stop_token/stop_source.h:28
+struct nostopstate_t {
+ explicit nostopstate_t() = default;
+};
----------------
Do you have a test for this? We need to make sure that:
1. It exists
2. The constructor is explicit
3. Maybe that it's empty and trivially default constructible?
4. That `std::nostopstate` (the variable, not the class) exists and is constexpr.
================
Comment at: libcxx/include/__stop_token/stop_state.h:1
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
----------------
Recording the discussion: We considered whether we should move some of these classes to the dylib, and I think the answer should be no. There isn't *that much* code, it's not platform-specific (e.g. no including `windows.h`), and it would add backdeployment requirements. All in all, I don't think there's enough bang for the buck.
================
Comment at: libcxx/include/__stop_token/stop_state.h:56
+ // When the counter reaches zero, the state is destroyed
+ // It is used by __ref_counted_stop_state, but it is stored here for better layout
+ std::atomic<uint32_t> __ref_count_ = 0;
----------------
================
Comment at: libcxx/include/__stop_token/stop_state.h:70
+ _LIBCPP_HIDE_FROM_ABI void __increment_stop_source_counter() noexcept {
+ __state_.fetch_add(1 << __stop_source_counter_shift, std::memory_order_relaxed);
+ }
----------------
Could we add a `_LIBCPP_ASSERT` here to make sure that we don't overflow? Same below for the decrement: if we decrement when we are already at 0, I guess it means that there's a lifetime bug in the program somewhere and someone's using a `stop_source` that has already been destroyed. Since that's easy to catch, I think we should add those assertions.
================
Comment at: libcxx/include/__stop_token/stop_state.h:109
+ bool __destroyed = false;
+ __cb->__destroyed_ = &__destroyed;
+
----------------
Taking note of what you explained just now:
Since there's only one thread looping through the list and executing callbacks, it should be possible to store a single pointer to the currently-executing callback in the stop state. That would avoid requiring a `__completed_` and a `__destroyed_` member in the callback. Then in `__remove_callback`, we would atomic-wait on the currently-executing callback not being `this`.
I would suggest that we ship this patch with the current approach, and we investigate this improvement in a separate patch.
================
Comment at: libcxx/include/__stop_token/stop_state.h:175
+ // The destructor of stop_callback runs on the same thread of the thread that invokes the callback.
+ // Potentially the callback is invoking the destuctor of itself. Set the flag to avoid accessing
+ // destroyed members on the invoking side
----------------
================
Comment at: libcxx/include/__stop_token/stop_token.h:52
+
+private:
+ friend class stop_source;
----------------
This `private` is redundant with the one above.
================
Comment at: libcxx/test/std/thread/thread.stoptoken/stopcallback/cons.const.token.pass.cpp:95
+
+ int calledTimes = 0;
+ std::stop_callback sc(st, [&] { ++calledTimes; });
----------------
Don't change anything, but we generally use snake_case for variable names. Just in the future.
================
Comment at: libcxx/test/std/thread/thread.stoptoken/stopsource/cons.copy.pass.cpp:9
+//
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: no-threads
----------------
This is duplicated with the line below (please double-check throughout all your tests).
================
Comment at: libcxx/test/std/thread/thread.stoptoken/stopsource/cons.copy.pass.cpp:12
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// stop_source(const stop_source&) noexcept;
----------------
Here you're missing `// XFAIL: availability-synchronization_library-missing`, that would fix some of your CI.
================
Comment at: libcxx/utils/generate_header_tests.py:1
#!/usr/bin/env python
----------------
To fix your CI issue, I think you need to add `"stop_token": ["UNSUPPORTED: no-threads, availability-synchronization_library-missing"],` to `libcxx/utils/generate_feature_test_macro_components.py`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D145183/new/
https://reviews.llvm.org/D145183
More information about the libcxx-commits
mailing list