Hi Aaron, On Sun, 2025-06-29 at 23:51 -0400, Aaron Merey wrote: > Add new internal static library libthread.a that provides infrastructure > for eu-* tools to run functions concurrently using pthreads. > > threadlib.c manages per-job threads as well as per-job buffers for stdout > output. Output for each job is printed to stdout in the order that the > jobs were added to the job queue. This helps preserve the order of > output when parallelization is added to an eu-* tool. > > threadlib.h declares functions add_job and run_jobs. Jobs are added to > a threadlib.c internal job queue using add_job. run_jobs concurrently > executes jobs in parallel. > > eu-readelf now links against libthread.a when elfutils is configured > with --enable-thread-safety. > > * src/Makefile.am: libthread.a is compiled and and linked with > readelf when USE_LOCKS is defined. > * src/threadlib.c: New file. Manages job creation, concurrent > execution and output handling. > * src/threadlib.h: New file. Declares functions add_job and > run_jobs. > > Signed-off-by: Aaron Merey <ame...@redhat.com> > > --- > v3: > Document that add_job cannot be called during run_jobs.
Now that we have that clear and I read the other patches I do think this is a limitation that we might want to address somehow. For example it seems nice to be able to parallize the processing of debug_info CUs or the debug_line tables. So it might be nice for a job to be able to create subjobs just for its own stream. But this doesn't need to be resolved right now. The threadlib is an internal library, so we can just change it however we want in the future. > Add noinst_HEADERS and EXTRA_libtreahd_a_DEPENDENCIES to src/Makefile.am > > Replace a printf call with fwrite. > > Add a comment clarifying the use of NULL in the job queue. > > The main thread now waits on a condition variable after creating worker > threads. A worker thread will signal this condition variable when a job > completes. This looks good. I think with the mutex and condition you no longer need the atomic stores (they all seem to happen under the mutex now?). Although it cannot hurt. > > On Thu, May 22, 2025 at 06:28:52PM -0400, Aaron Merey wrote: > > > +typedef enum { > > > + /* pthread_create has not been called. */ > > > + NOT_STARTED, > > > + > > > + /* pthread_create has been called. */ > > > + STARTED, > > > + > > > + /* The thread has finished running the job but has not been joined. */ > > > + DONE, > > > + > > > + /* pthread_join has been called. */ > > > + JOINED > > > +} thread_state_t; > > > > Do we have to think about the state of other possibly failed jobs? > > Or does a failed job just call exit and that terminates everything? > > Yes exit will terminate the whole program in this case. OK. Then we should make sure that they output their warning/error message to stderr and not their current stream (because that will be lost). I think that happens automatically when using error() to exit. Cheers, Mark