• Etienne Pierre-doray's avatar
    [Jobs]: Fix AcquireTaskIds memory fences. · 2a67d299
    Etienne Pierre-doray authored
    Relaxed ordering is insufficient since the resulting task id is used by
    the caller for order operations. Test case written by omerkatz@
    demonstrates the race:
    
    TEST_F(ConcurrentMarkingTest, JobTaskIds) {
      static constexpr size_t kNumTasksToRun = 2;
      static size_t tmp[kNumTasksToRun] = { 0 };
      base::JobHandle handle = base::PostJob(
          FROM_HERE, {base::ThreadPool(), base::TaskPriority::USER_VISIBLE},
          ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating(
              [](base::JobDelegate* job) {
                uint8_t id = job->GetTaskId();
                size_t& slot = tmp[id];
                slot++;
              })),
          ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating(
              [](size_t) { return kNumTasksToRun; })));
      handle.Join();
    }
    
    Thread 1 can release its task id and thread 2 immediately pick it up,
    which causes a data race on tmp when both thread access the same idx
    with no memory fence in between. Adding memory_order_seq_cst on
    Release/AcquireTaskId ensures that different thread with same task id
    are sequential.
    
    Bug: 1119518
    Change-Id: Ifa35ca03e3663f53f76ee830bcaa8654bc48838c
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2387554Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
    Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#804082}
    2a67d299
post_job_unittest.cc 2.22 KB