mirror of
https://gitlab.com/ita1024/waf.git
synced 2024-11-25 11:19:52 +01:00
Rework the priority system
- Have Task.weight apply to the current task only - Do not rely on object addresses to set the build order - Introduce tg.tg_idx_count to count task generators - Enable propagating/non-propagating weights through Task.tree_weight/Task.weight
This commit is contained in:
parent
0b5202a88b
commit
f49f162817
@ -228,8 +228,6 @@ class Parallel(object):
|
||||
elif not self.count:
|
||||
tasks = next(self.biter)
|
||||
ready, waiting = self.prio_and_split(tasks)
|
||||
# We cannot use a priority queue because the implementation
|
||||
# must be able to handle postponed dependencies
|
||||
self.outstanding.extend(ready)
|
||||
self.incomplete.update(waiting)
|
||||
self.total = self.bld.total()
|
||||
@ -447,6 +445,11 @@ class Parallel(object):
|
||||
dependency cycles are found quickly, and builds should be more efficient.
|
||||
A high priority number means that a task is processed first.
|
||||
|
||||
This method can be overridden to disable the priority system::
|
||||
|
||||
def prio_and_split(self, tasks):
|
||||
return tasks, []
|
||||
|
||||
:return: A pair of task lists
|
||||
:rtype: tuple
|
||||
"""
|
||||
@ -476,15 +479,17 @@ class Parallel(object):
|
||||
|
||||
if n.visited == 0:
|
||||
n.visited = 1
|
||||
|
||||
if n in reverse:
|
||||
rev = reverse[n]
|
||||
n.__order = n.priority() + len(rev) + sum(visit(k) for k in rev)
|
||||
n.prio_order = n.tree_weight + len(rev) + sum(visit(k) for k in rev)
|
||||
else:
|
||||
n.__order = n.priority()
|
||||
n.prio_order = n.tree_weight
|
||||
|
||||
n.visited = 2
|
||||
elif n.visited == 1:
|
||||
raise Errors.WafError('Dependency cycle found!')
|
||||
return n.__order
|
||||
return n.prio_order
|
||||
|
||||
for x in tasks:
|
||||
if x.visited != 0:
|
||||
|
@ -153,7 +153,20 @@ class Task(evil):
|
||||
This may be useful for certain extensions but it can a lot of memory.
|
||||
"""
|
||||
|
||||
__slots__ = ('hasrun', 'generator', 'env', 'inputs', 'outputs', 'dep_nodes', 'run_after', '__order')
|
||||
weight = 0
|
||||
"""Optional weight to tune the priority for task instances.
|
||||
The higher, the earlier. The weight only applies to single task objects."""
|
||||
|
||||
tree_weight = 0
|
||||
"""Optional weight to tune the priority of task instances and whole subtrees.
|
||||
The higher, the earlier."""
|
||||
|
||||
prio_order = 0
|
||||
"""Priority order set by the scheduler on instances during the build phase.
|
||||
You most likely do not need to set it.
|
||||
"""
|
||||
|
||||
__slots__ = ('hasrun', 'generator', 'env', 'inputs', 'outputs', 'dep_nodes', 'run_after')
|
||||
|
||||
def __init__(self, *k, **kw):
|
||||
self.hasrun = NOT_RUN
|
||||
@ -177,16 +190,14 @@ class Task(evil):
|
||||
self.run_after = set()
|
||||
"""Set of tasks that must be executed before this one"""
|
||||
|
||||
self.__order = 0
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.__order > other.__order or id(self) > id(other)
|
||||
return self.priority() > other.priority()
|
||||
def __le__(self, other):
|
||||
return self.__order >= other.__order or id(self) >= id(other)
|
||||
return self.priority() >= other.priority()
|
||||
def __gt__(self, other):
|
||||
return self.__order < other.__order or id(self) < id(other)
|
||||
return self.priority() < other.priority()
|
||||
def __ge__(self, other):
|
||||
return self.__order <= other.__order or id(self) <= id(other)
|
||||
return self.priority() <= other.priority()
|
||||
|
||||
def get_cwd(self):
|
||||
"""
|
||||
@ -222,12 +233,12 @@ class Task(evil):
|
||||
|
||||
def priority(self):
|
||||
"""
|
||||
The default priority for this task instance
|
||||
Priority of execution; the higher, the earlier
|
||||
|
||||
:return: a numeric value representing the urgency of running this task (the higher, the sooner)
|
||||
:rtype: int
|
||||
:return: the priority value
|
||||
:rtype: a tuple of numeric values
|
||||
"""
|
||||
return getattr(self, 'weight', 0)
|
||||
return (self.weight + self.prio_order, - self.generator.tg_idx_count)
|
||||
|
||||
def split_argfile(self, cmd):
|
||||
"""
|
||||
|
@ -76,13 +76,20 @@ class task_gen(object):
|
||||
self.env = self.bld.env.derive()
|
||||
self.path = self.bld.path # emulate chdir when reading scripts
|
||||
|
||||
# provide a unique id
|
||||
# Provide a unique index per folder
|
||||
# This is part of a measure to prevent output file name collisions
|
||||
try:
|
||||
self.idx = self.bld.idx[self.path] = self.bld.idx.get(self.path, 0) + 1
|
||||
except AttributeError:
|
||||
self.bld.idx = {}
|
||||
self.idx = self.bld.idx[self.path] = 1
|
||||
|
||||
# Record the global task generator count
|
||||
try:
|
||||
self.tg_idx_count = self.bld.tg_idx_count = self.bld.tg_idx_count + 1
|
||||
except AttributeError:
|
||||
self.tg_idx_count = self.bld.tg_idx_count = 1
|
||||
|
||||
for key, val in kw.items():
|
||||
setattr(self, key, val)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user