diff options
| author | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-18 11:30:53 +0100 |
|---|---|---|
| committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-18 11:49:58 +0100 |
| commit | 5d9f37873d88a33cc0f1c326a2cb0c2ff673a3a6 (patch) | |
| tree | f9a0a5c3c0a0ffd6084824e95f0fc863898098ee /bitbake/lib/bb/runqueue.py | |
| parent | d7bc9b8ecec524294cc9143fd0b349249b329891 (diff) | |
| download | poky-5d9f37873d88a33cc0f1c326a2cb0c2ff673a3a6.tar.gz | |
bitbake: Split Runqueue into two classes, a data processor and the execution part
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 221 |
1 files changed, 116 insertions, 105 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index bdd806a2c1..c25adc37fa 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -76,12 +76,13 @@ class RunQueueScheduler(object): | |||
| 76 | """ | 76 | """ |
| 77 | name = "basic" | 77 | name = "basic" |
| 78 | 78 | ||
| 79 | def __init__(self, runqueue): | 79 | def __init__(self, runqueue, rqdata): |
| 80 | """ | 80 | """ |
| 81 | The default scheduler just returns the first buildable task (the | 81 | The default scheduler just returns the first buildable task (the |
| 82 | priority map is sorted by task numer) | 82 | priority map is sorted by task numer) |
| 83 | """ | 83 | """ |
| 84 | self.rq = runqueue | 84 | self.rq = runqueue |
| 85 | self.rqdata = rqdata | ||
| 85 | numTasks = len(self.rq.runq_fnid) | 86 | numTasks = len(self.rq.runq_fnid) |
| 86 | 87 | ||
| 87 | self.prio_map = [] | 88 | self.prio_map = [] |
| @@ -91,7 +92,7 @@ class RunQueueScheduler(object): | |||
| 91 | """ | 92 | """ |
| 92 | Return the id of the first task we find that is buildable | 93 | Return the id of the first task we find that is buildable |
| 93 | """ | 94 | """ |
| 94 | for task1 in range(len(self.rq.runq_fnid)): | 95 | for task1 in range(len(self.rqdata.runq_fnid)): |
| 95 | task = self.prio_map[task1] | 96 | task = self.prio_map[task1] |
| 96 | if self.rq.runq_running[task] == 1: | 97 | if self.rq.runq_running[task] == 1: |
| 97 | continue | 98 | continue |
| @@ -105,16 +106,17 @@ class RunQueueSchedulerSpeed(RunQueueScheduler): | |||
| 105 | """ | 106 | """ |
| 106 | name = "speed" | 107 | name = "speed" |
| 107 | 108 | ||
| 108 | def __init__(self, runqueue): | 109 | def __init__(self, runqueue, rqdata): |
| 109 | """ | 110 | """ |
| 110 | The priority map is sorted by task weight. | 111 | The priority map is sorted by task weight. |
| 111 | """ | 112 | """ |
| 112 | from copy import deepcopy | 113 | from copy import deepcopy |
| 113 | 114 | ||
| 114 | self.rq = runqueue | 115 | self.rq = runqueue |
| 116 | self.rqdata = rqdata | ||
| 115 | 117 | ||
| 116 | sortweight = sorted(deepcopy(self.rq.runq_weight)) | 118 | sortweight = sorted(deepcopy(self.rqdata.runq_weight)) |
| 117 | copyweight = deepcopy(self.rq.runq_weight) | 119 | copyweight = deepcopy(self.rqdata.runq_weight) |
| 118 | self.prio_map = [] | 120 | self.prio_map = [] |
| 119 | 121 | ||
| 120 | for weight in sortweight: | 122 | for weight in sortweight: |
| @@ -134,8 +136,8 @@ class RunQueueSchedulerCompletion(RunQueueSchedulerSpeed): | |||
| 134 | """ | 136 | """ |
| 135 | name = "completion" | 137 | name = "completion" |
| 136 | 138 | ||
| 137 | def __init__(self, runqueue): | 139 | def __init__(self, runqueue, rqdata): |
| 138 | RunQueueSchedulerSpeed.__init__(self, runqueue) | 140 | RunQueueSchedulerSpeed.__init__(self, runqueue, rqdata) |
| 139 | from copy import deepcopy | 141 | from copy import deepcopy |
| 140 | 142 | ||
| 141 | #FIXME - whilst this groups all fnids together it does not reorder the | 143 | #FIXME - whilst this groups all fnids together it does not reorder the |
| @@ -146,10 +148,10 @@ class RunQueueSchedulerCompletion(RunQueueSchedulerSpeed): | |||
| 146 | while (len(basemap) > 0): | 148 | while (len(basemap) > 0): |
| 147 | entry = basemap.pop(0) | 149 | entry = basemap.pop(0) |
| 148 | self.prio_map.append(entry) | 150 | self.prio_map.append(entry) |
| 149 | fnid = self.rq.runq_fnid[entry] | 151 | fnid = self.rqdata.runq_fnid[entry] |
| 150 | todel = [] | 152 | todel = [] |
| 151 | for entry in basemap: | 153 | for entry in basemap: |
| 152 | entry_fnid = self.rq.runq_fnid[entry] | 154 | entry_fnid = self.rqdata.runq_fnid[entry] |
| 153 | if entry_fnid == fnid: | 155 | if entry_fnid == fnid: |
| 154 | todel.append(basemap.index(entry)) | 156 | todel.append(basemap.index(entry)) |
| 155 | self.prio_map.append(entry) | 157 | self.prio_map.append(entry) |
| @@ -157,30 +159,27 @@ class RunQueueSchedulerCompletion(RunQueueSchedulerSpeed): | |||
| 157 | for idx in todel: | 159 | for idx in todel: |
| 158 | del basemap[idx] | 160 | del basemap[idx] |
| 159 | 161 | ||
| 160 | class RunQueue: | 162 | class RunQueueData: |
| 161 | """ | 163 | """ |
| 162 | BitBake Run Queue implementation | 164 | BitBake Run Queue implementation |
| 163 | """ | 165 | """ |
| 164 | def __init__(self, cooker, cfgData, dataCache, taskData, targets): | 166 | def __init__(self, rq, cooker, cfgData, dataCache, taskData, targets): |
| 165 | self.reset_runqueue() | ||
| 166 | self.cooker = cooker | 167 | self.cooker = cooker |
| 167 | self.dataCache = dataCache | 168 | self.dataCache = dataCache |
| 168 | self.taskData = taskData | 169 | self.taskData = taskData |
| 169 | self.cfgData = cfgData | ||
| 170 | self.targets = targets | 170 | self.targets = targets |
| 171 | self.rq = rq | ||
| 171 | 172 | ||
| 172 | self.number_tasks = int(bb.data.getVar("BB_NUMBER_THREADS", cfgData, 1) or 1) | ||
| 173 | self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData, 1) or "").split() | ||
| 174 | self.scheduler = bb.data.getVar("BB_SCHEDULER", cfgData, 1) or "speed" | ||
| 175 | self.stamppolicy = bb.data.getVar("BB_STAMP_POLICY", cfgData, 1) or "perfile" | ||
| 176 | self.stampwhitelist = bb.data.getVar("BB_STAMP_WHITELIST", cfgData, 1) or "" | 173 | self.stampwhitelist = bb.data.getVar("BB_STAMP_WHITELIST", cfgData, 1) or "" |
| 174 | self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData, 1) or "").split() | ||
| 175 | |||
| 176 | self.reset() | ||
| 177 | 177 | ||
| 178 | def reset_runqueue(self): | 178 | def reset(self): |
| 179 | self.runq_fnid = [] | 179 | self.runq_fnid = [] |
| 180 | self.runq_task = [] | 180 | self.runq_task = [] |
| 181 | self.runq_depends = [] | 181 | self.runq_depends = [] |
| 182 | self.runq_revdeps = [] | 182 | self.runq_revdeps = [] |
| 183 | self.state = runQueuePrepare | ||
| 184 | 183 | ||
| 185 | def runq_depends_names(self, ids): | 184 | def runq_depends_names(self, ids): |
| 186 | import re | 185 | import re |
| @@ -348,7 +347,7 @@ class RunQueue: | |||
| 348 | 347 | ||
| 349 | return weight | 348 | return weight |
| 350 | 349 | ||
| 351 | def prepare_runqueue(self): | 350 | def prepare(self): |
| 352 | """ | 351 | """ |
| 353 | Turn a set of taskData into a RunQueue and compute data needed | 352 | Turn a set of taskData into a RunQueue and compute data needed |
| 354 | to optimise the execution order. | 353 | to optimise the execution order. |
| @@ -644,17 +643,6 @@ class RunQueue: | |||
| 644 | # Check of higher length circular dependencies | 643 | # Check of higher length circular dependencies |
| 645 | self.runq_weight = self.calculate_task_weights(endpoints) | 644 | self.runq_weight = self.calculate_task_weights(endpoints) |
| 646 | 645 | ||
| 647 | schedulers = [obj for obj in globals().itervalues() | ||
| 648 | if type(obj) is type and issubclass(obj, RunQueueScheduler)] | ||
| 649 | for scheduler in schedulers: | ||
| 650 | if self.scheduler == scheduler.name: | ||
| 651 | self.sched = scheduler(self) | ||
| 652 | break | ||
| 653 | else: | ||
| 654 | bb.error("Invalid scheduler '%s', using default 'speed' scheduler" % self.scheduler) | ||
| 655 | bb.error("Available schedulers: %s" % ", ".join(obj.name for obj in schedulers)) | ||
| 656 | self.sched = RunQueueSchedulerSpeed(self) | ||
| 657 | |||
| 658 | # Sanity Check - Check for multiple tasks building the same provider | 646 | # Sanity Check - Check for multiple tasks building the same provider |
| 659 | prov_list = {} | 647 | prov_list = {} |
| 660 | seen_fn = [] | 648 | seen_fn = [] |
| @@ -690,7 +678,43 @@ class RunQueue: | |||
| 690 | 678 | ||
| 691 | #self.dump_data(taskData) | 679 | #self.dump_data(taskData) |
| 692 | 680 | ||
| 693 | self.state = runQueueRunInit | 681 | def dump_data(self, taskQueue): |
| 682 | """ | ||
| 683 | Dump some debug information on the internal data structures | ||
| 684 | """ | ||
| 685 | bb.msg.debug(3, bb.msg.domain.RunQueue, "run_tasks:") | ||
| 686 | for task in range(len(self.rqdata.runq_task)): | ||
| 687 | bb.msg.debug(3, bb.msg.domain.RunQueue, " (%s)%s - %s: %s Deps %s RevDeps %s" % (task, | ||
| 688 | taskQueue.fn_index[self.rqdata.runq_fnid[task]], | ||
| 689 | self.rqdata.runq_task[task], | ||
| 690 | self.rqdata.runq_weight[task], | ||
| 691 | self.rqdata.runq_depends[task], | ||
| 692 | self.rqdata.runq_revdeps[task])) | ||
| 693 | |||
| 694 | bb.msg.debug(3, bb.msg.domain.RunQueue, "sorted_tasks:") | ||
| 695 | for task1 in range(len(self.rqdata.runq_task)): | ||
| 696 | if task1 in self.prio_map: | ||
| 697 | task = self.prio_map[task1] | ||
| 698 | bb.msg.debug(3, bb.msg.domain.RunQueue, " (%s)%s - %s: %s Deps %s RevDeps %s" % (task, | ||
| 699 | taskQueue.fn_index[self.rqdata.runq_fnid[task]], | ||
| 700 | self.rqdata.runq_task[task], | ||
| 701 | self.rqdata.runq_weight[task], | ||
| 702 | self.rqdata.runq_depends[task], | ||
| 703 | self.rqdata.runq_revdeps[task])) | ||
| 704 | |||
| 705 | |||
| 706 | class RunQueue: | ||
| 707 | def __init__(self, cooker, cfgData, dataCache, taskData, targets): | ||
| 708 | |||
| 709 | self.cooker = cooker | ||
| 710 | self.cfgData = cfgData | ||
| 711 | self.rqdata = RunQueueData(self, cooker, cfgData, dataCache, taskData, targets) | ||
| 712 | |||
| 713 | self.number_tasks = int(bb.data.getVar("BB_NUMBER_THREADS", cfgData, 1) or 1) | ||
| 714 | self.scheduler = bb.data.getVar("BB_SCHEDULER", cfgData, 1) or "speed" | ||
| 715 | self.stamppolicy = bb.data.getVar("BB_STAMP_POLICY", cfgData, 1) or "perfile" | ||
| 716 | |||
| 717 | self.state = runQueuePrepare | ||
| 694 | 718 | ||
| 695 | def check_stamps(self): | 719 | def check_stamps(self): |
| 696 | unchecked = {} | 720 | unchecked = {} |
| @@ -704,29 +728,29 @@ class RunQueue: | |||
| 704 | fulldeptree = True | 728 | fulldeptree = True |
| 705 | stampwhitelist = [] | 729 | stampwhitelist = [] |
| 706 | if self.stamppolicy == "whitelist": | 730 | if self.stamppolicy == "whitelist": |
| 707 | stampwhitelist = self.self.stampfnwhitelist | 731 | stampwhitelist = self.rqdata.stampfnwhitelist |
| 708 | 732 | ||
| 709 | for task in range(len(self.runq_fnid)): | 733 | for task in range(len(self.rqdata.runq_fnid)): |
| 710 | unchecked[task] = "" | 734 | unchecked[task] = "" |
| 711 | if len(self.runq_depends[task]) == 0: | 735 | if len(self.rqdata.runq_depends[task]) == 0: |
| 712 | buildable.append(task) | 736 | buildable.append(task) |
| 713 | 737 | ||
| 714 | def check_buildable(self, task, buildable): | 738 | def check_buildable(self, task, buildable): |
| 715 | for revdep in self.runq_revdeps[task]: | 739 | for revdep in self.rqdata.runq_revdeps[task]: |
| 716 | alldeps = 1 | 740 | alldeps = 1 |
| 717 | for dep in self.runq_depends[revdep]: | 741 | for dep in self.rqdata.runq_depends[revdep]: |
| 718 | if dep in unchecked: | 742 | if dep in unchecked: |
| 719 | alldeps = 0 | 743 | alldeps = 0 |
| 720 | if alldeps == 1: | 744 | if alldeps == 1: |
| 721 | if revdep in unchecked: | 745 | if revdep in unchecked: |
| 722 | buildable.append(revdep) | 746 | buildable.append(revdep) |
| 723 | 747 | ||
| 724 | for task in range(len(self.runq_fnid)): | 748 | for task in range(len(self.rqdata.runq_fnid)): |
| 725 | if task not in unchecked: | 749 | if task not in unchecked: |
| 726 | continue | 750 | continue |
| 727 | fn = self.taskData.fn_index[self.runq_fnid[task]] | 751 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 728 | taskname = self.runq_task[task] | 752 | taskname = self.rqdata.runq_task[task] |
| 729 | stampfile = "%s.%s" % (self.dataCache.stamp[fn], taskname) | 753 | stampfile = "%s.%s" % (self.rqdata.dataCache.stamp[fn], taskname) |
| 730 | # If the stamp is missing its not current | 754 | # If the stamp is missing its not current |
| 731 | if not os.access(stampfile, os.F_OK): | 755 | if not os.access(stampfile, os.F_OK): |
| 732 | del unchecked[task] | 756 | del unchecked[task] |
| @@ -734,7 +758,7 @@ class RunQueue: | |||
| 734 | check_buildable(self, task, buildable) | 758 | check_buildable(self, task, buildable) |
| 735 | continue | 759 | continue |
| 736 | # If its a 'nostamp' task, it's not current | 760 | # If its a 'nostamp' task, it's not current |
| 737 | taskdep = self.dataCache.task_deps[fn] | 761 | taskdep = self.rqdata.dataCache.task_deps[fn] |
| 738 | if 'nostamp' in taskdep and task in taskdep['nostamp']: | 762 | if 'nostamp' in taskdep and task in taskdep['nostamp']: |
| 739 | del unchecked[task] | 763 | del unchecked[task] |
| 740 | notcurrent.append(task) | 764 | notcurrent.append(task) |
| @@ -745,17 +769,17 @@ class RunQueue: | |||
| 745 | nextbuildable = [] | 769 | nextbuildable = [] |
| 746 | for task in buildable: | 770 | for task in buildable: |
| 747 | if task in unchecked: | 771 | if task in unchecked: |
| 748 | fn = self.taskData.fn_index[self.runq_fnid[task]] | 772 | fn = self.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 749 | taskname = self.runq_task[task] | 773 | taskname = self.rqdata.runq_task[task] |
| 750 | stampfile = "%s.%s" % (self.dataCache.stamp[fn], taskname) | 774 | stampfile = "%s.%s" % (self.rqdata.dataCache.stamp[fn], taskname) |
| 751 | iscurrent = True | 775 | iscurrent = True |
| 752 | 776 | ||
| 753 | t1 = os.stat(stampfile)[stat.ST_MTIME] | 777 | t1 = os.stat(stampfile)[stat.ST_MTIME] |
| 754 | for dep in self.runq_depends[task]: | 778 | for dep in self.rqdata.runq_depends[task]: |
| 755 | if iscurrent: | 779 | if iscurrent: |
| 756 | fn2 = self.taskData.fn_index[self.runq_fnid[dep]] | 780 | fn2 = self.taskData.fn_index[self.rqdata.runq_fnid[dep]] |
| 757 | taskname2 = self.runq_task[dep] | 781 | taskname2 = self.rqdata.runq_task[dep] |
| 758 | stampfile2 = "%s.%s" % (self.dataCache.stamp[fn2], taskname2) | 782 | stampfile2 = "%s.%s" % (self.rqdata.dataCache.stamp[fn2], taskname2) |
| 759 | if fn == fn2 or (fulldeptree and fn2 not in stampwhitelist): | 783 | if fn == fn2 or (fulldeptree and fn2 not in stampwhitelist): |
| 760 | if dep in notcurrent: | 784 | if dep in notcurrent: |
| 761 | iscurrent = False | 785 | iscurrent = False |
| @@ -794,29 +818,29 @@ class RunQueue: | |||
| 794 | fulldeptree = True | 818 | fulldeptree = True |
| 795 | stampwhitelist = [] | 819 | stampwhitelist = [] |
| 796 | if self.stamppolicy == "whitelist": | 820 | if self.stamppolicy == "whitelist": |
| 797 | stampwhitelist = self.stampfnwhitelist | 821 | stampwhitelist = self.rqdata.stampfnwhitelist |
| 798 | 822 | ||
| 799 | fn = self.taskData.fn_index[self.runq_fnid[task]] | 823 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 800 | if taskname is None: | 824 | if taskname is None: |
| 801 | taskname = self.runq_task[task] | 825 | taskname = self.rqdata.runq_task[task] |
| 802 | stampfile = "%s.%s" % (self.dataCache.stamp[fn], taskname) | 826 | stampfile = "%s.%s" % (self.rqdata.dataCache.stamp[fn], taskname) |
| 803 | # If the stamp is missing its not current | 827 | # If the stamp is missing its not current |
| 804 | if not os.access(stampfile, os.F_OK): | 828 | if not os.access(stampfile, os.F_OK): |
| 805 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stampfile %s not available\n" % stampfile) | 829 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stampfile %s not available\n" % stampfile) |
| 806 | return False | 830 | return False |
| 807 | # If its a 'nostamp' task, it's not current | 831 | # If its a 'nostamp' task, it's not current |
| 808 | taskdep = self.dataCache.task_deps[fn] | 832 | taskdep = self.rqdata.dataCache.task_deps[fn] |
| 809 | if 'nostamp' in taskdep and taskname in taskdep['nostamp']: | 833 | if 'nostamp' in taskdep and taskname in taskdep['nostamp']: |
| 810 | bb.msg.debug(2, bb.msg.domain.RunQueue, "%s.%s is nostamp\n" % (fn, taskname)) | 834 | bb.msg.debug(2, bb.msg.domain.RunQueue, "%s.%s is nostamp\n" % (fn, taskname)) |
| 811 | return False | 835 | return False |
| 812 | 836 | ||
| 813 | iscurrent = True | 837 | iscurrent = True |
| 814 | t1 = os.stat(stampfile)[stat.ST_MTIME] | 838 | t1 = os.stat(stampfile)[stat.ST_MTIME] |
| 815 | for dep in self.runq_depends[task]: | 839 | for dep in self.rqdata.runq_depends[task]: |
| 816 | if iscurrent: | 840 | if iscurrent: |
| 817 | fn2 = self.taskData.fn_index[self.runq_fnid[dep]] | 841 | fn2 = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[dep]] |
| 818 | taskname2 = self.runq_task[dep] | 842 | taskname2 = self.rqdata.runq_task[dep] |
| 819 | stampfile2 = "%s.%s" % (self.dataCache.stamp[fn2], taskname2) | 843 | stampfile2 = "%s.%s" % (self.rqdata.dataCache.stamp[fn2], taskname2) |
| 820 | if fn == fn2 or (fulldeptree and fn2 not in stampwhitelist): | 844 | if fn == fn2 or (fulldeptree and fn2 not in stampwhitelist): |
| 821 | try: | 845 | try: |
| 822 | t2 = os.stat(stampfile2)[stat.ST_MTIME] | 846 | t2 = os.stat(stampfile2)[stat.ST_MTIME] |
| @@ -831,13 +855,14 @@ class RunQueue: | |||
| 831 | 855 | ||
| 832 | def execute_runqueue(self): | 856 | def execute_runqueue(self): |
| 833 | """ | 857 | """ |
| 834 | Run the tasks in a queue prepared by prepare_runqueue | 858 | Run the tasks in a queue prepared by rqdata.prepare() |
| 835 | Upon failure, optionally try to recover the build using any alternate providers | 859 | Upon failure, optionally try to recover the build using any alternate providers |
| 836 | (if the abort on failure configuration option isn't set) | 860 | (if the abort on failure configuration option isn't set) |
| 837 | """ | 861 | """ |
| 838 | 862 | ||
| 839 | if self.state is runQueuePrepare: | 863 | if self.state is runQueuePrepare: |
| 840 | self.prepare_runqueue() | 864 | self.rqdata.prepare() |
| 865 | self.state = runQueueRunInit | ||
| 841 | 866 | ||
| 842 | if self.state is runQueueRunInit: | 867 | if self.state is runQueueRunInit: |
| 843 | bb.msg.note(1, bb.msg.domain.RunQueue, "Executing runqueue") | 868 | bb.msg.note(1, bb.msg.domain.RunQueue, "Executing runqueue") |
| @@ -850,11 +875,11 @@ class RunQueue: | |||
| 850 | self.finish_runqueue() | 875 | self.finish_runqueue() |
| 851 | 876 | ||
| 852 | if self.state is runQueueFailed: | 877 | if self.state is runQueueFailed: |
| 853 | if not self.taskData.tryaltconfigs: | 878 | if not self.rqdata.taskData.tryaltconfigs: |
| 854 | raise bb.runqueue.TaskFailure(self.failed_fnids) | 879 | raise bb.runqueue.TaskFailure(self.failed_fnids) |
| 855 | for fnid in self.failed_fnids: | 880 | for fnid in self.failed_fnids: |
| 856 | self.taskData.fail_fnid(fnid) | 881 | self.rqdata.taskData.fail_fnid(fnid) |
| 857 | self.reset_runqueue() | 882 | self.rqdata.reset() |
| 858 | 883 | ||
| 859 | if self.state is runQueueComplete: | 884 | if self.state is runQueueComplete: |
| 860 | # All done | 885 | # All done |
| @@ -870,7 +895,7 @@ class RunQueue: | |||
| 870 | 895 | ||
| 871 | def execute_runqueue_initVars(self): | 896 | def execute_runqueue_initVars(self): |
| 872 | 897 | ||
| 873 | self.stats = RunQueueStats(len(self.runq_fnid)) | 898 | self.stats = RunQueueStats(len(self.rqdata.runq_fnid)) |
| 874 | 899 | ||
| 875 | self.runq_buildable = [] | 900 | self.runq_buildable = [] |
| 876 | self.runq_running = [] | 901 | self.runq_running = [] |
| @@ -883,14 +908,25 @@ class RunQueue: | |||
| 883 | for task in range(self.stats.total): | 908 | for task in range(self.stats.total): |
| 884 | self.runq_running.append(0) | 909 | self.runq_running.append(0) |
| 885 | self.runq_complete.append(0) | 910 | self.runq_complete.append(0) |
| 886 | if len(self.runq_depends[task]) == 0: | 911 | if len(self.rqdata.runq_depends[task]) == 0: |
| 887 | self.runq_buildable.append(1) | 912 | self.runq_buildable.append(1) |
| 888 | else: | 913 | else: |
| 889 | self.runq_buildable.append(0) | 914 | self.runq_buildable.append(0) |
| 890 | 915 | ||
| 891 | self.state = runQueueRunning | 916 | self.state = runQueueRunning |
| 892 | 917 | ||
| 893 | event.fire(bb.event.StampUpdate(self.target_pairs, self.dataCache.stamp), self.cfgData) | 918 | event.fire(bb.event.StampUpdate(self.rqdata.target_pairs, self.rqdata.dataCache.stamp), self.cfgData) |
| 919 | |||
| 920 | schedulers = [obj for obj in globals().itervalues() | ||
| 921 | if type(obj) is type and issubclass(obj, RunQueueScheduler)] | ||
| 922 | for scheduler in schedulers: | ||
| 923 | if self.scheduler == scheduler.name: | ||
| 924 | self.sched = scheduler(self, self.rqdata) | ||
| 925 | break | ||
| 926 | else: | ||
| 927 | bb.error("Invalid scheduler '%s', using default 'speed' scheduler" % self.scheduler) | ||
| 928 | bb.error("Available schedulers: %s" % ", ".join(obj.name for obj in schedulers)) | ||
| 929 | self.sched = RunQueueSchedulerSpeed(self, self.rqdata) | ||
| 894 | 930 | ||
| 895 | def task_complete(self, task): | 931 | def task_complete(self, task): |
| 896 | """ | 932 | """ |
| @@ -899,19 +935,19 @@ class RunQueue: | |||
| 899 | completed dependencies as buildable | 935 | completed dependencies as buildable |
| 900 | """ | 936 | """ |
| 901 | self.runq_complete[task] = 1 | 937 | self.runq_complete[task] = 1 |
| 902 | for revdep in self.runq_revdeps[task]: | 938 | for revdep in self.rqdata.runq_revdeps[task]: |
| 903 | if self.runq_running[revdep] == 1: | 939 | if self.runq_running[revdep] == 1: |
| 904 | continue | 940 | continue |
| 905 | if self.runq_buildable[revdep] == 1: | 941 | if self.runq_buildable[revdep] == 1: |
| 906 | continue | 942 | continue |
| 907 | alldeps = 1 | 943 | alldeps = 1 |
| 908 | for dep in self.runq_depends[revdep]: | 944 | for dep in self.rqdata.runq_depends[revdep]: |
| 909 | if self.runq_complete[dep] != 1: | 945 | if self.runq_complete[dep] != 1: |
| 910 | alldeps = 0 | 946 | alldeps = 0 |
| 911 | if alldeps == 1: | 947 | if alldeps == 1: |
| 912 | self.runq_buildable[revdep] = 1 | 948 | self.runq_buildable[revdep] = 1 |
| 913 | fn = self.taskData.fn_index[self.runq_fnid[revdep]] | 949 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[revdep]] |
| 914 | taskname = self.runq_task[revdep] | 950 | taskname = self.rqdata.runq_task[revdep] |
| 915 | bb.msg.debug(1, bb.msg.domain.RunQueue, "Marking task %s (%s, %s) as buildable" % (revdep, fn, taskname)) | 951 | bb.msg.debug(1, bb.msg.domain.RunQueue, "Marking task %s (%s, %s) as buildable" % (revdep, fn, taskname)) |
| 916 | 952 | ||
| 917 | def task_fail(self, task, exitcode): | 953 | def task_fail(self, task, exitcode): |
| @@ -919,17 +955,17 @@ class RunQueue: | |||
| 919 | Called when a task has failed | 955 | Called when a task has failed |
| 920 | Updates the state engine with the failure | 956 | Updates the state engine with the failure |
| 921 | """ | 957 | """ |
| 922 | bb.msg.error(bb.msg.domain.RunQueue, "Task %s (%s) failed with %s" % (task, self.get_user_idstring(task), exitcode)) | 958 | bb.msg.error(bb.msg.domain.RunQueue, "Task %s (%s) failed with %s" % (task, self.rqdata.get_user_idstring(task), exitcode)) |
| 923 | self.stats.taskFailed() | 959 | self.stats.taskFailed() |
| 924 | fnid = self.runq_fnid[task] | 960 | fnid = self.rqdata.runq_fnid[task] |
| 925 | self.failed_fnids.append(fnid) | 961 | self.failed_fnids.append(fnid) |
| 926 | bb.event.fire(runQueueTaskFailed(task, self.stats, self), self.cfgData) | 962 | bb.event.fire(runQueueTaskFailed(task, self.stats, self), self.cfgData) |
| 927 | if self.taskData.abort: | 963 | if self.rqdata.taskData.abort: |
| 928 | self.state = runQueueCleanUp | 964 | self.state = runQueueCleanUp |
| 929 | 965 | ||
| 930 | def execute_runqueue_internal(self): | 966 | def execute_runqueue_internal(self): |
| 931 | """ | 967 | """ |
| 932 | Run the tasks in a queue prepared by prepare_runqueue | 968 | Run the tasks in a queue prepared by rqdata.prepare() |
| 933 | """ | 969 | """ |
| 934 | 970 | ||
| 935 | if self.stats.total == 0: | 971 | if self.stats.total == 0: |
| @@ -941,11 +977,11 @@ class RunQueue: | |||
| 941 | if self.stats.active < self.number_tasks: | 977 | if self.stats.active < self.number_tasks: |
| 942 | task = self.sched.next() | 978 | task = self.sched.next() |
| 943 | if task is not None: | 979 | if task is not None: |
| 944 | fn = self.taskData.fn_index[self.runq_fnid[task]] | 980 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 945 | 981 | ||
| 946 | taskname = self.runq_task[task] | 982 | taskname = self.rqdata.runq_task[task] |
| 947 | if self.check_stamp_task(task, taskname): | 983 | if self.check_stamp_task(task, taskname): |
| 948 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task))) | 984 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.rqdata.get_user_idstring(task))) |
| 949 | self.runq_running[task] = 1 | 985 | self.runq_running[task] = 1 |
| 950 | self.runq_buildable[task] = 1 | 986 | self.runq_buildable[task] = 1 |
| 951 | self.task_complete(task) | 987 | self.task_complete(task) |
| @@ -1072,7 +1108,7 @@ class RunQueue: | |||
| 1072 | "Running task %d of %d (ID: %s, %s)" % (self.stats.completed + self.stats.active + self.stats.failed + 1, | 1108 | "Running task %d of %d (ID: %s, %s)" % (self.stats.completed + self.stats.active + self.stats.failed + 1, |
| 1073 | self.stats.total, | 1109 | self.stats.total, |
| 1074 | task, | 1110 | task, |
| 1075 | self.get_user_idstring(task))) | 1111 | self.rqdata.get_user_idstring(task))) |
| 1076 | 1112 | ||
| 1077 | bb.data.setVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY", self, self.cooker.configuration.data) | 1113 | bb.data.setVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY", self, self.cooker.configuration.data) |
| 1078 | bb.data.setVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY2", fn, self.cooker.configuration.data) | 1114 | bb.data.setVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY2", fn, self.cooker.configuration.data) |
| @@ -1096,31 +1132,6 @@ class RunQueue: | |||
| 1096 | return pid, pipein, pipeout | 1132 | return pid, pipein, pipeout |
| 1097 | 1133 | ||
| 1098 | 1134 | ||
| 1099 | def dump_data(self, taskQueue): | ||
| 1100 | """ | ||
| 1101 | Dump some debug information on the internal data structures | ||
| 1102 | """ | ||
| 1103 | bb.msg.debug(3, bb.msg.domain.RunQueue, "run_tasks:") | ||
| 1104 | for task in range(len(self.runq_task)): | ||
| 1105 | bb.msg.debug(3, bb.msg.domain.RunQueue, " (%s)%s - %s: %s Deps %s RevDeps %s" % (task, | ||
| 1106 | taskQueue.fn_index[self.runq_fnid[task]], | ||
| 1107 | self.runq_task[task], | ||
| 1108 | self.runq_weight[task], | ||
| 1109 | self.runq_depends[task], | ||
| 1110 | self.runq_revdeps[task])) | ||
| 1111 | |||
| 1112 | bb.msg.debug(3, bb.msg.domain.RunQueue, "sorted_tasks:") | ||
| 1113 | for task1 in range(len(self.runq_task)): | ||
| 1114 | if task1 in self.prio_map: | ||
| 1115 | task = self.prio_map[task1] | ||
| 1116 | bb.msg.debug(3, bb.msg.domain.RunQueue, " (%s)%s - %s: %s Deps %s RevDeps %s" % (task, | ||
| 1117 | taskQueue.fn_index[self.runq_fnid[task]], | ||
| 1118 | self.runq_task[task], | ||
| 1119 | self.runq_weight[task], | ||
| 1120 | self.runq_depends[task], | ||
| 1121 | self.runq_revdeps[task])) | ||
| 1122 | |||
| 1123 | |||
| 1124 | class TaskFailure(Exception): | 1135 | class TaskFailure(Exception): |
| 1125 | """ | 1136 | """ |
| 1126 | Exception raised when a task in a runqueue fails | 1137 | Exception raised when a task in a runqueue fails |
| @@ -1145,7 +1156,7 @@ class runQueueEvent(bb.event.Event): | |||
| 1145 | """ | 1156 | """ |
| 1146 | def __init__(self, task, stats, rq): | 1157 | def __init__(self, task, stats, rq): |
| 1147 | self.taskid = task | 1158 | self.taskid = task |
| 1148 | self.taskstring = rq.get_user_idstring(task) | 1159 | self.taskstring = rq.rqdata.get_user_idstring(task) |
| 1149 | self.stats = stats | 1160 | self.stats = stats |
| 1150 | bb.event.Event.__init__(self) | 1161 | bb.event.Event.__init__(self) |
| 1151 | 1162 | ||
| @@ -1176,7 +1187,7 @@ class runQueueTaskCompleted(runQueueEvent): | |||
| 1176 | def check_stamp_fn(fn, taskname, d): | 1187 | def check_stamp_fn(fn, taskname, d): |
| 1177 | rq = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY", d) | 1188 | rq = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY", d) |
| 1178 | fn = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY2", d) | 1189 | fn = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY2", d) |
| 1179 | fnid = rq.taskData.getfn_id(fn) | 1190 | fnid = rq.rqdata.taskData.getfn_id(fn) |
| 1180 | taskid = rq.get_task_id(fnid, taskname) | 1191 | taskid = rq.get_task_id(fnid, taskname) |
| 1181 | if taskid is not None: | 1192 | if taskid is not None: |
| 1182 | return rq.check_stamp_task(taskid) | 1193 | return rq.check_stamp_task(taskid) |
