poky: subtree update:835f7eac06..20946c63c2
Aaron Chan (1):
python3-dbus: Add native and nativesdk variants
Adrian Bunk (8):
gnome: Remove the gnome class
bind: Remove RECIPE_NO_UPDATE_REASON and follow the ESV releases
webkitgtk: Reenable on mips
mtd-utils: Upgrade to 2.1.1
Change ftp:// URIs to http(s)://
webkitgtk: Stop disabling gold on aarch64 and mips
grub/libmpc/gdb: Use GNU_MIRROR in more recipes
screen: Backport fix for an implicit function declaration
Alexander Kanavin (28):
btrfs-tools: update 5.1.1 -> 5.2.1
libmodulemd: update to 2.6.0
libwebp: upgrade 1.0.2 -> 1.0.3
createrepo-c: upgrade 0.14.2 -> 0.14.3
webkitgtk: upgrade 2.24.2 -> 2.24.3
bzip2: fix upstream version check
stress-ng: add a recipe that replaces the original stress
meson: update 0.50.1 -> 0.51.1
meson.bbclass: do not pass native compiler/linker flags via command line
meson: add a backported patch to address vala cross-compilation errors
libedit: fix upstream verison check
maintainers.inc: assign acpica to Ross
stress-ng: add a patch to remove unneeded bash dependency
elfutils: use PRIVATE_LIBS for the ptest package
apt: add a missing perl runtime dependency
attr: add a missing perl runtime dependency
ofono: correct the python3 runtime dependency
bluez5: correct the python3 runtime dependency
local.conf.sample: do not add sdl to nativesdk qemu config
maintainers.inc: give python recipes to Oleksandr Kravchuk
python-numpy: remove the python 2.x version of the recipe
python-scons: remove the python 2.x version of the recipe
python-nose: remove the python 2.x version of the recipe
lib/oeqa/utils/qemurunner.py: add runqemuparams after kvm/nographic/snapshot/slirp
mesa: enable glx-tls option in native and nativesdk builds
insane.bbclass: in file-rdeps do not look into RDEPENDS recursively
sudo: correct SRC_URI
ovmf: fix upstream version check
Andreas Obergschwandtner (1):
bzip2: set the autoconf package version to the recipe version
Anuj Mittal (11):
mpg123: upgrade 1.25.10 -> 1.25.11
libsdl: remove
pulseaudio: don't include consolekit when systemd is enabled
libsdl2: upgrade 2.0.9 -> 2.0.10
grub: upgrade 2.02 -> 2.04
patch: fix CVE-2019-13636
python: fix CVE-2018-20852
python: CVE-2019-9947 is same as CVE-2019-9740
libtasn1: upgrade 4.13 -> 4.14
pango: upgrade 1.42.4 -> 1.44.3
harfbuzz: upgrade 2.4.0 -> 2.5.3
Bartosz Golaszewski (1):
qemu: add a patch fixing the native build on newer kernels
Bedel, Alban (3):
rng-tools: start rngd early in the boot process again
kernel-uboot: remove useless special casing of arm64 Image
boost: Fix build and enable context and coroutines on aarch64
Bruce Ashfield (2):
linux-yocto/4.19: update to v4.19.61
linux-yocto-dev: bump to 5.3-rcX
Changqing Li (6):
runqemu: add lockfile for port used when slirp enabled
runqemu: fix get portlock fail for multi users
qemuboot-x86: move QB_SYSTEM_NAME to corresponding conf
genericx86-64.conf/genericx86.conf: add QB_SYSTEM_NAME
grub/grub-efi: fix conflict for aach64
go-runtime: remove conflict files from -dev packages
Chen Qi (1):
sudo: use nonarch_libdir instead of libdir for tmpfiles.d
Chin Huat Ang (1):
cve-update-db-native: fix https proxy issues
Chris Laplante via bitbake-devel (1):
bitbake: fetch2/wget: avoid 'maximum recursion depth' RuntimeErrors when handling 403 codes
Daniel Ammann (2):
image_types: Remove remnants of hdddirect
bitbake: toaster: Sync list of fs_types with oe-core
Denys Dmytriyenko (2):
wayland-protocols: upgrade 1.17 -> 1.18
weston: upgrade 6.0.0 -> 6.0.1
Diego Rondini (1):
image_types.bbclass: make gzipped images rsyncable
Dmitry Eremin-Solenikov (1):
kernel.bbclass: fix installation of modules signing certificates
Frederic Ouellet (1):
systemd: Add partial support of drop-in configuration files to systemd-systemctl-native
Hongxu Jia (1):
grub: add grub-native
Jason Wessel (6):
sqlite3: Fix zlib determinism problem
pseudo: Fix openat() with a symlink pointing to a directory
image_types_wic.bbclass: Copy the .wks and .env files to deploy image dir
wic: Add partition type for msdos partition tables
wic: Make disk partition size consistently computed
dpkg: Provide update-alternative for start-stop-daemon
Johann Fridriksson (1):
ruby: Adding zlib-native to native dependencies
Joshua Lock via Openembedded-core (3):
sstate: fix log message
classes/sstate: don't use unsigned sstate when verification enabled
classes/sstate: regenerate sstate when signing enabled
Joshua Watt (1):
bitbake: hashserv: SQL Optimizations
Kai Kang (3):
subversion: add packageconfig boost
epiphany: set imcompatible with tune mips
e2fsprogs: 1.44.5 -> 1.45.3
Khem Raj (23):
strace: Upgrade to 5.2
linux-libc-header: Fix ptrace.h and prctl.h conflict on aarch64
libnss-nis: Fix build with glibc 2.30
lttng-ust: Check for gettid libc API
ltp: Fix build with glibc 2.30
lttng-tools: Fix build with glibc 2.30
xserver-xorg: Backport patch to remove using sys/io.h
Apache-2.0-with-LLVM-exception: Add new license file
libedit: Move from meta-oe
groff: Fix math.h inclusion from system headers issue
webkitgtk: Fix compile failures with clang
glibc: Update to glibc 2.30
virglrender: Fix endianness check on musl
syslinux: Override hardcoded toolnames in Makefile
systemd-boot: Add option to specify cross objcopy and use it
mesa,llvm,meson: Update llvm to 8.0.1 plus define and use LLVM version globally
musl: Update to master tip
oeqa/buildgalculator.py: Add dependency on gtk+3
oeqa/parselogs: grep for exact errors list keywords
gcc-runtime: Move content from gcclibdir into libdir
gdb: Do not set musl specific CFLAGS
linuxloader: Add entries for riscv64
musl: Delete GLIBC_LDSO before creating symlink with lnr
Luca Boccassi (1):
python3-pygobject: remove python3-setuptools from RDEPENDS
Mads Andreasen (1):
bitbake: fetch2/npm: Use npm pack to download node modules instead of wget
Mark Hatle (2):
glibc-package.inc: Add linux-libc-headers-dev to glibc-dev
bitbake: layerindexlib: Fix parsing of recursive layer dependencies
Martin Jansa (3):
icecc.bbclass: catch subprocess.CalledProcessError
powertop: import a fix from buildroot
meson: backport fix for builds with -Werror=return-type
Ming Liu (5):
libx11-compose-data: add recipe
libxkbcommon: RDEPENDS on libx11 compose data
weston: change to use meson build system
license_image.bbclass: drop invalid comments
opensbi: handle deploy task under sstate
Naveen Saini (2):
gdk-pixbuf: enable x11 PACKAGECONFIG option
image_types_wic: add syslinux-native dependency conditional
Oleksandr Kravchuk (17):
python3-pip: update to 19.2.1
python3-git: update to 2.1.12
ethtool: update to 5.2
python3-git: update to 2.1.13
xorgproto: update to 2019.1
xserver-xorg: update to 1.20.5
ell: update to 0.21
libinput: update to 1.14.0
wpa-supplicant: update to 2.9
aspell: update to 0.60.7
linux-firmware: add PE back
xf86-input-libinput: update to 0.29.0
git: update to 2.22.1
xrandr: update to 1.5.1
python3-git: update to 3.0.0
librepo: update to 1.10.5
libevent: update to 2.1.11
Pascal Bach (2):
cmake: 3.14.5 -> 3.15.1
cmake: 3.15.1 -> 3.15.2
Paul Eggleton (2):
scripts/create-pull-request: improve handling of non-SSH remote URLs
scripts/create-pull-request: fix putting subject containing / into cover letter
Piotr Tworek (2):
pulseaudio: Backport upstream fix new alsa compatibility.
libdrm: Move amdgpu.ids file into libdrm-amdgpu package.
Randy MacLeod (1):
ptest-runner: update from 2.3.1 to 2.3.2
Rasmus Villemoes (1):
iproute2: drop pointless configure-cross.patch
Ricardo Neri (5):
ovmf: Update to version edk2-stable201905
ovmf: Set PV
ovmf: Use HOSTTOOLS' python3
ovmf: Generate test Platform key and first Key Exchange Key
runqemu: Add support to handle EnrollDefaultKeys PK/KEK1 certificate
Ricardo Ribalda Delgado (2):
packagegroup-core-base-utils: Make it machine specific
inetutils: Fix abort on invalid files
Richard Purdie (50):
package: Improve determinism
sstate: Reduce race windows
bitbake: siggen: Import unihash code from OE-Core
bitbake: cache: Add SimpleCache class
bitbake: runqueue: Improve scenequeue processing logic
bitbake: siggen: Add new unitaskhashes data variable which is cached
bitbake: siggen: Convert to use self.unitaskhashes
bitbake: runqueue: Enable dynamic task adjustment to hash equivalency
bitbake: runqueue: Improve determinism
bitbake: cooker/hashserv: Allow autostarting of a local hash server using BB_HASHSERVE
bitbake: hashserv: Turn off sqlite synchronous mode
bitbake: prserv: Use a memory journal
bitbake: hashserv: Use separate threads for answering requests and handling them
bitbake: hashserv: Switch from threads to multiprocessing
bitbake: runqueue: Clean up BB_HASHCHECK_FUNCTION API
bitbake: siggen: Clean up task reference formats
bitbake: build/utils: Drop bb.build.FuncFailed
bitbake: tests/runqueue: Add hashserv+runqueue test
bitbake: bitbake: Bump version to 1.43.1 for API changes
sanity.conf: Require bitbake 1.43.1
classes/lib: Remove bb.build.FuncFailed
sstatesig: Move unihash siggen code to bitbake
sstatesig: Add debug for incorrect hash server settings
sstatesig: Adpat to recent bitbake hash equiv runqueue changes
sstatesig: Update to handle BB_HASHSERVE
sstate/sstatesig: Update to new form of BB_HASHCHECK_FUNCTION
sstatesig: Updates to match bitbake siggen changes
gstreamer: Add fix for glibc 2.30
sstatesig: Fix leftover splitting issue from siggen change
python3-pygobject: Add missing pkgutil RDEPENDS
bitbake: runqueue: Fix corruption issue
bitbake: runqueue: Improve setscene task handling logic
bitbake: tests/runqueue: Add further hash equivalence tests
bitbake: cooker: Improve hash server startup code to avoid exit tracebacks
bitbake: runqueue: Wait for covered tasks to complete before trying setscene
bitbake: runqueue: Fix next_buildable_task performance problem
bitbake: runqueue: Improve scenequeue debugging
bitbake: runqueue: Recompute holdoff tasks from scratch
bitbake: runqueue: Fix event timing race
bitbake: runqueue: Drop debug statement causing performance issues
bitbake: runqueue: Add further debug information
bitbake: runqueue: Add missing setscene task corner case
bitbake: runqueue: Ensure we clear the stamp cache
poky: Retire opensuse 42.3 from SANITY_TESTED_DISTROS
gcc-cross-canadian: Drop obsolete shlibs exclusion
bitbake: tests/runqueue: Fix tests
bitbake: runqueue: Fix data corruption problem
bitbake: runqueue: Ensure data is handled correctly
bitbake: hashserv: Ensure we don't accumulate sockets in TIME_WAIT state
bitbake: runqueue: Ensure target_tids is filtered
Robert Yang (3):
bitbake: cooker: Cleanup the queue before call process.join()
bitbake: knotty: Fix for the Second Keyboard Interrupt
bitbake: bitbake: server/process: Handle BBHandledException to avoid unexpected exceptions
Ross Burton (23):
libidn2: remove build paths from libidn2.pc
gnutls: don't use HOSTTOOLS_DIR/bash as a shell on target
libical: upgrade to 3.0.5
perl: fix whitespace
perl: add PACKAGECONFIG for db
fortran-helloworld: neaten recipe
python3: remove empty python3-distutils-staticdev
python3: support recommends in manifest
python3: split out the Windows distutils installer stubs
insane: check if the recipe incorrectly uses DEPENDS_${PN}
libxx86misc: remove this now redundant library
xserver-xorg: clean up xorgproto dependencies
xserver-xorg: add PACKAGECONFIG for DGA
xdpyinfo: don't depend on DGA
libxx86dga: remove obsolete client libary
xserver-xorg: remove embedded build path in the source
libx11: update to 1.6.8
sanity: update for new bb.build.exec_func() behaviour
libx11-diet: remove
qemu: fix patch Upstream-Status
xserver-xorg: refresh build path removal patch
waffle: upgrade 1.5.2 -> 1.6.0
libx11: replace libtool patch with upstreamed patch
Tim Blechmann (1):
deb: allow custom dpkg command
Trevor Gamblin (2):
gzip: update ptest package dependencies
patch: fix CVE-2019-13638
Wenlin Kang (1):
db: add switch for building database verification
Will Page (1):
uboot: fixes to uboot-extlinux-config attribute values
William Bourque (1):
meta/lib/oeqa: Remove ext4 for bootimg-biosplusefi
Yi Zhao (1):
libx11-compose-data: upgrade 1.6.7 -> 1.6.8
Yuan Chao (4):
glib-2.0:upgrade 2.60.5 -> 2.60.6
nettle:upgrade 3.4.1 -> 3.5.1
python3-pbr:upgrade 5.4.1 -> 5.4.2
gpgme:upgrade 1.13.0 -> 1.13.1
Zang Ruochen (8):
msmtp: upgrade 1.8.4 -> 1.8.5
curl: upgrade 7.65.2 -> 7.65.3
iso-codes: upgrade 4.2 -> 4.3
python-scons:upgrade 3.0.5 -> 3.1.0
libgudev:upgrade 232 -> 233
libglu:upgrade 9.0.0 -> 9.0.1
man-db:upgrade 2.8.5 -> 2.8.6.1
libnewt:upgrade 0.52.20 -> 0.52.21
Zheng Ruoqin (1):
python3-mako: 1.0.14 -> 1.1.0
Zoltan Kuscsik (1):
kmscube: update to latest revision
Change-Id: I2cd1a0d59da46725b1aba5a79b63eb6121b3c79e
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/poky/bitbake/lib/bb/runqueue.py b/poky/bitbake/lib/bb/runqueue.py
index 6a2de24..7fa074f 100644
--- a/poky/bitbake/lib/bb/runqueue.py
+++ b/poky/bitbake/lib/bb/runqueue.py
@@ -133,7 +133,7 @@
self.prio_map = [self.rqdata.runtaskentries.keys()]
- self.buildable = []
+ self.buildable = set()
self.skip_maxthread = {}
self.stamps = {}
for tid in self.rqdata.runtaskentries:
@@ -148,8 +148,10 @@
"""
Return the id of the first task we find that is buildable
"""
- self.buildable = [x for x in self.buildable if x not in self.rq.runq_running]
- buildable = [x for x in self.buildable if (x in self.rq.tasks_covered or x in self.rq.tasks_notcovered)]
+ buildable = set(self.buildable)
+ buildable.difference_update(self.rq.runq_running)
+ buildable.difference_update(self.rq.holdoff_tasks)
+ buildable.intersection_update(self.rq.tasks_covered | self.rq.tasks_notcovered)
if not buildable:
return None
@@ -167,7 +169,7 @@
skip_buildable[rtaskname] = 1
if len(buildable) == 1:
- tid = buildable[0]
+ tid = buildable.pop()
taskname = taskname_from_tid(tid)
if taskname in skip_buildable and skip_buildable[taskname] >= int(self.skip_maxthread[taskname]):
return None
@@ -204,7 +206,10 @@
return self.next_buildable_task()
def newbuildable(self, task):
- self.buildable.append(task)
+ self.buildable.add(task)
+
+ def removebuildable(self, task):
+ self.buildable.remove(task)
def describe_task(self, taskid):
result = 'ID %s' % taskid
@@ -1171,10 +1176,9 @@
def prepare_task_hash(self, tid):
procdep = []
for dep in self.runtaskentries[tid].depends:
- procdep.append(fn_from_tid(dep) + "." + taskname_from_tid(dep))
- (mc, fn, taskname, taskfn) = split_tid_mcfn(tid)
- self.runtaskentries[tid].hash = bb.parse.siggen.get_taskhash(taskfn, taskname, procdep, self.dataCaches[mc])
- self.runtaskentries[tid].unihash = bb.parse.siggen.get_unihash(taskfn + "." + taskname)
+ procdep.append(dep)
+ self.runtaskentries[tid].hash = bb.parse.siggen.get_taskhash(tid, procdep, self.dataCaches[mc_from_tid(tid)])
+ self.runtaskentries[tid].unihash = bb.parse.siggen.get_unihash(tid)
def dump_data(self):
"""
@@ -1251,6 +1255,7 @@
"buildname" : self.cfgData.getVar("BUILDNAME"),
"date" : self.cfgData.getVar("DATE"),
"time" : self.cfgData.getVar("TIME"),
+ "hashservport" : self.cooker.hashservport,
}
worker.stdin.write(b"<cookerconfig>" + pickle.dumps(self.cooker.configuration) + b"</cookerconfig>")
@@ -1384,57 +1389,29 @@
cache[tid] = iscurrent
return iscurrent
- def validate_hashes(self, tocheck, data, presentcount=None, siginfo=False):
+ def validate_hashes(self, tocheck, data, currentcount=None, siginfo=False):
valid = set()
if self.hashvalidate:
- sq_hash = []
- sq_hashfn = []
- sq_unihash = []
- sq_fn = []
- sq_taskname = []
- sq_task = []
+ sq_data = {}
+ sq_data['hash'] = {}
+ sq_data['hashfn'] = {}
+ sq_data['unihash'] = {}
for tid in tocheck:
(mc, fn, taskname, taskfn) = split_tid_mcfn(tid)
+ sq_data['hash'][tid] = self.rqdata.runtaskentries[tid].hash
+ sq_data['hashfn'][tid] = self.rqdata.dataCaches[mc].hashfn[taskfn]
+ sq_data['unihash'][tid] = self.rqdata.runtaskentries[tid].unihash
- sq_fn.append(fn)
- sq_hashfn.append(self.rqdata.dataCaches[mc].hashfn[taskfn])
- sq_hash.append(self.rqdata.runtaskentries[tid].hash)
- sq_unihash.append(self.rqdata.runtaskentries[tid].unihash)
- sq_taskname.append(taskname)
- sq_task.append(tid)
-
- if presentcount is not None:
- data.setVar("BB_SETSCENE_STAMPCURRENT_COUNT", presentcount)
-
- valid_ids = self.validate_hash(sq_fn, sq_taskname, sq_hash, sq_hashfn, siginfo, sq_unihash, data, presentcount)
-
- if presentcount is not None:
- data.delVar("BB_SETSCENE_STAMPCURRENT_COUNT")
-
- for v in valid_ids:
- valid.add(sq_task[v])
+ valid = self.validate_hash(sq_data, data, siginfo, currentcount)
return valid
- def validate_hash(self, sq_fn, sq_task, sq_hash, sq_hashfn, siginfo, sq_unihash, d, presentcount):
- locs = {"sq_fn" : sq_fn, "sq_task" : sq_task, "sq_hash" : sq_hash, "sq_hashfn" : sq_hashfn,
- "sq_unihash" : sq_unihash, "siginfo" : siginfo, "d" : d}
+ def validate_hash(self, sq_data, d, siginfo, currentcount):
+ locs = {"sq_data" : sq_data, "d" : d, "siginfo" : siginfo, "currentcount" : currentcount}
- # Backwards compatibility
- hashvalidate_args = ("(sq_fn, sq_task, sq_hash, sq_hashfn, d, siginfo=siginfo, sq_unihash=sq_unihash)",
- "(sq_fn, sq_task, sq_hash, sq_hashfn, d, siginfo=siginfo)",
- "(sq_fn, sq_task, sq_hash, sq_hashfn, d)")
+ # Metadata has **kwargs so args can be added, sq_data can also gain new fields
+ call = self.hashvalidate + "(sq_data, d, siginfo=siginfo, currentcount=currentcount)"
- for args in hashvalidate_args[:-1]:
- try:
- call = self.hashvalidate + args
- return bb.utils.better_eval(call, locs)
- except TypeError:
- continue
-
- # Call the last entry without a try...catch to propagate any thrown
- # TypeError
- call = self.hashvalidate + hashvalidate_args[-1]
return bb.utils.better_eval(call, locs)
def _execute_runqueue(self):
@@ -1516,6 +1493,7 @@
self.dm_event_handler_registered = False
if build_done and self.rqexe:
+ bb.parse.siggen.save_unitaskhashes()
self.teardown_workers()
if self.rqexe:
if self.rqexe.stats.failed:
@@ -1718,6 +1696,9 @@
self.sq_running = set()
self.sq_live = set()
+ self.updated_taskhash_queue = []
+ self.pending_migrations = set()
+
self.runq_buildable = set()
self.runq_running = set()
self.runq_complete = set()
@@ -1729,6 +1710,7 @@
self.stampcache = {}
+ self.holdoff_tasks = set()
self.sqdone = False
self.stats = RunQueueStats(len(self.rqdata.runtaskentries))
@@ -1751,7 +1733,10 @@
self.tasks_notcovered = set()
self.scenequeue_notneeded = set()
- self.coveredtopocess = set()
+ # We can't skip specified target tasks which aren't setscene tasks
+ self.cantskip = set(self.rqdata.target_tids)
+ self.cantskip.difference_update(self.rqdata.runq_setscene_tids)
+ self.cantskip.intersection_update(self.rqdata.runtaskentries)
schedulers = self.get_schedulers()
for scheduler in schedulers:
@@ -1763,9 +1748,9 @@
bb.fatal("Invalid scheduler '%s'. Available schedulers: %s" %
(self.scheduler, ", ".join(obj.name for obj in schedulers)))
- if len(self.rqdata.runq_setscene_tids) > 0:
- self.sqdata = SQData()
- build_scenequeue_data(self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self)
+ #if len(self.rqdata.runq_setscene_tids) > 0:
+ self.sqdata = SQData()
+ build_scenequeue_data(self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self)
def runqueue_process_waitpid(self, task, status):
@@ -1831,6 +1816,9 @@
if not self.rq.depvalidate:
return False
+ # Must not edit parent data
+ taskdeps = set(taskdeps)
+
taskdata = {}
taskdeps.add(task)
for dep in taskdeps:
@@ -1918,17 +1906,58 @@
self.stats.taskSkipped()
self.stats.taskCompleted()
+ def summarise_scenequeue_errors(self):
+ err = False
+ if not self.sqdone:
+ logger.debug(1, 'We could skip tasks %s', "\n".join(sorted(self.scenequeue_covered)))
+ completeevent = sceneQueueComplete(self.sq_stats, self.rq)
+ bb.event.fire(completeevent, self.cfgData)
+ if self.sq_deferred:
+ logger.error("Scenequeue had deferred entries: %s" % pprint.pformat(self.sq_deferred))
+ err = True
+ if self.updated_taskhash_queue:
+ logger.error("Scenequeue had unprocessed changed taskhash entries: %s" % pprint.pformat(self.updated_taskhash_queue))
+ err = True
+ if self.holdoff_tasks:
+ logger.error("Scenequeue had holdoff tasks: %s" % pprint.pformat(self.holdoff_tasks))
+ err = True
+
+ for tid in self.rqdata.runq_setscene_tids:
+ if tid not in self.scenequeue_covered and tid not in self.scenequeue_notcovered:
+ err = True
+ logger.error("Setscene Task %s was never marked as covered or not covered" % tid)
+ if tid not in self.sq_buildable:
+ err = True
+ logger.error("Setscene Task %s was never marked as buildable" % tid)
+ if tid not in self.sq_running:
+ err = True
+ logger.error("Setscene Task %s was never marked as running" % tid)
+
+ for x in self.rqdata.runtaskentries:
+ if x not in self.tasks_covered and x not in self.tasks_notcovered:
+ logger.error("Task %s was never moved from the setscene queue" % x)
+ err = True
+ if x not in self.tasks_scenequeue_done:
+ logger.error("Task %s was never processed by the setscene code" % x)
+ err = True
+ if len(self.rqdata.runtaskentries[x].depends) == 0 and x not in self.runq_buildable:
+ logger.error("Task %s was never marked as buildable by the setscene code" % x)
+ err = True
+ return err
+
+
def execute(self):
"""
Run the tasks in a queue prepared by prepare_runqueue
"""
self.rq.read_workers()
+ self.process_possible_migrations()
task = None
if not self.sqdone and self.can_start_task():
# Find the next setscene to run
- for nexttask in self.rqdata.runq_setscene_tids:
+ for nexttask in sorted(self.rqdata.runq_setscene_tids):
if nexttask in self.sq_buildable and nexttask not in self.sq_running and self.sqdata.stamps[nexttask] not in self.build_stamps.values():
if nexttask not in self.sqdata.unskippable and len(self.sqdata.sq_revdeps[nexttask]) > 0 and self.sqdata.sq_revdeps[nexttask].issubset(self.scenequeue_covered) and self.check_dependencies(nexttask, self.sqdata.sq_revdeps[nexttask]):
if nexttask not in self.rqdata.target_tids:
@@ -1938,6 +1967,10 @@
if nexttask in self.sq_deferred:
del self.sq_deferred[nexttask]
return True
+ # If covered tasks are running, need to wait for them to complete
+ for t in self.sqdata.sq_covered_tasks[nexttask]:
+ if t in self.runq_running and t not in self.runq_complete:
+ continue
if nexttask in self.sq_deferred:
if self.sq_deferred[nexttask] not in self.runq_complete:
continue
@@ -2006,24 +2039,10 @@
if self.can_start_task():
return True
- if not self.sq_live and not self.sqdone and not self.sq_deferred:
+ if not self.sq_live and not self.sqdone and not self.sq_deferred and not self.updated_taskhash_queue and not self.holdoff_tasks:
logger.info("Setscene tasks completed")
- logger.debug(1, 'We could skip tasks %s', "\n".join(sorted(self.scenequeue_covered)))
- completeevent = sceneQueueComplete(self.sq_stats, self.rq)
- bb.event.fire(completeevent, self.cfgData)
-
- err = False
- for x in self.rqdata.runtaskentries:
- if x not in self.tasks_covered and x not in self.tasks_notcovered:
- logger.error("Task %s was never moved from the setscene queue" % x)
- err = True
- if x not in self.tasks_scenequeue_done:
- logger.error("Task %s was never processed by the setscene code" % x)
- err = True
- if len(self.rqdata.runtaskentries[x].depends) == 0 and x not in self.runq_buildable:
- logger.error("Task %s was never marked as buildable by the setscene code" % x)
- err = True
+ err = self.summarise_scenequeue_errors()
if err:
self.rq.state = runQueueFailed
return True
@@ -2119,14 +2138,22 @@
return True
# Sanity Checks
+ err = self.summarise_scenequeue_errors()
for task in self.rqdata.runtaskentries:
if task not in self.runq_buildable:
logger.error("Task %s never buildable!", task)
+ err = True
elif task not in self.runq_running:
logger.error("Task %s never ran!", task)
+ err = True
elif task not in self.runq_complete:
logger.error("Task %s never completed!", task)
- self.rq.state = runQueueComplete
+ err = True
+
+ if err:
+ self.rq.state = runQueueFailed
+ else:
+ self.rq.state = runQueueComplete
return True
@@ -2144,7 +2171,7 @@
# as most code can't handle them
def build_taskdepdata(self, task):
taskdepdata = {}
- next = self.rqdata.runtaskentries[task].depends
+ next = self.rqdata.runtaskentries[task].depends.copy()
next.add(task)
next = self.filtermcdeps(task, next)
while next:
@@ -2166,57 +2193,153 @@
#bb.note("Task %s: " % task + str(taskdepdata).replace("], ", "],\n"))
return taskdepdata
- def scenequeue_process_notcovered(self, task):
- if len(self.rqdata.runtaskentries[task].depends) == 0:
- self.setbuildable(task)
- notcovered = set([task])
- while notcovered:
- new = set()
- for t in notcovered:
- for deptask in self.rqdata.runtaskentries[t].depends:
- if deptask in notcovered or deptask in new or deptask in self.rqdata.runq_setscene_tids or deptask in self.tasks_notcovered:
- continue
- logger.debug(1, 'Task %s depends on non-setscene task %s so not skipping' % (t, deptask))
- new.add(deptask)
- self.tasks_notcovered.add(deptask)
- if len(self.rqdata.runtaskentries[deptask].depends) == 0:
- self.setbuildable(deptask)
- notcovered = new
+ def update_holdofftasks(self):
+ self.holdoff_tasks = set()
- def scenequeue_process_unskippable(self, task):
- # Look up the dependency chain for non-setscene things which depend on this task
- # and mark as 'done'/notcovered
- ready = set([task])
- while ready:
- new = set()
- for t in ready:
- for deptask in self.rqdata.runtaskentries[t].revdeps:
- if deptask in ready or deptask in new or deptask in self.tasks_scenequeue_done or deptask in self.rqdata.runq_setscene_tids:
- continue
- if self.rqdata.runtaskentries[deptask].depends.issubset(self.tasks_scenequeue_done):
- new.add(deptask)
- self.tasks_scenequeue_done.add(deptask)
- self.tasks_notcovered.add(deptask)
- #logger.warning("Up: " + str(deptask))
- ready = new
+ for tid in self.rqdata.runq_setscene_tids:
+ if tid not in self.scenequeue_covered and tid not in self.scenequeue_notcovered:
+ self.holdoff_tasks.add(tid)
+
+ for tid in self.holdoff_tasks.copy():
+ for dep in self.sqdata.sq_covered_tasks[tid]:
+ if dep not in self.runq_complete:
+ self.holdoff_tasks.add(dep)
+
+ def process_possible_migrations(self):
+
+ changed = set()
+ for tid, unihash in self.updated_taskhash_queue.copy():
+ if tid in self.runq_running and tid not in self.runq_complete:
+ continue
+
+ self.updated_taskhash_queue.remove((tid, unihash))
+
+ if unihash != self.rqdata.runtaskentries[tid].unihash:
+ logger.info("Task %s unihash changed to %s" % (tid, unihash))
+ self.rqdata.runtaskentries[tid].unihash = unihash
+ bb.parse.siggen.set_unihash(tid, unihash)
+
+ # Work out all tasks which depend on this one
+ total = set()
+ next = set(self.rqdata.runtaskentries[tid].revdeps)
+ while next:
+ current = next.copy()
+ total = total |next
+ next = set()
+ for ntid in current:
+ next |= self.rqdata.runtaskentries[ntid].revdeps
+ next.difference_update(total)
+
+ # Now iterate those tasks in dependency order to regenerate their taskhash/unihash
+ done = set()
+ next = set(self.rqdata.runtaskentries[tid].revdeps)
+ while next:
+ current = next.copy()
+ next = set()
+ for tid in current:
+ if not self.rqdata.runtaskentries[tid].depends.isdisjoint(total):
+ continue
+ procdep = []
+ for dep in self.rqdata.runtaskentries[tid].depends:
+ procdep.append(dep)
+ orighash = self.rqdata.runtaskentries[tid].hash
+ self.rqdata.runtaskentries[tid].hash = bb.parse.siggen.get_taskhash(tid, procdep, self.rqdata.dataCaches[mc_from_tid(tid)])
+ origuni = self.rqdata.runtaskentries[tid].unihash
+ self.rqdata.runtaskentries[tid].unihash = bb.parse.siggen.get_unihash(tid)
+ logger.debug(1, "Task %s hash changes: %s->%s %s->%s" % (tid, orighash, self.rqdata.runtaskentries[tid].hash, origuni, self.rqdata.runtaskentries[tid].unihash))
+ next |= self.rqdata.runtaskentries[tid].revdeps
+ changed.add(tid)
+ total.remove(tid)
+ next.intersection_update(total)
+
+ if changed:
+ for mc in self.rq.worker:
+ self.rq.worker[mc].process.stdin.write(b"<newtaskhashes>" + pickle.dumps(bb.parse.siggen.get_taskhashes()) + b"</newtaskhashes>")
+ for mc in self.rq.fakeworker:
+ self.rq.fakeworker[mc].process.stdin.write(b"<newtaskhashes>" + pickle.dumps(bb.parse.siggen.get_taskhashes()) + b"</newtaskhashes>")
+
+ logger.debug(1, pprint.pformat("Tasks changed:\n%s" % (changed)))
+
+ for tid in changed:
+ if tid not in self.rqdata.runq_setscene_tids:
+ continue
+ valid = self.rq.validate_hashes(set([tid]), self.cooker.data, None, False)
+ if not valid:
+ continue
+ if tid in self.runq_running:
+ continue
+ if tid not in self.pending_migrations:
+ self.pending_migrations.add(tid)
+
+ for tid in self.pending_migrations.copy():
+ valid = True
+ # Check no tasks this covers are running
+ for dep in self.sqdata.sq_covered_tasks[tid]:
+ if dep in self.runq_running and dep not in self.runq_complete:
+ logger.debug(2, "Task %s is running which blocks setscene for %s from running" % (dep, tid))
+ valid = False
+ break
+ if not valid:
+ continue
+
+ self.pending_migrations.remove(tid)
+
+ if tid in self.tasks_scenequeue_done:
+ self.tasks_scenequeue_done.remove(tid)
+ for dep in self.sqdata.sq_covered_tasks[tid]:
+ if dep not in self.runq_complete:
+ if dep in self.tasks_scenequeue_done and dep not in self.sqdata.unskippable:
+ self.tasks_scenequeue_done.remove(dep)
+
+ if tid in self.sq_buildable:
+ self.sq_buildable.remove(tid)
+ if tid in self.sq_running:
+ self.sq_running.remove(tid)
+ if self.sqdata.sq_revdeps[tid].issubset(self.scenequeue_covered | self.scenequeue_notcovered):
+ if tid not in self.sq_buildable:
+ self.sq_buildable.add(tid)
+ if len(self.sqdata.sq_revdeps[tid]) == 0:
+ self.sq_buildable.add(tid)
+
+ if tid in self.sqdata.outrightfail:
+ self.sqdata.outrightfail.remove(tid)
+ if tid in self.scenequeue_notcovered:
+ self.scenequeue_notcovered.remove(tid)
+ if tid in self.scenequeue_covered:
+ self.scenequeue_covered.remove(tid)
+ if tid in self.scenequeue_notneeded:
+ self.scenequeue_notneeded.remove(tid)
+
+ (mc, fn, taskname, taskfn) = split_tid_mcfn(tid)
+ self.sqdata.stamps[tid] = bb.build.stampfile(taskname + "_setscene", self.rqdata.dataCaches[mc], taskfn, noextra=True)
+
+ if tid in self.stampcache:
+ del self.stampcache[tid]
+
+ if tid in self.build_stamps:
+ del self.build_stamps[tid]
+
+ logger.info("Setscene task %s now valid and being rerun" % tid)
+ self.sqdone = False
+
+ if changed:
+ self.update_holdofftasks()
def scenequeue_updatecounters(self, task, fail=False):
- for dep in self.sqdata.sq_deps[task]:
+
+ for dep in sorted(self.sqdata.sq_deps[task]):
if fail and task in self.sqdata.sq_harddeps and dep in self.sqdata.sq_harddeps[task]:
logger.debug(2, "%s was unavailable and is a hard dependency of %s so skipping" % (task, dep))
self.sq_task_failoutright(dep)
continue
- if task not in self.sqdata.sq_revdeps2[dep]:
- # May already have been removed by the fail case above
- continue
- self.sqdata.sq_revdeps2[dep].remove(task)
- if len(self.sqdata.sq_revdeps2[dep]) == 0:
- self.sq_buildable.add(dep)
+ if self.sqdata.sq_revdeps[dep].issubset(self.scenequeue_covered | self.scenequeue_notcovered):
+ if dep not in self.sq_buildable:
+ self.sq_buildable.add(dep)
next = set([task])
while next:
new = set()
- for t in next:
+ for t in sorted(next):
self.tasks_scenequeue_done.add(t)
# Look down the dependency chain for non-setscene things which this task depends on
# and mark as 'done'
@@ -2225,39 +2348,31 @@
continue
if self.rqdata.runtaskentries[dep].revdeps.issubset(self.tasks_scenequeue_done):
new.add(dep)
- #logger.warning(" Down: " + dep)
next = new
- if task in self.sqdata.unskippable:
- self.scenequeue_process_unskippable(task)
+ notcovered = set(self.scenequeue_notcovered)
+ notcovered |= self.cantskip
+ for tid in self.scenequeue_notcovered:
+ notcovered |= self.sqdata.sq_covered_tasks[tid]
+ notcovered |= self.sqdata.unskippable.difference(self.rqdata.runq_setscene_tids)
+ notcovered.intersection_update(self.tasks_scenequeue_done)
- if task in self.scenequeue_notcovered:
- logger.debug(1, 'Not skipping setscene task %s', task)
- self.scenequeue_process_notcovered(task)
- elif task in self.scenequeue_covered:
- logger.debug(1, 'Queued setscene task %s', task)
- self.coveredtopocess.add(task)
+ covered = set(self.scenequeue_covered)
+ for tid in self.scenequeue_covered:
+ covered |= self.sqdata.sq_covered_tasks[tid]
+ covered.difference_update(notcovered)
+ covered.intersection_update(self.tasks_scenequeue_done)
- for task in self.coveredtopocess.copy():
- if self.sqdata.sq_covered_tasks[task].issubset(self.tasks_scenequeue_done):
- logger.debug(1, 'Processing setscene task %s', task)
- covered = self.sqdata.sq_covered_tasks[task]
- covered.add(task)
+ for tid in notcovered | covered:
+ if len(self.rqdata.runtaskentries[tid].depends) == 0:
+ self.setbuildable(tid)
+ elif self.rqdata.runtaskentries[tid].depends.issubset(self.runq_complete):
+ self.setbuildable(tid)
- # If a task is in target_tids and isn't a setscene task, we can't skip it.
- cantskip = covered.intersection(self.rqdata.target_tids).difference(self.rqdata.runq_setscene_tids)
- for tid in cantskip:
- self.tasks_notcovered.add(tid)
- self.scenequeue_process_notcovered(tid)
- covered.difference_update(cantskip)
+ self.tasks_covered = covered
+ self.tasks_notcovered = notcovered
- # Remove notcovered tasks
- covered.difference_update(self.tasks_notcovered)
- self.tasks_covered.update(covered)
- self.coveredtopocess.remove(task)
- for tid in covered:
- if len(self.rqdata.runtaskentries[tid].depends) == 0:
- self.setbuildable(tid)
+ self.update_holdofftasks()
def sq_task_completeoutright(self, task):
"""
@@ -2268,7 +2383,6 @@
logger.debug(1, 'Found task %s which could be accelerated', task)
self.scenequeue_covered.add(task)
- self.tasks_covered.add(task)
self.scenequeue_updatecounters(task)
def sq_check_taskfail(self, task):
@@ -2289,7 +2403,6 @@
self.sq_stats.taskFailed()
bb.event.fire(sceneQueueTaskFailed(task, self.sq_stats, result, self), self.cfgData)
self.scenequeue_notcovered.add(task)
- self.tasks_notcovered.add(task)
self.scenequeue_updatecounters(task, True)
self.sq_check_taskfail(task)
@@ -2299,7 +2412,6 @@
self.sq_stats.taskSkipped()
self.sq_stats.taskCompleted()
self.scenequeue_notcovered.add(task)
- self.tasks_notcovered.add(task)
self.scenequeue_updatecounters(task, True)
def sq_task_skip(self, task):
@@ -2377,8 +2489,6 @@
self.sq_deps = {}
# SceneQueue reverse dependencies
self.sq_revdeps = {}
- # Copy of reverse dependencies used by sq processing code
- self.sq_revdeps2 = {}
# Injected inter-setscene task dependencies
self.sq_harddeps = {}
# Cache of stamp files so duplicates can't run in parallel
@@ -2458,27 +2568,28 @@
rqdata.init_progress_reporter.next_stage()
- # Build a list of setscene tasks which are "unskippable"
- # These are direct endpoints referenced by the build
+ # Build a list of tasks which are "unskippable"
+ # These are direct endpoints referenced by the build upto and including setscene tasks
# Take the build endpoints (no revdeps) and find the sstate tasks they depend upon
new = True
for tid in rqdata.runtaskentries:
if len(rqdata.runtaskentries[tid].revdeps) == 0:
sqdata.unskippable.add(tid)
+ sqdata.unskippable |= sqrq.cantskip
while new:
new = False
- for tid in sqdata.unskippable.copy():
+ orig = sqdata.unskippable.copy()
+ for tid in sorted(orig, reverse=True):
if tid in rqdata.runq_setscene_tids:
continue
- sqdata.unskippable.remove(tid)
if len(rqdata.runtaskentries[tid].depends) == 0:
# These are tasks which have no setscene tasks in their chain, need to mark as directly buildable
- sqrq.tasks_notcovered.add(tid)
- sqrq.tasks_scenequeue_done.add(tid)
sqrq.setbuildable(tid)
- sqrq.scenequeue_process_unskippable(tid)
sqdata.unskippable |= rqdata.runtaskentries[tid].depends
- new = True
+ if sqdata.unskippable != orig:
+ new = True
+
+ sqrq.tasks_scenequeue_done |= sqdata.unskippable.difference(rqdata.runq_setscene_tids)
rqdata.init_progress_reporter.next_stage(len(rqdata.runtaskentries))
@@ -2537,7 +2648,6 @@
# bb.warn("Task %s_setscene: is %s " % (tid, data))
sqdata.sq_revdeps = sq_revdeps_squash
- sqdata.sq_revdeps2 = copy.deepcopy(sqdata.sq_revdeps)
sqdata.sq_covered_tasks = sq_collated_deps
# Build reverse version of revdeps to populate deps structure
@@ -2562,7 +2672,7 @@
stamppresent = []
tocheck = set()
- for tid in sqdata.sq_revdeps:
+ for tid in sorted(sqdata.sq_revdeps):
(mc, fn, taskname, taskfn) = split_tid_mcfn(tid)
taskdep = rqdata.dataCaches[mc].task_deps[taskfn]
@@ -2595,7 +2705,7 @@
hashes = {}
for mc in sorted(multiconfigs):
- for tid in sqdata.sq_revdeps:
+ for tid in sorted(sqdata.sq_revdeps):
if mc_from_tid(tid) != mc:
continue
if tid not in valid_new and tid not in noexec and tid not in sqrq.scenequeue_notcovered:
@@ -2715,6 +2825,15 @@
runQueueEvent.__init__(self, task, stats, rq)
self.reason = reason
+class taskUniHashUpdate(bb.event.Event):
+ """
+ Base runQueue event class
+ """
+ def __init__(self, task, unihash):
+ self.taskid = task
+ self.unihash = unihash
+ bb.event.Event.__init__(self)
+
class runQueuePipe():
"""
Abstraction for a pipe between a worker thread and the server
@@ -2757,6 +2876,8 @@
except ValueError as e:
bb.msg.fatal("RunQueue", "failed load pickle '%s': '%s'" % (e, self.queue[7:index]))
bb.event.fire_from_worker(event, self.d)
+ if isinstance(event, taskUniHashUpdate):
+ self.rqexec.updated_taskhash_queue.append((event.taskid, event.unihash))
found = True
self.queue = self.queue[index+8:]
index = self.queue.find(b"</event>")