summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-18 11:30:53 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-18 11:49:58 +0100
commit5d9f37873d88a33cc0f1c326a2cb0c2ff673a3a6 (patch)
treef9a0a5c3c0a0ffd6084824e95f0fc863898098ee /bitbake
parentd7bc9b8ecec524294cc9143fd0b349249b329891 (diff)
downloadpoky-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')
-rw-r--r--bitbake/lib/bb/cooker.py16
-rw-r--r--bitbake/lib/bb/runqueue.py221
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
160class RunQueue: 162class 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
706class 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
1124class TaskFailure(Exception): 1135class 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):
1176def check_stamp_fn(fn, taskname, d): 1187def 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)