* [PATCH 2/7] pybootchartgui: Update to v5.0.3
2026-06-19 7:21 [PATCH 0/7] Update OE-core libs WIC to v5.0.3 Anton Mikanovich
2026-06-19 7:21 ` [PATCH 1/7] wic: Update libs " Anton Mikanovich
@ 2026-06-19 7:21 ` Anton Mikanovich
2026-06-19 7:21 ` [PATCH 3/7] Revert "patch: Set dummy credentials for git notes" Anton Mikanovich
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Anton Mikanovich @ 2026-06-19 7:21 UTC (permalink / raw)
To: isar-users; +Cc: Anton Mikanovich
OE-core Revision: 236ac1b43308df722a78d3aa20aef065dfae5b2b.
Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
---
scripts/pybootchartgui/pybootchartgui/draw.py | 156 +++++++++++++++++-
.../pybootchartgui/pybootchartgui/parsing.py | 35 +++-
.../pybootchartgui/pybootchartgui/samples.py | 25 +++
3 files changed, 207 insertions(+), 9 deletions(-)
diff --git a/scripts/pybootchartgui/pybootchartgui/draw.py b/scripts/pybootchartgui/pybootchartgui/draw.py
index 29eb7505..c6e67833 100644
--- a/scripts/pybootchartgui/pybootchartgui/draw.py
+++ b/scripts/pybootchartgui/pybootchartgui/draw.py
@@ -80,6 +80,22 @@ MEM_BUFFERS_COLOR = (0.4, 0.4, 0.4, 0.3)
# Swap color
MEM_SWAP_COLOR = DISK_TPUT_COLOR
+# avg10 CPU pressure color
+CPU_PRESSURE_AVG10_COLOR = (0.0, 0.0, 0.0, 1.0)
+# delta total CPU pressure color
+CPU_PRESSURE_TOTAL_COLOR = CPU_COLOR
+# avg10 IO pressure color
+IO_PRESSURE_AVG10_COLOR = (0.0, 0.0, 0.0, 1.0)
+# delta total IO pressure color
+IO_PRESSURE_TOTAL_COLOR = IO_COLOR
+# avg10 memory pressure color
+MEM_PRESSURE_AVG10_COLOR = (0.0, 0.0, 0.0, 1.0)
+# delta total memory pressure color
+MEM_PRESSURE_TOTAL_COLOR = DISK_TPUT_COLOR
+
+
+
+
# Process border color.
PROC_BORDER_COLOR = (0.71, 0.71, 0.71, 1.0)
# Waiting process color.
@@ -267,7 +283,10 @@ def draw_chart(ctx, color, fill, chart_bounds, data, proc_tree, data_range):
# avoid divide by zero
if max_y == 0:
max_y = 1.0
- xscale = float (chart_bounds[2]) / (max_x - x_shift)
+ if (max_x - x_shift):
+ xscale = float (chart_bounds[2]) / (max_x - x_shift)
+ else:
+ xscale = float (chart_bounds[2])
# If data_range is given, scale the chart so that the value range in
# data_range matches the chart bounds exactly.
# Otherwise, scale so that the actual data matches the chart bounds.
@@ -337,6 +356,12 @@ def extents(options, xscale, trace):
h += 30 + bar_h
if trace.disk_stats:
h += 30 + bar_h
+ if trace.cpu_pressure:
+ h += 30 + bar_h
+ if trace.io_pressure:
+ h += 30 + bar_h
+ if trace.mem_pressure:
+ h += 30 + bar_h
if trace.monitor_disk:
h += 30 + bar_h
if trace.mem_stats:
@@ -412,6 +437,108 @@ def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
curr_y = curr_y + 30 + bar_h
+ # render CPU pressure chart
+ if trace.cpu_pressure:
+ max_sample_avg = max (trace.cpu_pressure, key = lambda s: s.avg10)
+ max_sample_total = max (trace.cpu_pressure, key = lambda s: s.deltaTotal)
+ draw_legend_line(ctx, "avg10 CPU Pressure (max %d%%)" % (max_sample_avg.avg10), CPU_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
+ draw_legend_box(ctx, "delta total CPU Pressure (max %d)" % (max_sample_total.deltaTotal), CPU_PRESSURE_TOTAL_COLOR, off_x + 240, curr_y+20, leg_s)
+
+ # render delta total cpu
+ chart_rect = (off_x, curr_y+30, w, bar_h)
+ if clip_visible (clip, chart_rect):
+ draw_box_ticks (ctx, chart_rect, sec_w)
+ draw_annotations (ctx, proc_tree, trace.times, chart_rect)
+ draw_chart (ctx, CPU_PRESSURE_TOTAL_COLOR, True, chart_rect, \
+ [(sample.time, sample.deltaTotal) for sample in trace.cpu_pressure], \
+ proc_tree, None)
+
+ # render avg10 cpu
+ if clip_visible (clip, chart_rect):
+ draw_chart (ctx, CPU_PRESSURE_AVG10_COLOR, False, chart_rect, \
+ [(sample.time, sample.avg10) for sample in trace.cpu_pressure], \
+ proc_tree, None)
+
+ pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
+
+ shift_x, shift_y = -20, 20
+ if (pos_x < off_x + 245):
+ shift_x, shift_y = 5, 40
+
+
+ label = "%d%%" % (max_sample_avg.avg10)
+ draw_text (ctx, label, CPU_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
+
+ curr_y = curr_y + 30 + bar_h
+
+ # render I/O pressure chart
+ if trace.io_pressure:
+ max_sample_avg = max (trace.io_pressure, key = lambda s: s.avg10)
+ max_sample_total = max (trace.io_pressure, key = lambda s: s.deltaTotal)
+ draw_legend_line(ctx, "avg10 I/O Pressure (max %d%%)" % (max_sample_avg.avg10), IO_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
+ draw_legend_box(ctx, "delta total I/O Pressure (max %d)" % (max_sample_total.deltaTotal), IO_PRESSURE_TOTAL_COLOR, off_x + 240, curr_y+20, leg_s)
+
+ # render delta total io
+ chart_rect = (off_x, curr_y+30, w, bar_h)
+ if clip_visible (clip, chart_rect):
+ draw_box_ticks (ctx, chart_rect, sec_w)
+ draw_annotations (ctx, proc_tree, trace.times, chart_rect)
+ draw_chart (ctx, IO_PRESSURE_TOTAL_COLOR, True, chart_rect, \
+ [(sample.time, sample.deltaTotal) for sample in trace.io_pressure], \
+ proc_tree, None)
+
+ # render avg10 io
+ if clip_visible (clip, chart_rect):
+ draw_chart (ctx, IO_PRESSURE_AVG10_COLOR, False, chart_rect, \
+ [(sample.time, sample.avg10) for sample in trace.io_pressure], \
+ proc_tree, None)
+
+ pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
+
+ shift_x, shift_y = -20, 20
+ if (pos_x < off_x + 245):
+ shift_x, shift_y = 5, 40
+
+
+ label = "%d%%" % (max_sample_avg.avg10)
+ draw_text (ctx, label, IO_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
+
+ curr_y = curr_y + 30 + bar_h
+
+ # render MEM pressure chart
+ if trace.mem_pressure:
+ max_sample_avg = max (trace.mem_pressure, key = lambda s: s.avg10)
+ max_sample_total = max (trace.mem_pressure, key = lambda s: s.deltaTotal)
+ draw_legend_line(ctx, "avg10 MEM Pressure (max %d%%)" % (max_sample_avg.avg10), MEM_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
+ draw_legend_box(ctx, "delta total MEM Pressure (max %d)" % (max_sample_total.deltaTotal), MEM_PRESSURE_TOTAL_COLOR, off_x + 240, curr_y+20, leg_s)
+
+ # render delta total mem
+ chart_rect = (off_x, curr_y+30, w, bar_h)
+ if clip_visible (clip, chart_rect):
+ draw_box_ticks (ctx, chart_rect, sec_w)
+ draw_annotations (ctx, proc_tree, trace.times, chart_rect)
+ draw_chart (ctx, MEM_PRESSURE_TOTAL_COLOR, True, chart_rect, \
+ [(sample.time, sample.deltaTotal) for sample in trace.mem_pressure], \
+ proc_tree, None)
+
+ # render avg10 mem
+ if clip_visible (clip, chart_rect):
+ draw_chart (ctx, MEM_PRESSURE_AVG10_COLOR, False, chart_rect, \
+ [(sample.time, sample.avg10) for sample in trace.mem_pressure], \
+ proc_tree, None)
+
+ pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
+
+ shift_x, shift_y = -20, 20
+ if (pos_x < off_x + 245):
+ shift_x, shift_y = 5, 40
+
+
+ label = "%d%%" % (max_sample_avg.avg10)
+ draw_text (ctx, label, MEM_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
+
+ curr_y = curr_y + 30 + bar_h
+
# render disk space usage
#
# Draws the amount of disk space used on each volume relative to the
@@ -493,8 +620,8 @@ def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
return curr_y
-def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
- chart_rect = [off_x, curr_y+header_h, w, h - curr_y - 1 * off_y - header_h ]
+def render_processes_chart(ctx, options, trace, curr_y, width, h, sec_w):
+ chart_rect = [off_x, curr_y+header_h, width, h - curr_y - 1 * off_y - header_h ]
draw_legend_box (ctx, "Configure", \
TASK_COLOR_CONFIGURE, off_x , curr_y + 45, leg_s)
@@ -519,8 +646,9 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
offset = trace.min or min(trace.start.keys())
for start in sorted(trace.start.keys()):
for process in sorted(trace.start[start]):
+ elapsed_time = trace.processes[process][1] - start
if not options.app_options.show_all and \
- trace.processes[process][1] - start < options.app_options.mintime:
+ elapsed_time < options.app_options.mintime:
continue
task = process.split(":")[1]
@@ -529,14 +657,23 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
#print(s)
x = chart_rect[0] + (start - offset) * sec_w
- w = ((trace.processes[process][1] - start) * sec_w)
+ w = elapsed_time * sec_w
+
+ def set_alfa(color, alfa):
+ clist = list(color)
+ clist[-1] = alfa
+ return tuple(clist)
#print("proc at %s %s %s %s" % (x, y, w, proc_h))
col = None
if task == "do_compile":
col = TASK_COLOR_COMPILE
+ elif "do_compile" in task:
+ col = set_alfa(TASK_COLOR_COMPILE, 0.25)
elif task == "do_configure":
col = TASK_COLOR_CONFIGURE
+ elif "do_configure" in task:
+ col = set_alfa(TASK_COLOR_CONFIGURE, 0.25)
elif task == "do_install":
col = TASK_COLOR_INSTALL
elif task == "do_populate_sysroot":
@@ -554,7 +691,10 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
draw_fill_rect(ctx, col, (x, y, w, proc_h))
draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))
- draw_label_in_box(ctx, PROC_TEXT_COLOR, process, x, y + proc_h - 4, w, proc_h)
+ # Show elapsed time for each task
+ process = "%ds %s" % (elapsed_time, process)
+ draw_label_in_box(ctx, PROC_TEXT_COLOR, process, x, y + proc_h - 4, w, width)
+
y = y + proc_h
return curr_y
@@ -695,7 +835,7 @@ def draw_processes_recursively(ctx, proc, proc_tree, y, proc_h, rect, clip) :
cmdString = proc.cmd
else:
cmdString = ''
- if (OPTIONS.show_pid or OPTIONS.show_all) and ipid is not 0:
+ if (OPTIONS.show_pid or OPTIONS.show_all) and ipid != 0:
cmdString = cmdString + " [" + str(ipid // 1000) + "]"
if OPTIONS.show_all:
if proc.args:
@@ -793,7 +933,7 @@ class CumlSample:
if self.color is None:
i = self.next() % HSV_MAX_MOD
h = 0.0
- if i is not 0:
+ if i != 0:
h = (1.0 * i) / HSV_MAX_MOD
s = 0.5
v = 1.0
diff --git a/scripts/pybootchartgui/pybootchartgui/parsing.py b/scripts/pybootchartgui/pybootchartgui/parsing.py
index b42dac6b..63a53b6b 100644
--- a/scripts/pybootchartgui/pybootchartgui/parsing.py
+++ b/scripts/pybootchartgui/pybootchartgui/parsing.py
@@ -49,6 +49,9 @@ class Trace:
self.parent_map = None
self.mem_stats = []
self.monitor_disk = None
+ self.cpu_pressure = []
+ self.io_pressure = []
+ self.mem_pressure = []
self.times = [] # Always empty, but expected by draw.py when drawing system charts.
if len(paths):
@@ -128,7 +131,7 @@ class Trace:
def compile(self, writer):
def find_parent_id_for(pid):
- if pid is 0:
+ if pid == 0:
return 0
ppid = self.parent_map.get(pid)
if ppid:
@@ -554,6 +557,29 @@ def _parse_monitor_disk_log(file):
return disk_stats
+def _parse_pressure_logs(file, filename):
+ """
+ Parse file for "some" pressure with 'avg10', 'avg60' 'avg300' and delta total values
+ (in that order) directly stored on one line for both CPU and IO, based on filename.
+ """
+ pressure_stats = []
+ if filename == "cpu.log":
+ SamplingClass = CPUPressureSample
+ elif filename == "memory.log":
+ SamplingClass = MemPressureSample
+ else:
+ SamplingClass = IOPressureSample
+ for time, lines in _parse_timed_blocks(file):
+ for line in lines:
+ if not line: continue
+ tokens = line.split()
+ avg10 = float(tokens[0])
+ avg60 = float(tokens[1])
+ avg300 = float(tokens[2])
+ delta = float(tokens[3])
+ pressure_stats.append(SamplingClass(time, avg10, avg60, avg300, delta))
+
+ return pressure_stats
# if we boot the kernel with: initcall_debug printk.time=1 we can
# get all manner of interesting data from the dmesg output
@@ -741,6 +767,13 @@ def _do_parse(writer, state, filename, file):
state.cmdline = _parse_cmdline_log(writer, file)
elif name == "monitor_disk.log":
state.monitor_disk = _parse_monitor_disk_log(file)
+ #pressure logs are in a subdirectory
+ elif name == "cpu.log":
+ state.cpu_pressure = _parse_pressure_logs(file, name)
+ elif name == "io.log":
+ state.io_pressure = _parse_pressure_logs(file, name)
+ elif name == "memory.log":
+ state.mem_pressure = _parse_pressure_logs(file, name)
elif not filename.endswith('.log'):
_parse_bitbake_buildstats(writer, state, filename, file)
t2 = time.process_time()
diff --git a/scripts/pybootchartgui/pybootchartgui/samples.py b/scripts/pybootchartgui/pybootchartgui/samples.py
index 9fc309b3..a70d8a5a 100644
--- a/scripts/pybootchartgui/pybootchartgui/samples.py
+++ b/scripts/pybootchartgui/pybootchartgui/samples.py
@@ -37,6 +37,31 @@ class CPUSample:
return str(self.time) + "\t" + str(self.user) + "\t" + \
str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap)
+class CPUPressureSample:
+ def __init__(self, time, avg10, avg60, avg300, deltaTotal):
+ self.time = time
+ self.avg10 = avg10
+ self.avg60 = avg60
+ self.avg300 = avg300
+ self.deltaTotal = deltaTotal
+
+class IOPressureSample:
+ def __init__(self, time, avg10, avg60, avg300, deltaTotal):
+ self.time = time
+ self.avg10 = avg10
+ self.avg60 = avg60
+ self.avg300 = avg300
+ self.deltaTotal = deltaTotal
+
+class MemPressureSample:
+ def __init__(self, time, avg10, avg60, avg300, deltaTotal):
+ self.time = time
+ self.avg10 = avg10
+ self.avg60 = avg60
+ self.avg300 = avg300
+ self.deltaTotal = deltaTotal
+
+
class MemSample:
used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',)
--
2.43.0
--
You received this message because you are subscribed to the Google Groups "isar-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/isar-users/20260619072238.52120-3-amikan%40ilbers.de.
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 5/7] meta: Update OE-libs to v5.0.3
2026-06-19 7:21 [PATCH 0/7] Update OE-core libs WIC to v5.0.3 Anton Mikanovich
` (3 preceding siblings ...)
2026-06-19 7:21 ` [PATCH 4/7] Revert "devshell: Use different termination test to avoid warnings" Anton Mikanovich
@ 2026-06-19 7:21 ` Anton Mikanovich
2026-06-19 7:21 ` [PATCH 6/7] Revert "Revert "patch: Set dummy credentials for git notes"" Anton Mikanovich
2026-06-19 7:21 ` [PATCH 7/7] Revert "Revert "devshell: Use different termination test to avoid warnings"" Anton Mikanovich
6 siblings, 0 replies; 8+ messages in thread
From: Anton Mikanovich @ 2026-06-19 7:21 UTC (permalink / raw)
To: isar-users; +Cc: Anton Mikanovich
OE-core Revision: 236ac1b43308df722a78d3aa20aef065dfae5b2b.
Following changes are left because they are still needed in Isar:
9a714f6e patch: Set dummy credentials for git notes
68f299d0 devshell: Use different termination test to avoid warnings
Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
---
meta/lib/buildstats.py | 4 +-
meta/lib/oe/classutils.py | 2 +-
meta/lib/oe/data.py | 2 +-
meta/lib/oe/gpg_sign.py | 2 +-
meta/lib/oe/maketype.py | 2 +-
meta/lib/oe/patch.py | 2 +-
meta/lib/oe/path.py | 2 +-
meta/lib/oe/reproducible.py | 2 +-
meta/lib/oe/sstatesig.py | 2 +-
meta/lib/oe/terminal.py | 2 +-
meta/lib/oe/types.py | 2 +-
meta/lib/oe/utils.py | 100 ++++++++++--------------------------
12 files changed, 39 insertions(+), 85 deletions(-)
diff --git a/meta/lib/buildstats.py b/meta/lib/buildstats.py
index fe801a28..1ffe6798 100644
--- a/meta/lib/buildstats.py
+++ b/meta/lib/buildstats.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
@@ -212,4 +212,4 @@ class SystemStats:
b'\n')
self.last_disk_monitor = now
retval = True
- return retval
+ return retval
\ No newline at end of file
diff --git a/meta/lib/oe/classutils.py b/meta/lib/oe/classutils.py
index d879191d..ec3f6ad7 100644
--- a/meta/lib/oe/classutils.py
+++ b/meta/lib/oe/classutils.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/data.py b/meta/lib/oe/data.py
index b832e9b3..37121cfa 100644
--- a/meta/lib/oe/data.py
+++ b/meta/lib/oe/data.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/gpg_sign.py b/meta/lib/oe/gpg_sign.py
index 7a9cec94..ede6186c 100644
--- a/meta/lib/oe/gpg_sign.py
+++ b/meta/lib/oe/gpg_sign.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/maketype.py b/meta/lib/oe/maketype.py
index a9a1dd7b..7a83bdf6 100644
--- a/meta/lib/oe/maketype.py
+++ b/meta/lib/oe/maketype.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/patch.py b/meta/lib/oe/patch.py
index 35734a0d..60a0cc82 100644
--- a/meta/lib/oe/patch.py
+++ b/meta/lib/oe/patch.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/path.py b/meta/lib/oe/path.py
index 68dcb595..5d21cdcb 100644
--- a/meta/lib/oe/path.py
+++ b/meta/lib/oe/path.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/reproducible.py b/meta/lib/oe/reproducible.py
index 06a4b5fc..448befce 100644
--- a/meta/lib/oe/reproducible.py
+++ b/meta/lib/oe/reproducible.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py
index 63202204..a46e5502 100644
--- a/meta/lib/oe/sstatesig.py
+++ b/meta/lib/oe/sstatesig.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/terminal.py b/meta/lib/oe/terminal.py
index 2ae7a45a..4412bc14 100644
--- a/meta/lib/oe/terminal.py
+++ b/meta/lib/oe/terminal.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/types.py b/meta/lib/oe/types.py
index 4927fbc5..b929afb1 100644
--- a/meta/lib/oe/types.py
+++ b/meta/lib/oe/types.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
diff --git a/meta/lib/oe/utils.py b/meta/lib/oe/utils.py
index 9455aadb..14a7d07e 100644
--- a/meta/lib/oe/utils.py
+++ b/meta/lib/oe/utils.py
@@ -1,5 +1,5 @@
#
-# Imported from openembedded-core
+# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
@@ -7,6 +7,7 @@
import subprocess
import multiprocessing
import traceback
+import errno
def read_file(filename):
try:
@@ -258,16 +259,23 @@ def execute_pre_post_process(d, cmds):
if cmds is None:
return
- for cmd in cmds.strip().split(';'):
- cmd = cmd.strip()
- if cmd != '':
- bb.note("Executing %s ..." % cmd)
- bb.build.exec_func(cmd, d)
+ cmds = cmds.replace(";", " ")
-# For each item in items, call the function 'target' with item as the first
+ for cmd in cmds.split():
+ bb.note("Executing %s ..." % cmd)
+ bb.build.exec_func(cmd, d)
+
+def get_bb_number_threads(d):
+ return int(d.getVar("BB_NUMBER_THREADS") or os.cpu_count() or 1)
+
+def multiprocess_launch(target, items, d, extraargs=None):
+ max_process = get_bb_number_threads(d)
+ return multiprocess_launch_mp(target, items, max_process, extraargs)
+
+# For each item in items, call the function 'target' with item as the first
# argument, extraargs as the other arguments and handle any exceptions in the
# parent thread
-def multiprocess_launch(target, items, d, extraargs=None):
+def multiprocess_launch_mp(target, items, max_process, extraargs=None):
class ProcessLaunch(multiprocessing.Process):
def __init__(self, *args, **kwargs):
@@ -302,7 +310,6 @@ def multiprocess_launch(target, items, d, extraargs=None):
self.update()
return self._result
- max_process = int(d.getVar("BB_NUMBER_THREADS") or os.cpu_count() or 1)
launched = []
errors = []
results = []
@@ -475,70 +482,6 @@ def get_multilib_datastore(variant, d):
localdata.setVar("MLPREFIX", "")
return localdata
-#
-# Python 2.7 doesn't have threaded pools (just multiprocessing)
-# so implement a version here
-#
-
-from queue import Queue
-from threading import Thread
-
-class ThreadedWorker(Thread):
- """Thread executing tasks from a given tasks queue"""
- def __init__(self, tasks, worker_init, worker_end, name=None):
- Thread.__init__(self, name=name)
- self.tasks = tasks
- self.daemon = True
-
- self.worker_init = worker_init
- self.worker_end = worker_end
-
- def run(self):
- from queue import Empty
-
- if self.worker_init is not None:
- self.worker_init(self)
-
- while True:
- try:
- func, args, kargs = self.tasks.get(block=False)
- except Empty:
- if self.worker_end is not None:
- self.worker_end(self)
- break
-
- try:
- func(self, *args, **kargs)
- except Exception as e:
- # Eat all exceptions
- bb.mainlogger.debug("Worker task raised %s" % e, exc_info=e)
- finally:
- self.tasks.task_done()
-
-class ThreadedPool:
- """Pool of threads consuming tasks from a queue"""
- def __init__(self, num_workers, num_tasks, worker_init=None, worker_end=None, name="ThreadedPool-"):
- self.tasks = Queue(num_tasks)
- self.workers = []
-
- for i in range(num_workers):
- worker = ThreadedWorker(self.tasks, worker_init, worker_end, name=name + str(i))
- self.workers.append(worker)
-
- def start(self):
- for worker in self.workers:
- worker.start()
-
- def add_task(self, func, *args, **kargs):
- """Add a task to the queue"""
- self.tasks.put((func, args, kargs))
-
- def wait_completion(self):
- """Wait for completion of all the tasks in the queue"""
- self.tasks.join()
- for worker in self.workers:
- worker.join()
-
class ImageQAFailed(Exception):
def __init__(self, description, name=None, logfile=None):
self.description = description
@@ -586,3 +529,14 @@ def directory_size(root, blocksize=4096):
total += sum(roundup(getsize(os.path.join(root, name))) for name in files)
total += roundup(getsize(root))
return total
+
+# Update the mtime of a file, skip if permission/read-only issues
+def touch(filename):
+ try:
+ os.utime(filename, None)
+ except PermissionError:
+ pass
+ except OSError as e:
+ # Handle read-only file systems gracefully
+ if e.errno != errno.EROFS:
+ raise e
--
2.43.0
--
You received this message because you are subscribed to the Google Groups "isar-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/isar-users/20260619072238.52120-6-amikan%40ilbers.de.
^ permalink raw reply [flat|nested] 8+ messages in thread