Skip to content

Commit 259fb52

Browse files
committed
perf(zaparoo): reduce launcher startup contention
1 parent 7a05c05 commit 259fb52

3 files changed

Lines changed: 98 additions & 56 deletions

File tree

scheduler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "scheduler.h"
22
#include <stdio.h>
3+
#include <unistd.h>
34
#include "libco.h"
45
#include "menu.h"
56
#include "user_io.h"
@@ -86,6 +87,8 @@ void scheduler_run(void)
8687
for (;;)
8788
{
8889
scheduler_schedule();
90+
if (alt_launcher_scheduler_sleep_enabled())
91+
usleep(100);
8992
}
9093

9194
co_delete(co_ui);

support/zaparoo/alt_launcher.cpp

Lines changed: 94 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,10 @@ uint16_t alt_launcher_fb_terminal_key(uint32_t mask, bool osd_button)
6868
static pid_t s_pid = 0;
6969
static int s_crash_count = 0;
7070
static unsigned long s_respawn_timer = 0;
71+
static unsigned long s_tty_deadline = 0;
7172
static unsigned long s_native_status_timer = 0;
7273
static unsigned long s_native_fb_mode_timer = 0;
74+
static unsigned long s_native_crt_finish_timer = 0;
7375
static bool s_gave_up = false;
7476
static bool s_init_pending = false;
7577
static bool s_native_crt = false;
@@ -228,21 +230,29 @@ static void disable_native_crt_path(void)
228230
video_fb_enable(0);
229231
set_vga_fb(0);
230232
set_launcher_fb_mode(8888, 1, 960, 720, 3840);
233+
s_tty_deadline = 0;
231234
s_native_status_timer = 0;
232235
s_native_fb_mode_timer = 0;
236+
s_native_crt_finish_timer = 0;
233237
}
234238

235-
static void enable_native_crt_path(void)
239+
static void prepare_native_crt_path(void)
236240
{
237241
set_vga_fb(0);
238242
video_fb_enable(0);
239243

240-
// Double-write with a settle window so the kernel module's 320x240 layout
241-
// is live before status[9] flips. Without this, the frontend renders for
242-
// up to a second under stale dims (the post-fork retry timer used to be
243-
// what eventually fixed the picture).
244244
set_native_crt_fb_mode(false);
245-
usleep(100000);
245+
s_native_crt_finish_timer = GetTimer(100);
246+
if (!s_native_crt_finish_timer) s_native_crt_finish_timer = 1;
247+
}
248+
249+
static void finish_native_crt_path(void)
250+
{
251+
// Double-write with a settle window so the kernel module's 320x240 layout
252+
// is live before status[9] flips. The child is already execing/loading,
253+
// but the FPGA keeps scanning the stock path until the native buffer is
254+
// blanked below.
255+
s_native_crt_finish_timer = 0;
246256
set_native_crt_fb_mode();
247257

248258
blank_native_crt_fb();
@@ -254,16 +264,6 @@ static void enable_native_crt_path(void)
254264
if (!s_native_fb_mode_timer) s_native_fb_mode_timer = 1;
255265
}
256266

257-
static void wait_launcher_tty_ready(pid_t pid)
258-
{
259-
for (int i = 0; i < 100; i++)
260-
{
261-
if (launcher_tty_ready(pid))
262-
return;
263-
usleep(10000);
264-
}
265-
}
266-
267267
static void return_to_normal_mode(void)
268268
{
269269
user_io_osd_key_enable(1);
@@ -282,6 +282,10 @@ static void reset_launcher_state(void)
282282
{
283283
s_pid = 0;
284284
s_respawn_timer = 0;
285+
s_tty_deadline = 0;
286+
s_native_status_timer = 0;
287+
s_native_fb_mode_timer = 0;
288+
s_native_crt_finish_timer = 0;
285289
s_crash_count = 0;
286290
s_gave_up = false;
287291
s_init_pending = false;
@@ -337,34 +341,71 @@ static void release_launcher_video(void)
337341
}
338342
}
339343

344+
static void exec_launcher_child(const char *path)
345+
{
346+
setenv("LC_ALL", "en_US.UTF-8", 1);
347+
setenv("HOME", "/root", 1);
348+
349+
cpu_set_t set;
350+
CPU_ZERO(&set);
351+
CPU_SET(0, &set);
352+
sched_setaffinity(0, sizeof(set), &set);
353+
354+
setsid();
355+
356+
int tty_fd = open(s_tty_path, O_RDWR);
357+
if (tty_fd >= 0)
358+
{
359+
ioctl(tty_fd, TIOCSCTTY, 0);
360+
dup2(tty_fd, STDIN_FILENO);
361+
dup2(tty_fd, STDOUT_FILENO);
362+
dup2(tty_fd, STDERR_FILENO);
363+
if (tty_fd > STDERR_FILENO)
364+
close(tty_fd);
365+
}
366+
367+
static const char clear[] = "\033[0m\033[?25l\033[37m\033[40m\033[2J\033[H";
368+
if (write(STDOUT_FILENO, clear, sizeof(clear) - 1) < 0) {}
369+
370+
if (s_native_crt)
371+
execl(path, path, "--crt", NULL);
372+
else
373+
execl(path, path, NULL);
374+
_exit(1);
375+
}
376+
377+
static void finalize_spawn(void)
378+
{
379+
s_tty_deadline = 0;
380+
video_chvt(s_vt);
381+
if (!s_native_crt)
382+
video_fb_enable(1);
383+
else
384+
{
385+
input_switch(0);
386+
user_io_status_set("[9]", 1);
387+
}
388+
389+
// The frontend grabs input as soon as it starts. If the OSD is still
390+
// up (e.g. user toggled CRT mode or hit Reboot from System Settings),
391+
// it would trap input with no way to dismiss it — drop it now.
392+
if (menu_present()) MenuHide();
393+
}
394+
340395
static void spawn(void)
341396
{
342397
char path[2100];
343398
strncpy(path, getFullPath(s_launcher_path), sizeof(path) - 1);
344399
path[sizeof(path) - 1] = '\0';
345400

346-
static const char cmd[] =
347-
"#!/bin/bash\n"
348-
"export LC_ALL=en_US.UTF-8\n"
349-
"export HOME=/root\n"
350-
"printf '\\033[0m\\033[?25l\\033[37m\\033[40m\\033[2J\\033[H'\n"
351-
"if [ \"$ALT_LAUNCHER_CRT\" = \"1\" ]; then\n"
352-
" exec \"$ALT_LAUNCHER_PATH\" --crt\n"
353-
"fi\n"
354-
"exec \"$ALT_LAUNCHER_PATH\"\n";
355-
356-
unlink("/tmp/alt_launcher");
357-
if (!FileSave("/tmp/alt_launcher", (void*)cmd, strlen(cmd)))
358-
return;
359-
360401
user_io_osd_key_enable(0);
361402
clear_launcher_tty();
362403

363404
printf("alt_launcher: native_crt=%d\n", s_native_crt);
364405
if (s_native_crt)
365406
{
366-
enable_native_crt_path();
367-
printf("alt_launcher: native CRT path enabled\n");
407+
prepare_native_crt_path();
408+
printf("alt_launcher: native CRT path prepared\n");
368409
}
369410
else
370411
{
@@ -384,39 +425,23 @@ static void spawn(void)
384425
printf("alt_launcher: spawned pid=%d path=%s\n", s_pid, path);
385426
if (!s_pid)
386427
{
387-
setenv("ALT_LAUNCHER_PATH", path, 1);
388-
setenv("ALT_LAUNCHER_CRT", s_native_crt ? "1" : "0", 1);
389-
cpu_set_t set;
390-
CPU_ZERO(&set);
391-
CPU_SET(0, &set);
392-
sched_setaffinity(0, sizeof(set), &set);
393-
setsid();
394-
execl("/sbin/agetty", "/sbin/agetty", "-a", "root", "-l",
395-
"/tmp/alt_launcher", "-i", "--nohostname", "-L", s_tty, "linux", NULL);
396-
_exit(1);
428+
exec_launcher_child(path);
397429
}
398430

399-
wait_launcher_tty_ready(s_pid);
400-
video_chvt(s_vt);
401-
if (!s_native_crt)
402-
video_fb_enable(1);
403-
else
404-
{
405-
input_switch(0);
406-
user_io_status_set("[9]", 1);
407-
}
408-
409-
// The frontend grabs input as soon as it starts. If the OSD is still
410-
// up (e.g. user toggled CRT mode or hit Reboot from System Settings),
411-
// it would trap input with no way to dismiss it — drop it now.
412-
if (menu_present()) MenuHide();
431+
s_tty_deadline = GetTimer(1000);
432+
if (!s_tty_deadline) s_tty_deadline = 1;
413433
}
414434

415435
bool alt_launcher_active(void)
416436
{
417437
return s_pid != 0;
418438
}
419439

440+
bool alt_launcher_scheduler_sleep_enabled(void)
441+
{
442+
return s_pid || s_init_pending || s_respawn_timer || s_tty_deadline || s_native_crt_finish_timer;
443+
}
444+
420445
bool alt_launcher_native_crt(void)
421446
{
422447
return s_native_crt && s_pid != 0;
@@ -469,6 +494,7 @@ void alt_launcher_init(bool native_crt)
469494
return;
470495
s_crash_count = 0;
471496
s_respawn_timer = 0;
497+
s_tty_deadline = 0;
472498
s_native_crt = native_crt;
473499
s_init_pending = true;
474500
}
@@ -486,6 +512,7 @@ void alt_launcher_prepare_for_script(void)
486512
wait_launcher_stopped(pid);
487513
user_io_osd_key_enable(1);
488514
s_respawn_timer = 0;
515+
s_tty_deadline = 0;
489516
s_crash_count = 0;
490517
s_init_pending = false;
491518
s_gave_up = false;
@@ -514,6 +541,12 @@ void alt_launcher_poll(void)
514541
{
515542
if (s_pid)
516543
{
544+
if (s_native_crt && s_native_crt_finish_timer && CheckTimer(s_native_crt_finish_timer))
545+
{
546+
finish_native_crt_path();
547+
printf("alt_launcher: native CRT path enabled\n");
548+
}
549+
517550
if (s_native_crt && s_native_status_timer && CheckTimer(s_native_status_timer))
518551
{
519552
user_io_status_set("[9]", 1);
@@ -531,6 +564,7 @@ void alt_launcher_poll(void)
531564
if (waitpid(s_pid, &status, WNOHANG) == s_pid)
532565
{
533566
s_pid = 0;
567+
s_tty_deadline = 0;
534568
user_io_osd_key_enable(1);
535569
bool exited = WIFEXITED(status);
536570
int exit_status = exited ? WEXITSTATUS(status) : 0;
@@ -565,7 +599,11 @@ void alt_launcher_poll(void)
565599
s_crash_count = 0;
566600
s_respawn_timer = GetTimer(1000);
567601
if (!s_respawn_timer) s_respawn_timer = 1;
602+
return;
568603
}
604+
605+
if (s_tty_deadline && !s_native_crt_finish_timer && (launcher_tty_ready(s_pid) || CheckTimer(s_tty_deadline)))
606+
finalize_spawn();
569607
return;
570608
}
571609

support/zaparoo/alt_launcher.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ void alt_launcher_resume_after_script(void);
1313
bool alt_launcher_native_crt(void);
1414
bool alt_launcher_active(void);
1515
bool alt_launcher_configured(void);
16+
bool alt_launcher_scheduler_sleep_enabled(void);
1617

1718
// Display centering: signed offsets clamped to -8..+7. Setters update the
1819
// in-memory cache, persist to the config dir, and push to the FPGA via

0 commit comments

Comments
 (0)