Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 1 | From 513200cf76758de4668312c628d6362bdabfaf4b Mon Sep 17 00:00:00 2001 |
| 2 | From: Alexander Kanavin <alex.kanavin@gmail.com> |
| 3 | Date: Thu, 25 May 2017 19:30:20 +0300 |
| 4 | Subject: [PATCH 1/3] Run binary package creation via thread pools. |
| 5 | |
| 6 | Upstream-Status: Submitted [https://github.com/rpm-software-management/rpm/pull/226] |
| 7 | Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com> |
| 8 | |
| 9 | --- |
| 10 | build/pack.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++----------- |
| 11 | configure.ac | 3 +++ |
| 12 | 2 files changed, 70 insertions(+), 14 deletions(-) |
| 13 | |
| 14 | diff --git a/build/pack.c b/build/pack.c |
| 15 | index ccfd614cc..ed5b9ab4e 100644 |
| 16 | --- a/build/pack.c |
| 17 | +++ b/build/pack.c |
| 18 | @@ -616,25 +616,78 @@ static rpmRC packageBinary(rpmSpec spec, Package pkg, const char *cookie, int ch |
| 19 | return rc; |
| 20 | } |
| 21 | |
| 22 | -rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating) |
| 23 | +struct binaryPackageTaskData |
| 24 | { |
| 25 | - rpmRC rc; |
| 26 | Package pkg; |
| 27 | + char *filename; |
| 28 | + rpmRC result; |
| 29 | + struct binaryPackageTaskData *next; |
| 30 | +}; |
| 31 | + |
| 32 | +static struct binaryPackageTaskData* runBinaryPackageTasks(rpmSpec spec, const char *cookie, int cheating) |
| 33 | +{ |
| 34 | + struct binaryPackageTaskData *tasks = NULL; |
| 35 | + struct binaryPackageTaskData *task = NULL; |
| 36 | + struct binaryPackageTaskData *prev = NULL; |
| 37 | + |
| 38 | + for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) { |
| 39 | + task = rcalloc(1, sizeof(*task)); |
| 40 | + task->pkg = pkg; |
| 41 | + if (pkg == spec->packages) { |
| 42 | + // the first package needs to be processed ahead of others, as they copy |
| 43 | + // changelog data from it, and so otherwise data races would happen |
| 44 | + task->result = packageBinary(spec, pkg, cookie, cheating, &(task->filename)); |
| 45 | + rpmlog(RPMLOG_NOTICE, _("Finished binary package job, result %d, filename %s\n"), task->result, task->filename); |
| 46 | + tasks = task; |
| 47 | + } |
| 48 | + if (prev != NULL) { |
| 49 | + prev->next = task; |
| 50 | + } |
| 51 | + prev = task; |
| 52 | + } |
| 53 | + |
| 54 | + #pragma omp parallel |
| 55 | + #pragma omp single |
| 56 | + // re-declaring task variable is necessary, or older gcc versions will produce code that segfaults |
| 57 | + for (struct binaryPackageTaskData *task = tasks; task != NULL; task = task->next) { |
| 58 | + if (task != tasks) |
| 59 | + #pragma omp task |
| 60 | + { |
| 61 | + task->result = packageBinary(spec, task->pkg, cookie, cheating, &(task->filename)); |
| 62 | + rpmlog(RPMLOG_NOTICE, _("Finished binary package job, result %d, filename %s\n"), task->result, task->filename); |
| 63 | + } |
| 64 | + } |
| 65 | + |
| 66 | + return tasks; |
| 67 | +} |
| 68 | + |
| 69 | +static void freeBinaryPackageTasks(struct binaryPackageTaskData* tasks) |
| 70 | +{ |
| 71 | + while (tasks != NULL) { |
| 72 | + struct binaryPackageTaskData* next = tasks->next; |
| 73 | + rfree(tasks->filename); |
| 74 | + rfree(tasks); |
| 75 | + tasks = next; |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +rpmRC packageBinaries(rpmSpec spec, const char *cookie, int cheating) |
| 80 | +{ |
| 81 | char *pkglist = NULL; |
| 82 | |
| 83 | - for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { |
| 84 | - char *fn = NULL; |
| 85 | - rc = packageBinary(spec, pkg, cookie, cheating, &fn); |
| 86 | - if (rc == RPMRC_OK) { |
| 87 | - rstrcat(&pkglist, fn); |
| 88 | - rstrcat(&pkglist, " "); |
| 89 | - } |
| 90 | - free(fn); |
| 91 | - if (rc != RPMRC_OK) { |
| 92 | - pkglist = _free(pkglist); |
| 93 | - return rc; |
| 94 | - } |
| 95 | + struct binaryPackageTaskData *tasks = runBinaryPackageTasks(spec, cookie, cheating); |
| 96 | + |
| 97 | + for (struct binaryPackageTaskData *task = tasks; task != NULL; task = task->next) { |
| 98 | + if (task->result == RPMRC_OK) { |
| 99 | + rstrcat(&pkglist, task->filename); |
| 100 | + rstrcat(&pkglist, " "); |
| 101 | + } else { |
| 102 | + _free(pkglist); |
| 103 | + freeBinaryPackageTasks(tasks); |
| 104 | + return RPMRC_FAIL; |
| 105 | + } |
| 106 | } |
| 107 | + freeBinaryPackageTasks(tasks); |
| 108 | |
| 109 | /* Now check the package set if enabled */ |
| 110 | if (pkglist != NULL) { |
| 111 | diff --git a/configure.ac b/configure.ac |
| 112 | index a506ec819..59fa0acaf 100644 |
| 113 | --- a/configure.ac |
| 114 | +++ b/configure.ac |
| 115 | @@ -17,6 +17,9 @@ AC_DISABLE_STATIC |
| 116 | |
| 117 | PKG_PROG_PKG_CONFIG |
| 118 | |
| 119 | +AC_OPENMP |
| 120 | +RPMCFLAGS="$OPENMP_CFLAGS $RPMCFLAGS" |
| 121 | + |
| 122 | dnl Checks for programs. |
| 123 | AC_PROG_CXX |
| 124 | AC_PROG_AWK |
| 125 | -- |
| 126 | 2.11.0 |
| 127 | |