diff options
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
-rw-r--r-- | bitbake/lib/bb/runqueue.py | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 00c71070d2..fa848326d8 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
@@ -68,6 +68,14 @@ def build_tid(mc, fn, taskname): | |||
68 | return "mc:" + mc + ":" + fn + ":" + taskname | 68 | return "mc:" + mc + ":" + fn + ":" + taskname |
69 | return fn + ":" + taskname | 69 | return fn + ":" + taskname |
70 | 70 | ||
71 | # Index used to pair up potentially matching multiconfig tasks | ||
72 | # We match on PN, taskname and hash being equal | ||
73 | def pending_hash_index(tid, rqdata): | ||
74 | (mc, fn, taskname, taskfn) = split_tid_mcfn(tid) | ||
75 | pn = rqdata.dataCaches[mc].pkg_fn[taskfn] | ||
76 | h = rqdata.runtaskentries[tid].hash | ||
77 | return pn + ":" + "taskname" + h | ||
78 | |||
71 | class RunQueueStats: | 79 | class RunQueueStats: |
72 | """ | 80 | """ |
73 | Holds statistics on the tasks handled by the associated runQueue | 81 | Holds statistics on the tasks handled by the associated runQueue |
@@ -1717,6 +1725,7 @@ class RunQueueExecute: | |||
1717 | self.build_stamps = {} | 1725 | self.build_stamps = {} |
1718 | self.build_stamps2 = [] | 1726 | self.build_stamps2 = [] |
1719 | self.failed_tids = [] | 1727 | self.failed_tids = [] |
1728 | self.sq_deferred = {} | ||
1720 | 1729 | ||
1721 | self.stampcache = {} | 1730 | self.stampcache = {} |
1722 | 1731 | ||
@@ -1921,17 +1930,32 @@ class RunQueueExecute: | |||
1921 | # Find the next setscene to run | 1930 | # Find the next setscene to run |
1922 | for nexttask in self.rqdata.runq_setscene_tids: | 1931 | for nexttask in self.rqdata.runq_setscene_tids: |
1923 | if nexttask in self.sq_buildable and nexttask not in self.sq_running and self.sqdata.stamps[nexttask] not in self.build_stamps.values(): | 1932 | if nexttask in self.sq_buildable and nexttask not in self.sq_running and self.sqdata.stamps[nexttask] not in self.build_stamps.values(): |
1924 | if nexttask in self.sqdata.unskippable: | ||
1925 | logger.debug(2, "Setscene task %s is unskippable" % nexttask) | ||
1926 | if nexttask not in self.sqdata.unskippable and len(self.sqdata.sq_revdeps[nexttask]) > 0 and self.sqdata.sq_revdeps[nexttask].issubset(self.scenequeue_covered) and self.check_dependencies(nexttask, self.sqdata.sq_revdeps[nexttask]): | 1933 | if nexttask not in self.sqdata.unskippable and len(self.sqdata.sq_revdeps[nexttask]) > 0 and self.sqdata.sq_revdeps[nexttask].issubset(self.scenequeue_covered) and self.check_dependencies(nexttask, self.sqdata.sq_revdeps[nexttask]): |
1927 | if nexttask not in self.rqdata.target_tids: | 1934 | if nexttask not in self.rqdata.target_tids: |
1928 | logger.debug(2, "Skipping setscene for task %s" % nexttask) | 1935 | logger.debug(2, "Skipping setscene for task %s" % nexttask) |
1929 | self.sq_task_skip(nexttask) | 1936 | self.sq_task_skip(nexttask) |
1930 | self.scenequeue_notneeded.add(nexttask) | 1937 | self.scenequeue_notneeded.add(nexttask) |
1938 | if nexttask in self.sq_deferred: | ||
1939 | del self.sq_deferred[nexttask] | ||
1940 | return True | ||
1941 | if nexttask in self.sq_deferred: | ||
1942 | if self.sq_deferred[nexttask] not in self.runq_complete: | ||
1943 | continue | ||
1944 | logger.debug(1, "Task %s no longer deferred" % nexttask) | ||
1945 | del self.sq_deferred[nexttask] | ||
1946 | valid = self.rq.validate_hashes(set([nexttask]), self.cooker.data, None, False) | ||
1947 | if not valid: | ||
1948 | logger.debug(1, "%s didn't become valid, skipping setscene" % nexttask) | ||
1949 | self.sq_task_failoutright(nexttask) | ||
1931 | return True | 1950 | return True |
1951 | else: | ||
1952 | self.sqdata.outrightfail.remove(nexttask) | ||
1932 | if nexttask in self.sqdata.outrightfail: | 1953 | if nexttask in self.sqdata.outrightfail: |
1954 | logger.debug(2, 'No package found, so skipping setscene task %s', nexttask) | ||
1933 | self.sq_task_failoutright(nexttask) | 1955 | self.sq_task_failoutright(nexttask) |
1934 | return True | 1956 | return True |
1957 | if nexttask in self.sqdata.unskippable: | ||
1958 | logger.debug(2, "Setscene task %s is unskippable" % nexttask) | ||
1935 | task = nexttask | 1959 | task = nexttask |
1936 | break | 1960 | break |
1937 | if task is not None: | 1961 | if task is not None: |
@@ -1982,7 +2006,7 @@ class RunQueueExecute: | |||
1982 | if self.can_start_task(): | 2006 | if self.can_start_task(): |
1983 | return True | 2007 | return True |
1984 | 2008 | ||
1985 | if not self.sq_live and not self.sqdone: | 2009 | if not self.sq_live and not self.sqdone and not self.sq_deferred: |
1986 | logger.info("Setscene tasks completed") | 2010 | logger.info("Setscene tasks completed") |
1987 | logger.debug(1, 'We could skip tasks %s', "\n".join(sorted(self.scenequeue_covered))) | 2011 | logger.debug(1, 'We could skip tasks %s', "\n".join(sorted(self.scenequeue_covered))) |
1988 | 2012 | ||
@@ -2083,6 +2107,13 @@ class RunQueueExecute: | |||
2083 | self.rq.read_workers() | 2107 | self.rq.read_workers() |
2084 | return self.rq.active_fds() | 2108 | return self.rq.active_fds() |
2085 | 2109 | ||
2110 | # No more tasks can be run. If we have deferred setscene tasks we should run them. | ||
2111 | if self.sq_deferred: | ||
2112 | tid = self.sq_deferred.pop(list(self.sq_deferred.keys())[0]) | ||
2113 | logger.warning("Runqeueue deadlocked on deferred tasks, forcing task %s" % tid) | ||
2114 | self.sq_task_failoutright(tid) | ||
2115 | return True | ||
2116 | |||
2086 | if len(self.failed_tids) != 0: | 2117 | if len(self.failed_tids) != 0: |
2087 | self.rq.state = runQueueFailed | 2118 | self.rq.state = runQueueFailed |
2088 | return True | 2119 | return True |
@@ -2347,7 +2378,7 @@ class SQData(object): | |||
2347 | # Setscene tasks directly depended upon by the build | 2378 | # Setscene tasks directly depended upon by the build |
2348 | self.unskippable = set() | 2379 | self.unskippable = set() |
2349 | # List of setscene tasks which aren't present | 2380 | # List of setscene tasks which aren't present |
2350 | self.outrightfail = [] | 2381 | self.outrightfail = set() |
2351 | # A list of normal tasks a setscene task covers | 2382 | # A list of normal tasks a setscene task covers |
2352 | self.sq_covered_tasks = {} | 2383 | self.sq_covered_tasks = {} |
2353 | 2384 | ||
@@ -2510,7 +2541,9 @@ def build_scenequeue_data(sqdata, rqdata, rq, cooker, stampcache, sqrq): | |||
2510 | 2541 | ||
2511 | rqdata.init_progress_reporter.next_stage() | 2542 | rqdata.init_progress_reporter.next_stage() |
2512 | 2543 | ||
2544 | multiconfigs = set() | ||
2513 | for tid in sqdata.sq_revdeps: | 2545 | for tid in sqdata.sq_revdeps: |
2546 | multiconfigs.add(mc_from_tid(tid)) | ||
2514 | if len(sqdata.sq_revdeps[tid]) == 0: | 2547 | if len(sqdata.sq_revdeps[tid]) == 0: |
2515 | sqrq.sq_buildable.add(tid) | 2548 | sqrq.sq_buildable.add(tid) |
2516 | 2549 | ||
@@ -2552,10 +2585,21 @@ def build_scenequeue_data(sqdata, rqdata, rq, cooker, stampcache, sqrq): | |||
2552 | for v in valid: | 2585 | for v in valid: |
2553 | valid_new.append(v) | 2586 | valid_new.append(v) |
2554 | 2587 | ||
2555 | for tid in sqdata.sq_revdeps: | 2588 | hashes = {} |
2556 | if tid not in valid_new and tid not in noexec: | 2589 | for mc in sorted(multiconfigs): |
2557 | logger.debug(2, 'No package found, so skipping setscene task %s', tid) | 2590 | for tid in sqdata.sq_revdeps: |
2558 | sqdata.outrightfail.append(tid) | 2591 | if mc_from_tid(tid) != mc: |
2592 | continue | ||
2593 | if tid not in valid_new and tid not in noexec and tid not in sqrq.scenequeue_notcovered: | ||
2594 | sqdata.outrightfail.add(tid) | ||
2595 | |||
2596 | h = pending_hash_index(tid, rqdata) | ||
2597 | if h not in hashes: | ||
2598 | hashes[h] = tid | ||
2599 | else: | ||
2600 | sqrq.sq_deferred[tid] = hashes[h] | ||
2601 | bb.warn("Deferring %s after %s" % (tid, hashes[h])) | ||
2602 | |||
2559 | 2603 | ||
2560 | class TaskFailure(Exception): | 2604 | class TaskFailure(Exception): |
2561 | """ | 2605 | """ |