Skip to content

Speed up Dmod_Mgr_IsSystemModule/IsLoaded/IsEnabled - #326

Merged
JohnAmadis merged 3 commits into
developfrom
feature/mgr-check-loaded-modules-first
Oct 5, 2026
Merged

JohnAmadis merged 3 commits into
developfrom
feature/mgr-check-loaded-modules-first

Conversation

@JohnAmadis

@JohnAmadis JohnAmadis commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Dmod_Mgr_IsSystemModule() checks a module against every built-in input API, running Dmod_ApiSignature_IsModule() on each one. In dmod-boot that is 351 entries, ~105–137k instructions per call.

Dmod_Mgr_IsLoaded() and Dmod_Mgr_IsEnabled() called it first. So every Dmod_IsModuleLoaded(), Dmod_IsModuleEnabled() and Dmod_LoadModuleByName() paid for this scan, even for an ordinary module that was already loaded.

dmdevfs calls these several times per configured driver. In dmod-boot that was ~750 calls, ~226 ms of the boot in Renode.

Changes

1. Check loaded modules first

Dmod_Mgr_IsLoaded() and Dmod_Mgr_IsEnabled() now look the module up in the context table first (Dmod_Context_Get()). They fall back to Dmod_Mgr_IsSystemModule() only if the module is not there.

The result is the same as before; only the order of the two checks changed:

  • IsLoaded = loaded || system
  • IsEnabled = (loaded && enabled) || system

2. List of system module names built once

Dmod_Initialize() now calls Dmod_Mgr_BuildSystemModuleList(). It collects the module names of the built-in APIs once, into a single allocation (names packed one after another). In dmod-boot that is 7 names, 44 bytes.

Dmod_Mgr_IsSystemModule() then only compares the given name with this list.

  • The comparison is the same as in Dmod_ApiSignature_IsModule(): the module name of an API starts with the given name. Only signatures with the DMOD/DMBI/DMAL/DDIF prefixes count, as before.
  • If Dmod_Initialize() was not called (e.g. in unit tests), the list is built on first use.
  • Dmod_Deinitialize() frees it (Dmod_Mgr_FreeSystemModuleList()).
  • If the list cannot be allocated, the built-in APIs are checked one by one as before.

Tests

  • CI steps run locally (MODULE + SYSTEM build, x86_64):
    • the dmod_loader runs, including the non-existent module case;
    • dif_test and test_direct_access;
    • tests_dmod_manifest.
  • All 32 gtest unit test binaries pass.
  • New tests in tests_dmod_mgr (17/17 pass):
    • BuildSystemModuleList: the list can be built twice;
    • IsSystemModuleAfterFreeingList: the list is rebuilt after it has been freed;
    • IsSystemModuleForEveryBuiltinApi: every module named by a built-in API is still reported as a system module.

Measured on dmod-boot (Renode, STM32F746G-DISCO, virtual time)

Before Loaded modules first + name list
Dmod_Mgr_IsSystemModule calls during boot ~750 329 354
Time in Dmod_Mgr_IsSystemModule ~226 ms ~75 ms 0.4 ms (~560 instructions per call)
One GPIO pin configured 4.0 ms 2.6 ms —
Shell prompt 2052 ms 1892 ms 1788 ms
  • Building the list takes 0.8 ms, once, in Dmod_Initialize().
  • No new errors in the boot log.

🤖 Generated with Claude Code

https://claude.ai/code/session_01V9XGvT9zLJVAagoEVhYh9T

claude added 2 commits October 5, 2026 09:37
…bled

Dmod_Mgr_IsSystemModule() runs Dmod_ApiSignature_IsModule() over every
built-in input API - 351 entries in dmod-boot, ~137k instructions per
call. Dmod_Mgr_IsLoaded() and Dmod_Mgr_IsEnabled() called it first, so
every Dmod_IsModuleLoaded(), Dmod_IsModuleEnabled() and
Dmod_LoadModuleByName() paid that scan even for an ordinary module that
is already loaded. dmdevfs calls these several times per configured
driver: in dmod-boot it was 624 calls, ~185 ms of the driver
configuration in Renode.

Both functions now look the module up in the context table first and
only fall back to the system module check when it is not found there.
The result is the same - only the order of the two checks changed.

dmod-boot in Renode: one GPIO pin is configured in 2.6 ms instead of
4.0 ms, boot to the shell prompt 2052 ms -> 1892 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9XGvT9zLJVAagoEVhYh9T
Dmod_Mgr_IsSystemModule() ran Dmod_ApiSignature_IsModule() over every
built-in input API on each call - ~105k instructions per call even
after loaded modules are checked first, still ~330 calls and ~75 ms of
the boot of dmod-boot in Renode (required modules of every loaded
module, modules that are not loaded yet).

Dmod_Initialize() now builds the list of the module names of the
built-in APIs once (Dmod_Mgr_InitSystemModules), packed into a single
allocation - 7 names, 44 bytes in dmod-boot - and
Dmod_Mgr_IsSystemModule() only compares the name with those. The list
is built on first use if Dmod_Initialize() was not called, freed by
Dmod_Deinitialize(), and if it cannot be allocated the built-in APIs
are checked one by one as before. The comparison is the same as in
Dmod_ApiSignature_IsModule(): the module name of an API starts with the
given name.

dmod-boot in Renode: Dmod_Mgr_IsSystemModule() takes ~560 instructions
instead of ~105k (354 calls: 0.4 ms instead of ~75 ms), building the
list takes 0.8 ms once; boot to the shell prompt 1892 ms -> 1788 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9XGvT9zLJVAagoEVhYh9T
@JohnAmadis JohnAmadis changed the title Check loaded modules before system modules in Dmod_Mgr_IsLoaded/IsEnabled Speed up Dmod_Mgr_IsSystemModule/IsLoaded/IsEnabled Oct 5, 2026
Dmod_Mgr_InitSystemModules/DeinitSystemModules suggested that the
modules themselves are initialized; they only build and free the list
of the system module names, so they are now
Dmod_Mgr_BuildSystemModuleList/FreeSystemModuleList.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9XGvT9zLJVAagoEVhYh9T
@JohnAmadis
JohnAmadis merged commit 4c6b25b into develop Oct 5, 2026
6 checks passed
JohnAmadis pushed a commit to choco-technologies/dmod-boot that referenced this pull request Oct 5, 2026
dmod now checks loaded modules before system modules in
Dmod_Mgr_IsLoaded/IsEnabled, and looks system modules up in a list of
their names built once in Dmod_Initialize() instead of checking the
signature of every built-in API on each call
(choco-technologies/dmod#326).

Boot to the shell prompt in Renode, together with dmvfs and the
dmeth 1.0.4 release: 1558 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9XGvT9zLJVAagoEVhYh9T
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants