forked from brl/citadel
128 lines
4.0 KiB
Diff
128 lines
4.0 KiB
Diff
|
From 513200cf76758de4668312c628d6362bdabfaf4b Mon Sep 17 00:00:00 2001
|
||
|
From: Alexander Kanavin <alex.kanavin@gmail.com>
|
||
|
Date: Thu, 25 May 2017 19:30:20 +0300
|
||
|
Subject: [PATCH 1/3] Run binary package creation via thread pools.
|
||
|
|
||
|
Upstream-Status: Submitted [https://github.com/rpm-software-management/rpm/pull/226]
|
||
|
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
|
||
|
|
||
|
---
|
||
|
build/pack.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
|
||
|
configure.ac | 3 +++
|
||
|
2 files changed, 70 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/build/pack.c b/build/pack.c
|
||
|
index ccfd614cc..ed5b9ab4e 100644
|
||
|
--- a/build/pack.c
|
||
|
+++ b/build/pack.c
|
||
|
@@ -616,25 +616,78 @@ static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int ch
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
-rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
|
||
|
+struct binaryPackageTaskData
|
||
|
{
|
||
|
- rpmRC rc;
|
||
|
Package pkg;
|
||
|
+ char *filename;
|
||
|
+ rpmRC result;
|
||
|
+ struct binaryPackageTaskData *next;
|
||
|
+};
|
||
|
+
|
||
|
+static struct binaryPackageTaskData* runBinaryPackageTasks(rpmSpec spec, const char *cookie, int cheating)
|
||
|
+{
|
||
|
+ struct binaryPackageTaskData *tasks = NULL;
|
||
|
+ struct binaryPackageTaskData *task = NULL;
|
||
|
+ struct binaryPackageTaskData *prev = NULL;
|
||
|
+
|
||
|
+ for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
||
|
+ task = rcalloc(1, sizeof(*task));
|
||
|
+ task->pkg = pkg;
|
||
|
+ if (pkg == spec->packages) {
|
||
|
+ // the first package needs to be processed ahead of others, as they copy
|
||
|
+ // changelog data from it, and so otherwise data races would happen
|
||
|
+ task->result = packageBinary(spec, pkg, cookie, cheating, &(task->filename));
|
||
|
+ rpmlog(RPMLOG_NOTICE, _("Finished binary package job, result %d, filename %s\n"), task->result, task->filename);
|
||
|
+ tasks = task;
|
||
|
+ }
|
||
|
+ if (prev != NULL) {
|
||
|
+ prev->next = task;
|
||
|
+ }
|
||
|
+ prev = task;
|
||
|
+ }
|
||
|
+
|
||
|
+ #pragma omp parallel
|
||
|
+ #pragma omp single
|
||
|
+ // re-declaring task variable is necessary, or older gcc versions will produce code that segfaults
|
||
|
+ for (struct binaryPackageTaskData *task = tasks; task != NULL; task = task->next) {
|
||
|
+ if (task != tasks)
|
||
|
+ #pragma omp task
|
||
|
+ {
|
||
|
+ task->result = packageBinary(spec, task->pkg, cookie, cheating, &(task->filename));
|
||
|
+ rpmlog(RPMLOG_NOTICE, _("Finished binary package job, result %d, filename %s\n"), task->result, task->filename);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return tasks;
|
||
|
+}
|
||
|
+
|
||
|
+static void freeBinaryPackageTasks(struct binaryPackageTaskData* tasks)
|
||
|
+{
|
||
|
+ while (tasks != NULL) {
|
||
|
+ struct binaryPackageTaskData* next = tasks->next;
|
||
|
+ rfree(tasks->filename);
|
||
|
+ rfree(tasks);
|
||
|
+ tasks = next;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating)
|
||
|
+{
|
||
|
char *pkglist = NULL;
|
||
|
|
||
|
- for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
||
|
- char *fn = NULL;
|
||
|
- rc = packageBinary(spec, pkg, cookie, cheating, &fn);
|
||
|
- if (rc == RPMRC_OK) {
|
||
|
- rstrcat(&pkglist, fn);
|
||
|
- rstrcat(&pkglist, " ");
|
||
|
- }
|
||
|
- free(fn);
|
||
|
- if (rc != RPMRC_OK) {
|
||
|
- pkglist = _free(pkglist);
|
||
|
- return rc;
|
||
|
- }
|
||
|
+ struct binaryPackageTaskData *tasks = runBinaryPackageTasks(spec, cookie, cheating);
|
||
|
+
|
||
|
+ for (struct binaryPackageTaskData *task = tasks; task != NULL; task = task->next) {
|
||
|
+ if (task->result == RPMRC_OK) {
|
||
|
+ rstrcat(&pkglist, task->filename);
|
||
|
+ rstrcat(&pkglist, " ");
|
||
|
+ } else {
|
||
|
+ _free(pkglist);
|
||
|
+ freeBinaryPackageTasks(tasks);
|
||
|
+ return RPMRC_FAIL;
|
||
|
+ }
|
||
|
}
|
||
|
+ freeBinaryPackageTasks(tasks);
|
||
|
|
||
|
/* Now check the package set if enabled */
|
||
|
if (pkglist != NULL) {
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
index a506ec819..59fa0acaf 100644
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -17,6 +17,9 @@ AC_DISABLE_STATIC
|
||
|
|
||
|
PKG_PROG_PKG_CONFIG
|
||
|
|
||
|
+AC_OPENMP
|
||
|
+RPMCFLAGS="$OPENMP_CFLAGS $RPMCFLAGS"
|
||
|
+
|
||
|
dnl Checks for programs.
|
||
|
AC_PROG_CXX
|
||
|
AC_PROG_AWK
|
||
|
--
|
||
|
2.11.0
|
||
|
|