diff options
Diffstat (limited to 'bitbake-dev')
-rw-r--r-- | bitbake-dev/lib/bb/runqueue.py | 190 |
1 files changed, 75 insertions, 115 deletions
diff --git a/bitbake-dev/lib/bb/runqueue.py b/bitbake-dev/lib/bb/runqueue.py index 4f0996dad6..1be2aa0db2 100644 --- a/bitbake-dev/lib/bb/runqueue.py +++ b/bitbake-dev/lib/bb/runqueue.py | |||
@@ -340,9 +340,10 @@ class RunQueue: | |||
340 | to optimise the execution order. | 340 | to optimise the execution order. |
341 | """ | 341 | """ |
342 | 342 | ||
343 | depends = [] | ||
344 | runq_build = [] | 343 | runq_build = [] |
345 | recursive_tdepends = {} | 344 | recursive_tdepends = {} |
345 | runq_recrdepends = [] | ||
346 | tdepends_fnid = {} | ||
346 | 347 | ||
347 | taskData = self.taskData | 348 | taskData = self.taskData |
348 | 349 | ||
@@ -354,9 +355,9 @@ class RunQueue: | |||
354 | 355 | ||
355 | # Step A - Work out a list of tasks to run | 356 | # Step A - Work out a list of tasks to run |
356 | # | 357 | # |
357 | # Taskdata gives us a list of possible providers for a every target | 358 | # Taskdata gives us a list of possible providers for every build and run |
358 | # ordered by priority (build_targets, run_targets). It also gives | 359 | # target ordered by priority. It also gives information on each of those |
359 | # information on each of those providers. | 360 | # providers. |
360 | # | 361 | # |
361 | # To create the actual list of tasks to execute we fix the list of | 362 | # To create the actual list of tasks to execute we fix the list of |
362 | # providers and then resolve the dependencies into task IDs. This | 363 | # providers and then resolve the dependencies into task IDs. This |
@@ -364,10 +365,14 @@ class RunQueue: | |||
364 | # rdeptast, recrdeptask, idepends). | 365 | # rdeptast, recrdeptask, idepends). |
365 | 366 | ||
366 | for task in range(len(taskData.tasks_name)): | 367 | for task in range(len(taskData.tasks_name)): |
368 | depends = [] | ||
369 | recrdepends = [] | ||
367 | fnid = taskData.tasks_fnid[task] | 370 | fnid = taskData.tasks_fnid[task] |
368 | fn = taskData.fn_index[fnid] | 371 | fn = taskData.fn_index[fnid] |
369 | task_deps = self.dataCache.task_deps[fn] | 372 | task_deps = self.dataCache.task_deps[fn] |
370 | 373 | ||
374 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Processing %s:%s" %(fn, taskData.tasks_name[task])) | ||
375 | |||
371 | if fnid not in taskData.failed_fnids: | 376 | if fnid not in taskData.failed_fnids: |
372 | 377 | ||
373 | # Resolve task internal dependencies | 378 | # Resolve task internal dependencies |
@@ -407,6 +412,8 @@ class RunQueue: | |||
407 | # | 412 | # |
408 | # e.g. do_sometask[depends] = "targetname:do_someothertask" | 413 | # e.g. do_sometask[depends] = "targetname:do_someothertask" |
409 | # (makes sure sometask runs after targetname's someothertask) | 414 | # (makes sure sometask runs after targetname's someothertask) |
415 | if fnid not in tdepends_fnid: | ||
416 | tdepends_fnid[fnid] = set() | ||
410 | idepends = taskData.tasks_idepends[task] | 417 | idepends = taskData.tasks_idepends[task] |
411 | for (depid, idependtask) in idepends: | 418 | for (depid, idependtask) in idepends: |
412 | if depid in taskData.build_targets: | 419 | if depid in taskData.build_targets: |
@@ -414,122 +421,37 @@ class RunQueue: | |||
414 | depdata = taskData.build_targets[depid][0] | 421 | depdata = taskData.build_targets[depid][0] |
415 | if depdata is not None: | 422 | if depdata is not None: |
416 | dep = taskData.fn_index[depdata] | 423 | dep = taskData.fn_index[depdata] |
417 | depends.append(taskData.gettask_id(dep, idependtask)) | 424 | taskid = taskData.gettask_id(dep, idependtask) |
418 | 425 | depends.append(taskid) | |
419 | # Create a list of recursive dependent tasks (from tdepends) and cache | 426 | if depdata != fnid: |
420 | def get_recursive_tdepends(task): | 427 | tdepends_fnid[fnid].add(taskid) |
421 | if not task: | 428 | |
422 | return [] | 429 | |
423 | if task in recursive_tdepends: | 430 | # Resolve recursive 'recrdeptask' dependencies (A) |
424 | return recursive_tdepends[task] | ||
425 | |||
426 | fnid = taskData.tasks_fnid[task] | ||
427 | taskids = taskData.gettask_ids(fnid) | ||
428 | |||
429 | rectdepends = taskids | ||
430 | nextdeps = taskids | ||
431 | while len(nextdeps) != 0: | ||
432 | newdeps = [] | ||
433 | for nextdep in nextdeps: | ||
434 | for tdepend in taskData.tasks_tdepends[nextdep]: | ||
435 | if tdepend not in rectdepends: | ||
436 | rectdepends.append(tdepend) | ||
437 | newdeps.append(tdepend) | ||
438 | nextdeps = newdeps | ||
439 | recursive_tdepends[task] = rectdepends | ||
440 | return rectdepends | ||
441 | |||
442 | # Using the list of tdepends for this task create a list of | ||
443 | # the recursive idepends we have | ||
444 | def get_recursive_idepends(task): | ||
445 | if not task: | ||
446 | return [] | ||
447 | rectdepends = get_recursive_tdepends(task) | ||
448 | |||
449 | recidepends = [] | ||
450 | for tdepend in rectdepends: | ||
451 | for idepend in taskData.tasks_idepends[tdepend]: | ||
452 | recidepends.append(idepend) | ||
453 | return recidepends | ||
454 | |||
455 | def add_recursive_build(depid, depfnid): | ||
456 | """ | ||
457 | Add build depends of depid to depends | ||
458 | (if we've not see it before) | ||
459 | (calls itself recursively) | ||
460 | """ | ||
461 | if str(depid) in dep_seen: | ||
462 | return | ||
463 | dep_seen.append(depid) | ||
464 | if depid in taskData.build_targets: | ||
465 | depdata = taskData.build_targets[depid][0] | ||
466 | if depdata is not None: | ||
467 | dep = taskData.fn_index[depdata] | ||
468 | # Need to avoid creating new tasks here | ||
469 | taskid = taskData.gettask_id(dep, taskname, False) | ||
470 | if taskid is not None: | ||
471 | depends.append(taskid) | ||
472 | fnid = taskData.tasks_fnid[taskid] | ||
473 | #print "Added %s (%s) due to %s" % (taskid, taskData.fn_index[fnid], taskData.fn_index[depfnid]) | ||
474 | else: | ||
475 | fnid = taskData.getfn_id(dep) | ||
476 | for nextdepid in taskData.depids[fnid]: | ||
477 | if nextdepid not in dep_seen: | ||
478 | add_recursive_build(nextdepid, fnid) | ||
479 | for nextdepid in taskData.rdepids[fnid]: | ||
480 | if nextdepid not in rdep_seen: | ||
481 | add_recursive_run(nextdepid, fnid) | ||
482 | for (idependid, idependtask) in get_recursive_idepends(taskid): | ||
483 | if idependid not in dep_seen: | ||
484 | add_recursive_build(idependid, fnid) | ||
485 | |||
486 | def add_recursive_run(rdepid, depfnid): | ||
487 | """ | ||
488 | Add runtime depends of rdepid to depends | ||
489 | (if we've not see it before) | ||
490 | (calls itself recursively) | ||
491 | """ | ||
492 | if str(rdepid) in rdep_seen: | ||
493 | return | ||
494 | rdep_seen.append(rdepid) | ||
495 | if rdepid in taskData.run_targets: | ||
496 | depdata = taskData.run_targets[rdepid][0] | ||
497 | if depdata is not None: | ||
498 | dep = taskData.fn_index[depdata] | ||
499 | # Need to avoid creating new tasks here | ||
500 | taskid = taskData.gettask_id(dep, taskname, False) | ||
501 | if taskid is not None: | ||
502 | depends.append(taskid) | ||
503 | fnid = taskData.tasks_fnid[taskid] | ||
504 | #print "Added %s (%s) due to %s" % (taskid, taskData.fn_index[fnid], taskData.fn_index[depfnid]) | ||
505 | else: | ||
506 | fnid = taskData.getfn_id(dep) | ||
507 | for nextdepid in taskData.depids[fnid]: | ||
508 | if nextdepid not in dep_seen: | ||
509 | add_recursive_build(nextdepid, fnid) | ||
510 | for nextdepid in taskData.rdepids[fnid]: | ||
511 | if nextdepid not in rdep_seen: | ||
512 | add_recursive_run(nextdepid, fnid) | ||
513 | for (idependid, idependtask) in get_recursive_idepends(taskid): | ||
514 | if idependid not in dep_seen: | ||
515 | add_recursive_build(idependid, fnid) | ||
516 | |||
517 | # Resolve recursive 'recrdeptask' dependencies | ||
518 | # | 431 | # |
519 | # e.g. do_sometask[recrdeptask] = "do_someothertask" | 432 | # e.g. do_sometask[recrdeptask] = "do_someothertask" |
520 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) | 433 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) |
434 | # We cover the recursive part of the dependencies below | ||
521 | if 'recrdeptask' in task_deps and taskData.tasks_name[task] in task_deps['recrdeptask']: | 435 | if 'recrdeptask' in task_deps and taskData.tasks_name[task] in task_deps['recrdeptask']: |
522 | for taskname in task_deps['recrdeptask'][taskData.tasks_name[task]].split(): | 436 | for taskname in task_deps['recrdeptask'][taskData.tasks_name[task]].split(): |
523 | dep_seen = [] | 437 | recrdepends.append(taskname) |
524 | rdep_seen = [] | 438 | for depid in taskData.rdepids[fnid]: |
525 | idep_seen = [] | 439 | if depid in taskData.run_targets: |
440 | depdata = taskData.run_targets[depid][0] | ||
441 | if depdata is not None: | ||
442 | dep = taskData.fn_index[depdata] | ||
443 | taskid = taskData.gettask_id(dep, taskname, False) | ||
444 | if taskid is not None: | ||
445 | depends.append(taskid) | ||
526 | for depid in taskData.depids[fnid]: | 446 | for depid in taskData.depids[fnid]: |
527 | add_recursive_build(depid, fnid) | 447 | # Won't be in build_targets if ASSUME_PROVIDED |
528 | for rdepid in taskData.rdepids[fnid]: | 448 | if depid in taskData.build_targets: |
529 | add_recursive_run(rdepid, fnid) | 449 | depdata = taskData.build_targets[depid][0] |
530 | deptaskid = taskData.gettask_id(fn, taskname, False) | 450 | if depdata is not None: |
531 | for (idependid, idependtask) in get_recursive_idepends(deptaskid): | 451 | dep = taskData.fn_index[depdata] |
532 | add_recursive_build(idependid, fnid) | 452 | taskid = taskData.gettask_id(dep, taskname, False) |
453 | if taskid is not None: | ||
454 | depends.append(taskid) | ||
533 | 455 | ||
534 | # Rmove all self references | 456 | # Rmove all self references |
535 | if task in depends: | 457 | if task in depends: |
@@ -540,13 +462,51 @@ class RunQueue: | |||
540 | newdep.append(dep) | 462 | newdep.append(dep) |
541 | depends = newdep | 463 | depends = newdep |
542 | 464 | ||
543 | |||
544 | self.runq_fnid.append(taskData.tasks_fnid[task]) | 465 | self.runq_fnid.append(taskData.tasks_fnid[task]) |
545 | self.runq_task.append(taskData.tasks_name[task]) | 466 | self.runq_task.append(taskData.tasks_name[task]) |
546 | self.runq_depends.append(set(depends)) | 467 | self.runq_depends.append(set(depends)) |
547 | self.runq_revdeps.append(set()) | 468 | self.runq_revdeps.append(set()) |
548 | 469 | ||
549 | runq_build.append(0) | 470 | runq_build.append(0) |
471 | runq_recrdepends.append(recrdepends) | ||
472 | |||
473 | # | ||
474 | # Build a list of recursive cumulative dependencies for each fnid | ||
475 | # We do this by fnid, since if A depends on some task in B | ||
476 | # we're interested in later tasks B's fnid might have but B itself | ||
477 | # doesn't depend on | ||
478 | # | ||
479 | # Algorithm is O(tasks) + O(tasks)*O(fnids) | ||
480 | # | ||
481 | reccumdepends = {} | ||
482 | for task in range(len(self.runq_fnid)): | ||
483 | fnid = self.runq_fnid[task] | ||
484 | if fnid not in reccumdepends: | ||
485 | reccumdepends[fnid] = set() | ||
486 | if task in self.runq_depends: | ||
487 | reccumdepends[fnid].update(self.runq_depends[task]) | ||
488 | if fnid in tdepends_fnid: | ||
489 | reccumdepends[fnid].update(tdepends_fnid[fnid]) | ||
490 | for task in range(len(self.runq_fnid)): | ||
491 | taskfnid = self.runq_fnid[task] | ||
492 | for fnid in reccumdepends: | ||
493 | if task in reccumdepends[fnid]: | ||
494 | reccumdepends[fnid].add(task) | ||
495 | if taskfnid in reccumdepends: | ||
496 | reccumdepends[fnid].update(reccumdepends[taskfnid]) | ||
497 | |||
498 | |||
499 | # Resolve recursive 'recrdeptask' dependencies (B) | ||
500 | # | ||
501 | # e.g. do_sometask[recrdeptask] = "do_someothertask" | ||
502 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) | ||
503 | for task in range(len(self.runq_fnid)): | ||
504 | if len(runq_recrdepends[task]) > 0: | ||
505 | taskfnid = self.runq_fnid[task] | ||
506 | for dep in reccumdepends[taskfnid]: | ||
507 | for taskname in runq_recrdepends[task]: | ||
508 | if taskData.tasks_name[dep] == taskname: | ||
509 | self.runq_depends[task].add(dep) | ||
550 | 510 | ||
551 | # Step B - Mark all active tasks | 511 | # Step B - Mark all active tasks |
552 | # | 512 | # |