Add mixed-vendor GPU summary and fix startup heap corruption
Collect AMD amdgpu sysfs and optional NVIDIA nvidia-smi stats in the background, auto-detecting supported adapters in PCI order and rotating additional pairs alongside CPU/RAM. Explicit PCI selection and off mode remain supported; missing metrics render as N/A. Initialize the bitmap-only canvas locally instead of the ABI-dependent libg15render initializer: the installed TTF-enabled renderer wrote an 8-byte FreeType pointer past the smaller bitmap-only allocation, corrupting the heap before GPU threads started. Add collector, rendering and full-main regression tests.
This commit is contained in:
1 parent
076641c867
commit
7c06a8089d
12 files changed
+1417
-4
No files matched your search
@@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Full application startup/draw loop, real libgtop and bitmap renderer.
|
||||
* Only daemon transport is replaced. No TCP, USB, or input-device access.
|
||||
* Default: GPU off, three frames. Optional: runtime-test auto 21 verifies
|
||||
* real read-only GPU samples over twenty seconds (not a physical LCD test).
|
||||
*/
|
||||
#define main g15stats_application_main
|
||||
#include "../g15stats.c"
|
||||
#undef main
|
||||
#include <assert.h>
|
||||
|
||||
static unsigned frames, target = 3;
|
||||
static int peer = -1;
|
||||
|
||||
/* Catch the ABI-unsafe initializer even with a non-TTF renderer in CI.
|
||||
* Do not stub any bitmap drawing or host statistics functions. */
|
||||
void g15r_initCanvas(g15canvas *canvas)
|
||||
{
|
||||
(void)canvas;
|
||||
fputs("FAIL: bitmap client called ABI-dependent g15r_initCanvas\n", stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
int new_g15_screen(int type)
|
||||
{
|
||||
int pair[2];
|
||||
assert(type == G15_G15RBUF);
|
||||
assert(!socketpair(AF_UNIX, SOCK_STREAM, 0, pair));
|
||||
peer = pair[1]; /* No key events: actual keyboard thread blocks in recv. */
|
||||
return pair[0];
|
||||
}
|
||||
|
||||
int g15_send(int fd, char *buffer, unsigned int length)
|
||||
{
|
||||
unsigned ink = 0;
|
||||
gpu_frame frame = gpu_snapshot();
|
||||
(void)fd;
|
||||
assert(length == G15_BUFFER_LEN);
|
||||
for (unsigned i = 0; i < 160 * 43 / 8; i++) ink += !!buffer[i];
|
||||
assert(ink);
|
||||
fprintf(stderr, "runtime frame %u: %u ink bytes, %zu GPUs\n",
|
||||
++frames, ink, frame.count);
|
||||
if (frames == target) {
|
||||
glibtop_cpu cpu;
|
||||
glibtop_mem mem;
|
||||
glibtop_get_cpu(&cpu);
|
||||
glibtop_get_mem(&mem);
|
||||
assert(cpu.total > 0 && mem.total > 0 && mem.free <= mem.total);
|
||||
fprintf(stderr, "host stats: CPU ticks=%llu RAM total=%llu free=%llu\n",
|
||||
(unsigned long long)cpu.total, (unsigned long long)mem.total,
|
||||
(unsigned long long)mem.free);
|
||||
for (size_t i = 0; i < frame.count; i++) {
|
||||
gpu_sample s = frame.samples[i];
|
||||
fprintf(stderr, "%s: busy=%lld used=%lld total=%lld temp=%lld\n",
|
||||
gpu_devices[i].bus, s.busy, s.used, s.total, s.temp);
|
||||
assert(s.busy >= 0 && s.used >= 0 && s.total > 0 && s.temp != LLONG_MIN);
|
||||
}
|
||||
assert(!gpu_stop());
|
||||
/* Full main is intentionally endless. Terminate without closing the
|
||||
* peer first (which would wake the legacy keyboard loop with EOF). */
|
||||
fputs("PASS full main, isolated transport, real renderer/collectors\n", stderr);
|
||||
_Exit(0);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *args[] = {"g15stats", "--gpu", argc > 1 ? argv[1] : "off", NULL};
|
||||
if (argc > 2) {
|
||||
long n = gpu_number(argv[2], 3, 30, -1);
|
||||
assert(n >= 3);
|
||||
target = (unsigned)n;
|
||||
}
|
||||
alarm(target + 10); /* Failure bound, not a passing timeout. */
|
||||
return g15stats_application_main(3, args);
|
||||
}
|
||||
Reference in new issue
Block a user