summaryrefslogtreecommitdiffstats
path: root/bin/helper-functions.sh
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-05-11 12:36:22 -0400
committerMike Frysinger <vapier@gentoo.org>2012-05-12 00:09:34 -0400
commit76939c46aa2817bdbcea703432c52e5aa04160f9 (patch)
tree561409f067c048780846c069e836f69710e92bda /bin/helper-functions.sh
parent0098ee7395e2c9b35471a5c088eef1fa59946912 (diff)
downloadportage-76939c46aa2817bdbcea703432c52e5aa04160f9.tar.gz
portage-76939c46aa2817bdbcea703432c52e5aa04160f9.tar.bz2
portage-76939c46aa2817bdbcea703432c52e5aa04160f9.zip
prepstrip/ecompressdir: parallelize operations
Stealing some ideas from ferringb, add a new API for doing parallel processing in bash, and then deploy this with the stripping and compressing stages. For stripping coreutils which has about 100 ELFs, this brings time to strip down from ~7 seconds to ~0.7 seconds on my system. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'bin/helper-functions.sh')
-rw-r--r--bin/helper-functions.sh62
1 files changed, 62 insertions, 0 deletions
diff --git a/bin/helper-functions.sh b/bin/helper-functions.sh
new file mode 100644
index 000000000..1c355e247
--- /dev/null
+++ b/bin/helper-functions.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# For routines we want to use in ebuild-helpers/ but don't want to
+# expose to the general ebuild environment.
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+#
+# API functions for doing parallel processing
+#
+numjobs() {
+ # Copied from eutils.eclass:makeopts_jobs()
+ local jobs=$(echo " ${MAKEOPTS} " | \
+ sed -r -n 's:.*[[:space:]](-j|--jobs[=[:space:]])[[:space:]]*([0-9]+).*:\2:p')
+ echo ${jobs:-1}
+}
+
+multijob_init() {
+ # Setup a pipe for children to write their pids to when they finish.
+ mj_control_pipe=$(mktemp -t multijob.XXXXXX)
+ rm "${mj_control_pipe}"
+ mkfifo "${mj_control_pipe}"
+ exec {mj_control_fd}<>${mj_control_pipe}
+ rm -f "${mj_control_pipe}"
+
+ # See how many children we can fork based on the user's settings.
+ mj_max_jobs=$(numjobs)
+ mj_num_jobs=0
+}
+
+multijob_child_init() {
+ trap 'echo ${BASHPID} $? >&'${mj_control_fd} EXIT
+ trap 'exit 1' INT TERM
+}
+
+multijob_finish_one() {
+ local pid ret
+ read -r -u ${mj_control_fd} pid ret
+ : $(( --mj_num_jobs ))
+ return ${ret}
+}
+
+multijob_finish() {
+ local ret=0
+ while [[ ${mj_num_jobs} -gt 0 ]] ; do
+ multijob_finish_one
+ : $(( ret |= $? ))
+ done
+ # Let bash clean up its internal child tracking state.
+ wait
+ return ${ret}
+}
+
+multijob_post_fork() {
+ : $(( ++mj_num_jobs ))
+ if [[ ${mj_num_jobs} -ge ${mj_max_jobs} ]] ; then
+ multijob_finish_one
+ fi
+ return 0
+}