aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/rpm/files/0002-Run-binary-package-creation-via-thread-pools.patch
blob: 549148930fa396f844a4d1ffd6802174e50c7a8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
From f8a05339a1e7b307e8de8c858e6e963782fc5925 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 | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-----------
 configure.ac |  3 +++
 2 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/build/pack.c b/build/pack.c
index 5898a491b..f85d8dc90 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -616,25 +616,77 @@ 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
+    for (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