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 | |
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')
-rw-r--r-- | bitbake/lib/bb/cooker.py | 16 | ||||
-rw-r--r-- | bitbake/lib/bb/runqueue.py | 221 |
2 files changed, 124 insertions, 113 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 3f6f6ef0b6..8d65ba809a 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -275,7 +275,7 @@ class BBCooker: | |||
275 | taskdata.add_unresolved(localdata, self.status) | 275 | taskdata.add_unresolved(localdata, self.status) |
276 | 276 | ||
277 | rq = bb.runqueue.RunQueue(self, self.configuration.data, self.status, taskdata, runlist) | 277 | rq = bb.runqueue.RunQueue(self, self.configuration.data, self.status, taskdata, runlist) |
278 | rq.prepare_runqueue() | 278 | rq.rqdata.prepare() |
279 | 279 | ||
280 | seen_fnids = [] | 280 | seen_fnids = [] |
281 | depend_tree = {} | 281 | depend_tree = {} |
@@ -287,9 +287,9 @@ class BBCooker: | |||
287 | depend_tree["rdepends-pkg"] = {} | 287 | depend_tree["rdepends-pkg"] = {} |
288 | depend_tree["rrecs-pkg"] = {} | 288 | depend_tree["rrecs-pkg"] = {} |
289 | 289 | ||
290 | for task in range(len(rq.runq_fnid)): | 290 | for task in range(len(rq.rqdata.runq_fnid)): |
291 | taskname = rq.runq_task[task] | 291 | taskname = rq.rqdata.runq_task[task] |
292 | fnid = rq.runq_fnid[task] | 292 | fnid = rq.rqdata.runq_fnid[task] |
293 | fn = taskdata.fn_index[fnid] | 293 | fn = taskdata.fn_index[fnid] |
294 | pn = self.status.pkg_fn[fn] | 294 | pn = self.status.pkg_fn[fn] |
295 | version = "%s:%s-%s" % self.status.pkg_pepvpr[fn] | 295 | version = "%s:%s-%s" % self.status.pkg_pepvpr[fn] |
@@ -297,13 +297,13 @@ class BBCooker: | |||
297 | depend_tree["pn"][pn] = {} | 297 | depend_tree["pn"][pn] = {} |
298 | depend_tree["pn"][pn]["filename"] = fn | 298 | depend_tree["pn"][pn]["filename"] = fn |
299 | depend_tree["pn"][pn]["version"] = version | 299 | depend_tree["pn"][pn]["version"] = version |
300 | for dep in rq.runq_depends[task]: | 300 | for dep in rq.rqdata.runq_depends[task]: |
301 | depfn = taskdata.fn_index[rq.runq_fnid[dep]] | 301 | depfn = taskdata.fn_index[rq.rqdata.runq_fnid[dep]] |
302 | deppn = self.status.pkg_fn[depfn] | 302 | deppn = self.status.pkg_fn[depfn] |
303 | dotname = "%s.%s" % (pn, rq.runq_task[task]) | 303 | dotname = "%s.%s" % (pn, rq.rqdata.runq_task[task]) |
304 | if not dotname in depend_tree["tdepends"]: | 304 | if not dotname in depend_tree["tdepends"]: |
305 | depend_tree["tdepends"][dotname] = [] | 305 | depend_tree["tdepends"][dotname] = [] |
306 | depend_tree["tdepends"][dotname].append("%s.%s" % (deppn, rq.runq_task[dep])) | 306 | depend_tree["tdepends"][dotname].append("%s.%s" % (deppn, rq.rqdata.runq_task[dep])) |
307 | if fnid not in seen_fnids: | 307 | if fnid not in seen_fnids: |
308 | seen_fnids.append(fnid) | 308 | seen_fnids.append(fnid) |
309 | packages = [] | 309 | packages = [] |
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) |