Repository navigation
GH-50239: [R] Data race issue from R API requests in parallel region - #50488
Conversation
|
|
|
@ursabot please benchmark |
|
Benchmark runs are scheduled for commit 824f648. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete. |
There was a problem hiding this comment.
Pull request overview
This PR addresses a ThreadSanitizer-detected data race in the R bindings when use_threads = TRUE by preventing worker threads from touching R vectors until after all R-side allocations and list assignments are complete on the main thread.
Changes:
- Delay scheduling of parallel
RTaskswork untilRTasks::Finish()instead of submitting immediately inRTasks::Append(). - Add storage for delayed parallel tasks and ensure it is cleared on
Reset().
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| r/src/RTasks.cpp | Queues parallel tasks in Append(), then submits them in Finish() after serial work completes; clears the new queue in Reset(). |
| r/src/r_task_group.h | Adds delayed_parallel_tasks_ to hold parallel tasks until Finish(). |
|
Thanks for your patience. Conbench analyzed the 4 benchmarking runs that have been run so far on PR commit 824f648. There were 7 benchmark results indicating a performance regression:
The full Conbench report has more details. |
824f648 to
d95aab3
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
r/src/RTasks.cpp:49
- RTasks::Finish() will submit delayed parallel tasks even after a delayed serial task has failed (and stop has been requested). Since parallel tasks are now delayed, it’s safer to skip submission/Finish on the error path. Also consider clearing delayed_parallel_tasks_ after moving tasks so a second Finish() call can’t try to append moved-from tasks.
if (use_threads_) {
for (auto& task : delayed_parallel_tasks_) {
parallel_tasks_->Append(std::move(task));
}
status &= parallel_tasks_->Finish();
It's happening with everyone lately but noones been bothered enough yet. |
|
Best I can assume is that those regressions above are existing ones given they're for the C++ benchmarks. I ran a few tests locally and is all good. And the approval thing is to do with Copilot not being a committer and so some label runs won't trigger. |

Rationale for this change
When
use_threads = TRUE, parallel tasks are submitted to the thread pool immediately duringRTasks::Append(). This means worker threads start reading R vector headers (viaINTEGER(),REAL(), etc.) while the main thread is still assigning vectors into the output list viaSET_VECTOR_ELT, which writes to the same header memory. ThreadSanitizer detects this as a data race.What changes are included in this PR?
Delay submission of parallel tasks until
RTasks::Finish(), matching the existing pattern for serial tasks. All R-side allocations and list assignments complete on the main thread before any worker threads start.Are these changes tested?
Existing tests cover the affected code path.
I also ran some local benchmarks to see if this change affected performance, but seems fine.
Are there any user-facing changes?
No.