]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
seekable_format: Fix race in parallel_processing
authorDave Vasilevsky <dave@vasilevsky.ca>
Wed, 7 May 2025 04:10:10 +0000 (00:10 -0400)
committerYann Collet <Cyan4973@users.noreply.github.com>
Thu, 8 May 2025 05:01:49 +0000 (22:01 -0700)
There was no memory barrier between writing and reading `done`, which
would allow reordering to cause races. With so little data to handle
after each job completes, we might as well just join.

contrib/seekable_format/examples/parallel_processing.c

index 928371025c977cc6e2b7652d0fca97964735575c..2757a9aba07fa19219aee532ba62ba4d37c0e667 100644 (file)
@@ -100,13 +100,11 @@ struct sum_job {
     const char* fname;
     unsigned long long sum;
     unsigned frameNb;
-    int done;
 };
 
 static void sumFrame(void* opaque)
 {
     struct sum_job* job = (struct sum_job*)opaque;
-    job->done = 0;
 
     FILE* const fin = fopen_orDie(job->fname, "rb");
 
@@ -128,7 +126,6 @@ static void sumFrame(void* opaque)
         sum += data[i];
     }
     job->sum = sum;
-    job->done = 1;
 
     fclose(fin);
     ZSTD_seekable_free(seekable);
@@ -153,14 +150,14 @@ static void sumFile_orDie(const char* fname, int nbThreads)
 
     unsigned fnb;
     for (fnb = 0; fnb < numFrames; fnb++) {
-        jobs[fnb] = (struct sum_job){ fname, 0, fnb, 0 };
+        jobs[fnb] = (struct sum_job){ fname, 0, fnb };
         POOL_add(pool, sumFrame, &jobs[fnb]);
     }
+    POOL_joinJobs(pool);
 
     unsigned long long total = 0;
 
     for (fnb = 0; fnb < numFrames; fnb++) {
-        while (!jobs[fnb].done) SLEEP(5); /* wake up every 5 milliseconds to check */
         total += jobs[fnb].sum;
     }