| 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 |
| |