Mark Wielaard a11f22
commit 1b338aa84d4c67fefa957352a028eaca1a45d1f6
Mark Wielaard a11f22
Author: Michal Marek <mmarek@suse.com>
Mark Wielaard a11f22
Date:   Sat Sep 10 23:13:25 2016 +0200
Mark Wielaard a11f22
Mark Wielaard a11f22
    find-debuginfo.sh: Process files in parallel
Mark Wielaard a11f22
    
Mark Wielaard a11f22
    Add a -j <n> option, which, when used, will spawn <n> processes to do the
Mark Wielaard a11f22
    debuginfo extraction in parallel. A pipe is used to dispatch the files among
Mark Wielaard a11f22
    the processes.
Mark Wielaard a11f22
    
Mark Wielaard a11f22
    Signed-off-by: Michal Marek <mmarek@suse.com>
Mark Wielaard a11f22
Mark Wielaard a11f22
diff --git a/macros.in b/macros.in
Mark Wielaard a11f22
index b03c5a9..8bde2d7 100644
Mark Wielaard a11f22
--- a/macros.in
Mark Wielaard a11f22
+++ b/macros.in
Mark Wielaard a11f22
@@ -180,7 +180,7 @@
Mark Wielaard a11f22
 #	the script.  See the script for details.
Mark Wielaard a11f22
 #
Mark Wielaard a11f22
 %__debug_install_post   \
Mark Wielaard a11f22
-   %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_no_recompute_build_ids:-n} %{?_include_minidebuginfo:-m} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{VERSION}-%{RELEASE}"} %{?_unique_debug_names:--unique-debug-arch "%{_arch}"} %{?_unique_debug_srcs:--unique-debug-src-base "%{name}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
Mark Wielaard a11f22
+   %{_rpmconfigdir}/find-debuginfo.sh %{?_smp_mflags} %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_no_recompute_build_ids:-n} %{?_include_minidebuginfo:-m} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{VERSION}-%{RELEASE}"} %{?_unique_debug_names:--unique-debug-arch "%{_arch}"} %{?_unique_debug_srcs:--unique-debug-src-base "%{name}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
Mark Wielaard a11f22
 %{nil}
Mark Wielaard a11f22
 
Mark Wielaard a11f22
 #	Template for debug information sub-package.
Mark Wielaard a11f22
diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
Mark Wielaard a11f22
index 6dcd5a4..2016222 100644
Mark Wielaard a11f22
--- a/scripts/find-debuginfo.sh
Mark Wielaard a11f22
+++ b/scripts/find-debuginfo.sh
Mark Wielaard a11f22
@@ -74,6 +74,9 @@
Mark Wielaard a11f22
 # Base given by --unique-debug-src-base
Mark Wielaard a11f22
 unique_debug_src_base=
Mark Wielaard a11f22
 
Mark Wielaard a11f22
+# Number of parallel jobs to spawn
Mark Wielaard a11f22
+n_jobs=1
Mark Wielaard a11f22
+
Mark Wielaard a11f22
 BUILDDIR=.
Mark Wielaard a11f22
 out=debugfiles.list
Mark Wielaard a11f22
 nout=0
Mark Wielaard a11f22
@@ -137,6 +140,13 @@
Mark Wielaard a11f22
   -r)
Mark Wielaard a11f22
     strip_r=true
Mark Wielaard a11f22
     ;;
Mark Wielaard a11f22
+  -j)
Mark Wielaard a11f22
+    n_jobs=$2
Mark Wielaard a11f22
+    shift
Mark Wielaard a11f22
+    ;;
Mark Wielaard a11f22
+  -j*)
Mark Wielaard a11f22
+    n_jobs=${1#-j}
Mark Wielaard a11f22
+    ;;
Mark Wielaard a11f22
   *)
Mark Wielaard a11f22
     BUILDDIR=$1
Mark Wielaard a11f22
     shift
Mark Wielaard a11f22
@@ -389,9 +399,56 @@
Mark Wielaard a11f22
   fi
Mark Wielaard a11f22
 }
Mark Wielaard a11f22
 
Mark Wielaard a11f22
-while read nlinks inum f; do
Mark Wielaard a11f22
-  do_file "$nlinks" "$inum" "$f"
Mark Wielaard a11f22
-done <"$temp/primary"
Mark Wielaard a11f22
+# 16^6 - 1 or about 16 milion files
Mark Wielaard a11f22
+FILENUM_DIGITS=6
Mark Wielaard a11f22
+run_job()
Mark Wielaard a11f22
+{
Mark Wielaard a11f22
+  local jobid=$1 filenum
Mark Wielaard a11f22
+  local SOURCEFILE=$temp/debugsources.$jobid ELFBINSFILE=$temp/elfbins.$jobid
Mark Wielaard a11f22
+
Mark Wielaard a11f22
+  >"$SOURCEFILE"
Mark Wielaard a11f22
+  >"$ELFBINSFILE"
Mark Wielaard a11f22
+  # can't use read -n <n>, because it reads bytes one by one, allowing for
Mark Wielaard a11f22
+  # races
Mark Wielaard a11f22
+  while :; do
Mark Wielaard a11f22
+    filenum=$(dd bs=$(( FILENUM_DIGITS + 1 )) count=1 status=none)
Mark Wielaard a11f22
+    if test -z "$filenum"; then
Mark Wielaard a11f22
+      break
Mark Wielaard a11f22
+    fi
Mark Wielaard a11f22
+    do_file $(sed -n "$(( 0x$filenum )) p" "$temp/primary")
Mark Wielaard a11f22
+  done
Mark Wielaard a11f22
+  echo 0 >"$temp/res.$jobid"
Mark Wielaard a11f22
+}
Mark Wielaard a11f22
+
Mark Wielaard a11f22
+n_files=$(wc -l <"$temp/primary")
Mark Wielaard a11f22
+if [ $n_jobs -gt $n_files ]; then
Mark Wielaard a11f22
+  n_jobs=$n_files
Mark Wielaard a11f22
+fi
Mark Wielaard a11f22
+if [ $n_jobs -le 1 ]; then
Mark Wielaard a11f22
+  while read nlinks inum f; do
Mark Wielaard a11f22
+    do_file "$nlinks" "$inum" "$f"
Mark Wielaard a11f22
+  done <"$temp/primary"
Mark Wielaard a11f22
+else
Mark Wielaard a11f22
+  for ((i = 1; i <= n_files; i++)); do
Mark Wielaard a11f22
+    printf "%0${FILENUM_DIGITS}x\\n" $i
Mark Wielaard a11f22
+  done | (
Mark Wielaard a11f22
+    exec 3<&0
Mark Wielaard a11f22
+    for ((i = 0; i < n_jobs; i++)); do
Mark Wielaard a11f22
+      # The shell redirects stdin to /dev/null for background jobs. Work
Mark Wielaard a11f22
+      # around this by duplicating fd 0
Mark Wielaard a11f22
+      run_job $i <&3 &
Mark Wielaard a11f22
+    done
Mark Wielaard a11f22
+    wait
Mark Wielaard a11f22
+  )
Mark Wielaard a11f22
+  for f in "$temp"/res.*; do
Mark Wielaard a11f22
+    res=$(< "$f")
Mark Wielaard a11f22
+    if [ "$res" !=  "0" ]; then
Mark Wielaard a11f22
+      exit 1
Mark Wielaard a11f22
+    fi
Mark Wielaard a11f22
+  done
Mark Wielaard a11f22
+  cat "$temp"/debugsources.* >"$SOURCEFILE"
Mark Wielaard a11f22
+  cat "$temp"/elfbins.* >"$ELFBINSFILE"
Mark Wielaard a11f22
+fi
Mark Wielaard a11f22
 
Mark Wielaard a11f22
 # Invoke the DWARF Compressor utility.
Mark Wielaard a11f22
 if $run_dwz \