5. Parallel Implementation - wait for first

pthread_first.c (using shared memory):
// run a function in parallel N times, wait for the first one to finish
//
// run time is minimum of the run times for each function call
//
// main() uses an excessive amount of CPU time
//
#include <pthread.h>
#include <sched.h> // for sched_yield

#include "common.c"

 // start the threads
 //
  pthread_t t[N];

  for( int i = 0; i < N; ++i)
    if( pthread_create( &t[i], 0, f, &D[i].i ) ) { perror( "pthread_create"); return 1; }

 // wait until any one thread is finished
 //
  while(1)
  {
    int done = 0; for( int i = 0; i < N; ++i) if( D[i].size == 0) ++done;

    if( done > 0) break; // at least one thread is done

    sched_yield(); // wait a while
  }

 // stop all threads
 //
  for( int i = 0; i < N; ++i) pthread_cancel( t[i]);
}
---
$ gcc -std=c11 -pedantic -Wall -g -O -o pthread_first pthread_first.c -pthread
$ time ./pthread_first
f 0 start = 0, size = 6
f 1 start = 10, size = 5
f 3 start = 30, size = 3
f 2 start = 20, size = 4
f 3 done

real	0m3.003s
user	0m1.564s
sys	0m1.440s
---
At the same time, in another window: main() uses 100% of one CPU:
$ mpstat -P ALL 1 1
Linux 4.15.0-153-generic (zz)   11/19/2021      _x86_64_        (4 CPU)
01:46:56 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
01:46:57 PM  all   14.79    0.00   10.78    0.00    0.00    0.00    0.00    0.00    0.00   74.44
01:46:57 PM    0    1.00    0.00    1.00    0.00    0.00    0.00    0.00    0.00    0.00   98.00
01:46:57 PM    1   57.00    0.00   43.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
01:46:57 PM    2    1.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.00
01:46:57 PM    3    1.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.00