summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2019-08-12 15:53:13 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-08-14 17:28:23 +0100
commitc86ae704d312eec4e4a86ef046bc8d5601ef4176 (patch)
tree03d411c170e9163640fffc242f4173c4d544908a /bitbake
parent18c109d6f5366d5c92f10735f7408bbd7ffa76cb (diff)
downloadpoky-c86ae704d312eec4e4a86ef046bc8d5601ef4176.tar.gz
bitbake: runqueue: Improve setscene task handling logic
The previous tasks_covered and tasks_notcovered were basically unstable data structures. We couldn't always tell whether tasks should be covered or not when trying to repair the sturcture if sstate tasks reran. In the end its simpler to throw the lists away and rebuild them based upon current data rather than trying to patch it adhoc. This turns out to be simpler and much more reliable and I've much more confidence in this code. (Bitbake rev: 52ee2ba2c617d928569f5afa404925c8b6f317bc) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/runqueue.py109
1 files changed, 34 insertions, 75 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 2bf19b9778..29786c400b 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1730,7 +1730,9 @@ class RunQueueExecute:
1730 self.tasks_notcovered = set() 1730 self.tasks_notcovered = set()
1731 self.scenequeue_notneeded = set() 1731 self.scenequeue_notneeded = set()
1732 1732
1733 self.coveredtopocess = set() 1733 # We can't skip specified target tasks which aren't setscene tasks
1734 self.cantskip = set(self.rqdata.target_tids)
1735 self.cantskip.difference_update(self.rqdata.runq_setscene_tids)
1734 1736
1735 schedulers = self.get_schedulers() 1737 schedulers = self.get_schedulers()
1736 for scheduler in schedulers: 1738 for scheduler in schedulers:
@@ -2235,12 +2237,12 @@ class RunQueueExecute:
2235 if not valid: 2237 if not valid:
2236 continue 2238 continue
2237 2239
2240 if tid in self.tasks_scenequeue_done:
2241 self.tasks_scenequeue_done.remove(tid)
2238 for dep in self.sqdata.sq_covered_tasks[tid]: 2242 for dep in self.sqdata.sq_covered_tasks[tid]:
2239 if dep not in self.runq_complete: 2243 if dep not in self.runq_complete:
2240 if dep in self.tasks_scenequeue_done: 2244 if dep in self.tasks_scenequeue_done and dep not in self.sqdata.unskippable:
2241 self.tasks_scenequeue_done.remove(dep) 2245 self.tasks_scenequeue_done.remove(dep)
2242 if dep in self.tasks_notcovered:
2243 self.tasks_notcovered.remove(dep)
2244 2246
2245 if tid in self.sq_buildable: 2247 if tid in self.sq_buildable:
2246 self.sq_buildable.remove(tid) 2248 self.sq_buildable.remove(tid)
@@ -2254,6 +2256,8 @@ class RunQueueExecute:
2254 self.sqdata.outrightfail.remove(tid) 2256 self.sqdata.outrightfail.remove(tid)
2255 if tid in self.scenequeue_notcovered: 2257 if tid in self.scenequeue_notcovered:
2256 self.scenequeue_notcovered.remove(tid) 2258 self.scenequeue_notcovered.remove(tid)
2259 if tid in self.scenequeue_covered:
2260 self.scenequeue_covered.remove(tid)
2257 2261
2258 (mc, fn, taskname, taskfn) = split_tid_mcfn(tid) 2262 (mc, fn, taskname, taskfn) = split_tid_mcfn(tid)
2259 self.sqdata.stamps[tid] = bb.build.stampfile(taskname + "_setscene", self.rqdata.dataCaches[mc], taskfn, noextra=True) 2263 self.sqdata.stamps[tid] = bb.build.stampfile(taskname + "_setscene", self.rqdata.dataCaches[mc], taskfn, noextra=True)
@@ -2269,41 +2273,8 @@ class RunQueueExecute:
2269 if changes: 2273 if changes:
2270 self.update_holdofftasks() 2274 self.update_holdofftasks()
2271 2275
2272 def scenequeue_process_notcovered(self, task):
2273 if len(self.rqdata.runtaskentries[task].depends) == 0:
2274 self.setbuildable(task)
2275 notcovered = set([task])
2276 while notcovered:
2277 new = set()
2278 for t in sorted(notcovered):
2279 for deptask in sorted(self.rqdata.runtaskentries[t].depends):
2280 if deptask in notcovered or deptask in new or deptask in self.rqdata.runq_setscene_tids or deptask in self.tasks_notcovered:
2281 continue
2282 logger.debug(1, 'Task %s depends on non-setscene task %s so not skipping' % (t, deptask))
2283 new.add(deptask)
2284 self.tasks_notcovered.add(deptask)
2285 if len(self.rqdata.runtaskentries[deptask].depends) == 0:
2286 self.setbuildable(deptask)
2287 notcovered = new
2288
2289 def scenequeue_process_unskippable(self, task):
2290 # Look up the dependency chain for non-setscene things which depend on this task
2291 # and mark as 'done'/notcovered
2292 ready = set([task])
2293 while ready:
2294 new = set()
2295 for t in sorted(ready):
2296 for deptask in sorted(self.rqdata.runtaskentries[t].revdeps):
2297 if deptask in ready or deptask in new or deptask in self.tasks_scenequeue_done or deptask in self.rqdata.runq_setscene_tids:
2298 continue
2299 if deptask in self.sqdata.unskippable:
2300 new.add(deptask)
2301 self.tasks_scenequeue_done.add(deptask)
2302 self.tasks_notcovered.add(deptask)
2303 #logger.warning("Up: " + str(deptask))
2304 ready = new
2305
2306 def scenequeue_updatecounters(self, task, fail=False): 2276 def scenequeue_updatecounters(self, task, fail=False):
2277
2307 for dep in sorted(self.sqdata.sq_deps[task]): 2278 for dep in sorted(self.sqdata.sq_deps[task]):
2308 if fail and task in self.sqdata.sq_harddeps and dep in self.sqdata.sq_harddeps[task]: 2279 if fail and task in self.sqdata.sq_harddeps and dep in self.sqdata.sq_harddeps[task]:
2309 logger.debug(2, "%s was unavailable and is a hard dependency of %s so skipping" % (task, dep)) 2280 logger.debug(2, "%s was unavailable and is a hard dependency of %s so skipping" % (task, dep))
@@ -2325,39 +2296,30 @@ class RunQueueExecute:
2325 continue 2296 continue
2326 if self.rqdata.runtaskentries[dep].revdeps.issubset(self.tasks_scenequeue_done): 2297 if self.rqdata.runtaskentries[dep].revdeps.issubset(self.tasks_scenequeue_done):
2327 new.add(dep) 2298 new.add(dep)
2328 #logger.warning(" Down: " + dep)
2329 next = new 2299 next = new
2330 2300
2331 if task in self.sqdata.unskippable: 2301 notcovered = set(self.scenequeue_notcovered)
2332 self.scenequeue_process_unskippable(task) 2302 notcovered |= self.cantskip
2333 2303 for tid in self.scenequeue_notcovered:
2334 if task in self.scenequeue_notcovered: 2304 notcovered |= self.sqdata.sq_covered_tasks[tid]
2335 logger.debug(1, 'Not skipping setscene task %s', task) 2305 notcovered |= self.sqdata.unskippable.difference(self.rqdata.runq_setscene_tids)
2336 self.scenequeue_process_notcovered(task) 2306 notcovered.intersection_update(self.tasks_scenequeue_done)
2337 elif task in self.scenequeue_covered: 2307
2338 logger.debug(1, 'Queued setscene task %s', task) 2308 covered = set(self.scenequeue_covered)
2339 self.coveredtopocess.add(task) 2309 for tid in self.scenequeue_covered:
2340 2310 covered |= self.sqdata.sq_covered_tasks[tid]
2341 for task in sorted(self.coveredtopocess.copy()): 2311 covered.difference_update(notcovered)
2342 if self.sqdata.sq_covered_tasks[task].issubset(self.tasks_scenequeue_done): 2312 covered.intersection_update(self.tasks_scenequeue_done)
2343 logger.debug(1, 'Processing setscene task %s', task) 2313
2344 covered = self.sqdata.sq_covered_tasks[task] 2314 for tid in notcovered | covered:
2345 covered.add(task) 2315 if len(self.rqdata.runtaskentries[tid].depends) == 0:
2346 2316 self.setbuildable(tid)
2347 # If a task is in target_tids and isn't a setscene task, we can't skip it. 2317 elif self.rqdata.runtaskentries[tid].depends.issubset(self.runq_complete):
2348 cantskip = covered.intersection(self.rqdata.target_tids).difference(self.rqdata.runq_setscene_tids) 2318 self.setbuildable(tid)
2349 for tid in sorted(cantskip): 2319
2350 self.tasks_notcovered.add(tid) 2320 self.tasks_covered = covered
2351 self.scenequeue_process_notcovered(tid) 2321 self.tasks_notcovered = notcovered
2352 covered.difference_update(cantskip) 2322
2353
2354 # Remove notcovered tasks
2355 covered.difference_update(self.tasks_notcovered)
2356 self.tasks_covered.update(covered)
2357 self.coveredtopocess.remove(task)
2358 for tid in sorted(covered):
2359 if self.rqdata.runtaskentries[tid].depends.issubset(self.runq_complete):
2360 self.setbuildable(tid)
2361 self.update_holdofftasks() 2323 self.update_holdofftasks()
2362 2324
2363 def sq_task_completeoutright(self, task): 2325 def sq_task_completeoutright(self, task):
@@ -2369,7 +2331,6 @@ class RunQueueExecute:
2369 2331
2370 logger.debug(1, 'Found task %s which could be accelerated', task) 2332 logger.debug(1, 'Found task %s which could be accelerated', task)
2371 self.scenequeue_covered.add(task) 2333 self.scenequeue_covered.add(task)
2372 self.tasks_covered.add(task)
2373 self.scenequeue_updatecounters(task) 2334 self.scenequeue_updatecounters(task)
2374 2335
2375 def sq_check_taskfail(self, task): 2336 def sq_check_taskfail(self, task):
@@ -2390,7 +2351,6 @@ class RunQueueExecute:
2390 self.sq_stats.taskFailed() 2351 self.sq_stats.taskFailed()
2391 bb.event.fire(sceneQueueTaskFailed(task, self.sq_stats, result, self), self.cfgData) 2352 bb.event.fire(sceneQueueTaskFailed(task, self.sq_stats, result, self), self.cfgData)
2392 self.scenequeue_notcovered.add(task) 2353 self.scenequeue_notcovered.add(task)
2393 self.tasks_notcovered.add(task)
2394 self.scenequeue_updatecounters(task, True) 2354 self.scenequeue_updatecounters(task, True)
2395 self.sq_check_taskfail(task) 2355 self.sq_check_taskfail(task)
2396 2356
@@ -2400,7 +2360,6 @@ class RunQueueExecute:
2400 self.sq_stats.taskSkipped() 2360 self.sq_stats.taskSkipped()
2401 self.sq_stats.taskCompleted() 2361 self.sq_stats.taskCompleted()
2402 self.scenequeue_notcovered.add(task) 2362 self.scenequeue_notcovered.add(task)
2403 self.tasks_notcovered.add(task)
2404 self.scenequeue_updatecounters(task, True) 2363 self.scenequeue_updatecounters(task, True)
2405 2364
2406 def sq_task_skip(self, task): 2365 def sq_task_skip(self, task):
@@ -2564,6 +2523,7 @@ def build_scenequeue_data(sqdata, rqdata, rq, cooker, stampcache, sqrq):
2564 for tid in rqdata.runtaskentries: 2523 for tid in rqdata.runtaskentries:
2565 if len(rqdata.runtaskentries[tid].revdeps) == 0: 2524 if len(rqdata.runtaskentries[tid].revdeps) == 0:
2566 sqdata.unskippable.add(tid) 2525 sqdata.unskippable.add(tid)
2526 sqdata.unskippable |= sqrq.cantskip
2567 while new: 2527 while new:
2568 new = False 2528 new = False
2569 orig = sqdata.unskippable.copy() 2529 orig = sqdata.unskippable.copy()
@@ -2572,14 +2532,13 @@ def build_scenequeue_data(sqdata, rqdata, rq, cooker, stampcache, sqrq):
2572 continue 2532 continue
2573 if len(rqdata.runtaskentries[tid].depends) == 0: 2533 if len(rqdata.runtaskentries[tid].depends) == 0:
2574 # These are tasks which have no setscene tasks in their chain, need to mark as directly buildable 2534 # These are tasks which have no setscene tasks in their chain, need to mark as directly buildable
2575 sqrq.tasks_notcovered.add(tid)
2576 sqrq.tasks_scenequeue_done.add(tid)
2577 sqrq.setbuildable(tid) 2535 sqrq.setbuildable(tid)
2578 sqrq.scenequeue_process_unskippable(tid)
2579 sqdata.unskippable |= rqdata.runtaskentries[tid].depends 2536 sqdata.unskippable |= rqdata.runtaskentries[tid].depends
2580 if sqdata.unskippable != orig: 2537 if sqdata.unskippable != orig:
2581 new = True 2538 new = True
2582 2539
2540 sqrq.tasks_scenequeue_done |= sqdata.unskippable.difference(rqdata.runq_setscene_tids)
2541
2583 rqdata.init_progress_reporter.next_stage(len(rqdata.runtaskentries)) 2542 rqdata.init_progress_reporter.next_stage(len(rqdata.runtaskentries))
2584 2543
2585 # Sanity check all dependencies could be changed to setscene task references 2544 # Sanity check all dependencies could be changed to setscene task references