diff options
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 75797e2520..0c7dfec2b6 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -785,6 +785,7 @@ class RunQueue: | |||
| 785 | self.stamppolicy = cfgData.getVar("BB_STAMP_POLICY", True) or "perfile" | 785 | self.stamppolicy = cfgData.getVar("BB_STAMP_POLICY", True) or "perfile" |
| 786 | self.hashvalidate = cfgData.getVar("BB_HASHCHECK_FUNCTION", True) or None | 786 | self.hashvalidate = cfgData.getVar("BB_HASHCHECK_FUNCTION", True) or None |
| 787 | self.setsceneverify = cfgData.getVar("BB_SETSCENE_VERIFY_FUNCTION", True) or None | 787 | self.setsceneverify = cfgData.getVar("BB_SETSCENE_VERIFY_FUNCTION", True) or None |
| 788 | self.depvalidate = cfgData.getVar("BB_SETSCENE_DEPVALID", True) or None | ||
| 788 | 789 | ||
| 789 | self.state = runQueuePrepare | 790 | self.state = runQueuePrepare |
| 790 | 791 | ||
| @@ -1161,6 +1162,26 @@ class RunQueueExecute: | |||
| 1161 | 1162 | ||
| 1162 | return pid, pipein, pipeout | 1163 | return pid, pipein, pipeout |
| 1163 | 1164 | ||
| 1165 | def check_dependencies(self, task, taskdeps, setscene = False): | ||
| 1166 | if not self.rq.depvalidate: | ||
| 1167 | return False | ||
| 1168 | |||
| 1169 | taskdata = {} | ||
| 1170 | taskdeps.add(task) | ||
| 1171 | for dep in taskdeps: | ||
| 1172 | if setscene: | ||
| 1173 | depid = self.rqdata.runq_setscene[dep] | ||
| 1174 | else: | ||
| 1175 | depid = dep | ||
| 1176 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[depid]] | ||
| 1177 | pn = self.rqdata.dataCache.pkg_fn[fn] | ||
| 1178 | taskname = self.rqdata.runq_task[depid] | ||
| 1179 | taskdata[dep] = [pn, taskname, fn] | ||
| 1180 | call = self.rq.depvalidate + "(task, taskdata, notneeded, d)" | ||
| 1181 | locs = { "task" : task, "taskdata" : taskdata, "notneeded" : self.scenequeue_notneeded, "d" : self.cooker.configuration.data } | ||
| 1182 | valid = bb.utils.better_eval(call, locs) | ||
| 1183 | return valid | ||
| 1184 | |||
| 1164 | class RunQueueExecuteDummy(RunQueueExecute): | 1185 | class RunQueueExecuteDummy(RunQueueExecute): |
| 1165 | def __init__(self, rq): | 1186 | def __init__(self, rq): |
| 1166 | self.rq = rq | 1187 | self.rq = rq |
| @@ -1198,16 +1219,8 @@ class RunQueueExecuteTasks(RunQueueExecute): | |||
| 1198 | logger.debug(1, 'Considering %s (%s): %s' % (task, self.rqdata.get_user_idstring(task), str(self.rqdata.runq_revdeps[task]))) | 1219 | logger.debug(1, 'Considering %s (%s): %s' % (task, self.rqdata.get_user_idstring(task), str(self.rqdata.runq_revdeps[task]))) |
| 1199 | 1220 | ||
| 1200 | if len(self.rqdata.runq_revdeps[task]) > 0 and self.rqdata.runq_revdeps[task].issubset(self.rq.scenequeue_covered) and task not in self.rq.scenequeue_notcovered: | 1221 | if len(self.rqdata.runq_revdeps[task]) > 0 and self.rqdata.runq_revdeps[task].issubset(self.rq.scenequeue_covered) and task not in self.rq.scenequeue_notcovered: |
| 1201 | ok = True | 1222 | found = True |
| 1202 | for revdep in self.rqdata.runq_revdeps[task]: | 1223 | self.rq.scenequeue_covered.add(task) |
| 1203 | if self.rqdata.runq_fnid[task] != self.rqdata.runq_fnid[revdep]: | ||
| 1204 | logger.debug(1, 'Found "bad" dep %s (%s) for %s (%s)' % (revdep, self.rqdata.get_user_idstring(revdep), task, self.rqdata.get_user_idstring(task))) | ||
| 1205 | |||
| 1206 | ok = False | ||
| 1207 | break | ||
| 1208 | if ok: | ||
| 1209 | found = True | ||
| 1210 | self.rq.scenequeue_covered.add(task) | ||
| 1211 | 1224 | ||
| 1212 | logger.debug(1, 'Skip list (pre setsceneverify) %s', sorted(self.rq.scenequeue_covered)) | 1225 | logger.debug(1, 'Skip list (pre setsceneverify) %s', sorted(self.rq.scenequeue_covered)) |
| 1213 | 1226 | ||
| @@ -1408,6 +1421,7 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1408 | 1421 | ||
| 1409 | self.scenequeue_covered = set() | 1422 | self.scenequeue_covered = set() |
| 1410 | self.scenequeue_notcovered = set() | 1423 | self.scenequeue_notcovered = set() |
| 1424 | self.scenequeue_notneeded = set() | ||
| 1411 | 1425 | ||
| 1412 | # If we don't have any setscene functions, skip this step | 1426 | # If we don't have any setscene functions, skip this step |
| 1413 | if len(self.rqdata.runq_setscene) == 0: | 1427 | if len(self.rqdata.runq_setscene) == 0: |
| @@ -1417,7 +1431,6 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1417 | 1431 | ||
| 1418 | self.stats = RunQueueStats(len(self.rqdata.runq_setscene)) | 1432 | self.stats = RunQueueStats(len(self.rqdata.runq_setscene)) |
| 1419 | 1433 | ||
| 1420 | endpoints = {} | ||
| 1421 | sq_revdeps = [] | 1434 | sq_revdeps = [] |
| 1422 | sq_revdeps_new = [] | 1435 | sq_revdeps_new = [] |
| 1423 | sq_revdeps_squash = [] | 1436 | sq_revdeps_squash = [] |
| @@ -1432,12 +1445,15 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1432 | self.runq_complete.append(0) | 1445 | self.runq_complete.append(0) |
| 1433 | self.runq_buildable.append(0) | 1446 | self.runq_buildable.append(0) |
| 1434 | 1447 | ||
| 1448 | # First process the chains up to the first setscene task. | ||
| 1449 | endpoints = {} | ||
| 1435 | for task in xrange(len(self.rqdata.runq_fnid)): | 1450 | for task in xrange(len(self.rqdata.runq_fnid)): |
| 1436 | sq_revdeps.append(copy.copy(self.rqdata.runq_revdeps[task])) | 1451 | sq_revdeps.append(copy.copy(self.rqdata.runq_revdeps[task])) |
| 1437 | sq_revdeps_new.append(set()) | 1452 | sq_revdeps_new.append(set()) |
| 1438 | if (len(self.rqdata.runq_revdeps[task]) == 0) and task not in self.rqdata.runq_setscene: | 1453 | if (len(self.rqdata.runq_revdeps[task]) == 0) and task not in self.rqdata.runq_setscene: |
| 1439 | endpoints[task] = set() | 1454 | endpoints[task] = set() |
| 1440 | 1455 | ||
| 1456 | # Secondly process the chains between setscene tasks. | ||
| 1441 | for task in self.rqdata.runq_setscene: | 1457 | for task in self.rqdata.runq_setscene: |
| 1442 | for dep in self.rqdata.runq_depends[task]: | 1458 | for dep in self.rqdata.runq_depends[task]: |
| 1443 | if dep not in endpoints: | 1459 | if dep not in endpoints: |
| @@ -1453,6 +1469,8 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1453 | if sq_revdeps_new[point]: | 1469 | if sq_revdeps_new[point]: |
| 1454 | tasks |= sq_revdeps_new[point] | 1470 | tasks |= sq_revdeps_new[point] |
| 1455 | sq_revdeps_new[point] = set() | 1471 | sq_revdeps_new[point] = set() |
| 1472 | if point in self.rqdata.runq_setscene: | ||
| 1473 | sq_revdeps_new[point] = tasks | ||
| 1456 | for dep in self.rqdata.runq_depends[point]: | 1474 | for dep in self.rqdata.runq_depends[point]: |
| 1457 | if point in sq_revdeps[dep]: | 1475 | if point in sq_revdeps[dep]: |
| 1458 | sq_revdeps[dep].remove(point) | 1476 | sq_revdeps[dep].remove(point) |
| @@ -1465,6 +1483,42 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1465 | 1483 | ||
| 1466 | process_endpoints(endpoints) | 1484 | process_endpoints(endpoints) |
| 1467 | 1485 | ||
| 1486 | # Build a list of setscene tasks which as "unskippable" | ||
| 1487 | # These are direct endpoints referenced by the build | ||
| 1488 | endpoints2 = {} | ||
| 1489 | sq_revdeps2 = [] | ||
| 1490 | sq_revdeps_new2 = [] | ||
| 1491 | def process_endpoints2(endpoints): | ||
| 1492 | newendpoints = {} | ||
| 1493 | for point, task in endpoints.items(): | ||
| 1494 | tasks = set([point]) | ||
| 1495 | if task: | ||
| 1496 | tasks |= task | ||
| 1497 | if sq_revdeps_new2[point]: | ||
| 1498 | tasks |= sq_revdeps_new2[point] | ||
| 1499 | sq_revdeps_new2[point] = set() | ||
| 1500 | if point in self.rqdata.runq_setscene: | ||
| 1501 | sq_revdeps_new2[point] = tasks | ||
| 1502 | for dep in self.rqdata.runq_depends[point]: | ||
| 1503 | if point in sq_revdeps2[dep]: | ||
| 1504 | sq_revdeps2[dep].remove(point) | ||
| 1505 | if tasks: | ||
| 1506 | sq_revdeps_new2[dep] |= tasks | ||
| 1507 | if (len(sq_revdeps2[dep]) == 0 or len(sq_revdeps_new2[dep]) != 0) and dep not in self.rqdata.runq_setscene: | ||
| 1508 | newendpoints[dep] = tasks | ||
| 1509 | if len(newendpoints) != 0: | ||
| 1510 | process_endpoints2(newendpoints) | ||
| 1511 | for task in xrange(len(self.rqdata.runq_fnid)): | ||
| 1512 | sq_revdeps2.append(copy.copy(self.rqdata.runq_revdeps[task])) | ||
| 1513 | sq_revdeps_new2.append(set()) | ||
| 1514 | if (len(self.rqdata.runq_revdeps[task]) == 0) and task not in self.rqdata.runq_setscene: | ||
| 1515 | endpoints2[task] = set() | ||
| 1516 | process_endpoints2(endpoints2) | ||
| 1517 | self.unskippable = [] | ||
| 1518 | for task in self.rqdata.runq_setscene: | ||
| 1519 | if sq_revdeps_new2[task]: | ||
| 1520 | self.unskippable.append(self.rqdata.runq_setscene.index(task)) | ||
| 1521 | |||
| 1468 | for task in xrange(len(self.rqdata.runq_fnid)): | 1522 | for task in xrange(len(self.rqdata.runq_fnid)): |
| 1469 | if task in self.rqdata.runq_setscene: | 1523 | if task in self.rqdata.runq_setscene: |
| 1470 | deps = set() | 1524 | deps = set() |
| @@ -1625,6 +1679,13 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1625 | # Find the next setscene to run | 1679 | # Find the next setscene to run |
| 1626 | for nexttask in xrange(self.stats.total): | 1680 | for nexttask in xrange(self.stats.total): |
| 1627 | if self.runq_buildable[nexttask] == 1 and self.runq_running[nexttask] != 1: | 1681 | if self.runq_buildable[nexttask] == 1 and self.runq_running[nexttask] != 1: |
| 1682 | if nexttask in self.unskippable: | ||
| 1683 | logger.debug(2, "Setscene task %s is unskippable" % self.rqdata.get_user_idstring(self.rqdata.runq_setscene[nexttask])) | ||
| 1684 | if nexttask not in self.unskippable and len(self.sq_revdeps[nexttask]) > 0 and self.sq_revdeps[nexttask].issubset(self.scenequeue_covered) and self.check_dependencies(nexttask, self.sq_revdeps[nexttask], True): | ||
| 1685 | logger.debug(2, "Skipping setscene for task %s" % self.rqdata.get_user_idstring(self.rqdata.runq_setscene[nexttask])) | ||
| 1686 | self.task_skip(nexttask) | ||
| 1687 | self.scenequeue_notneeded.add(nexttask) | ||
| 1688 | return True | ||
| 1628 | task = nexttask | 1689 | task = nexttask |
| 1629 | break | 1690 | break |
| 1630 | if task is not None: | 1691 | if task is not None: |
