Deduplicate minipal header helpers - #132113
Merged
Merged
Conversation
|
Azure Pipelines: Successfully started running 4 pipeline(s). 12 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR deduplicates several minipal helper implementations by moving them out of headers into single .c translation units, reducing per-TU duplication (including TLS) and improving call-stack visibility for these helpers.
Changes:
- Move
thread,getexepath, andentrypointshelper implementations from headers to new.cfiles with exported prototypes. - Add minipal sources (
*.c) to the minipal build and adjustSystem.IO.Compression.Nativeto link againstminipal. - Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably
ospagesize.handcpuid.h).
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/minipal/thread.h | Replaces header inlines with prototypes + shared TLS declaration. |
| src/native/minipal/thread.c | New implementation file for thread ID helpers and thread naming. |
| src/native/minipal/ospagesize.h | Adds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms. |
| src/native/minipal/ospagesize.c | Refactors to include header first and conditionally compile POSIX implementation. |
| src/native/minipal/getexepath.h | Replaces header inline with prototype for external implementation. |
| src/native/minipal/getexepath.c | New implementation file for executable path resolution across platforms. |
| src/native/minipal/entrypoints.h | Replaces header inline resolver with exported prototype. |
| src/native/minipal/entrypoints.c | New implementation file for minipal_resolve_dllimport. |
| src/native/minipal/cpuid.h | Adds MINIPAL_CPUID_* inline control macro. |
| src/native/minipal/cpuid.c | New compilation unit to host cpuid fallback implementations. |
| src/native/minipal/CMakeLists.txt | Adds new .c sources to minipal build outputs. |
| src/native/libs/System.IO.Compression.Native/CMakeLists.txt | Links System.IO.Compression.Native against minipal to satisfy new out-of-line symbols. |
jkotas
reviewed
Aug 11, 2026
am11
reviewed
Aug 11, 2026
am11
reviewed
Aug 11, 2026
Link the shared library against minipal so externally defined helpers are resolved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep helper implementations inline in headers while providing one external definition for callers when the compiler does not inline them. Move the shared thread ID TLS cache to thread.c. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep minipal_getexepath inline for callers while providing one external fallback definition when the compiler does not inline it. Use a target-platform condition for the Linux auxv fallback because HAVE_GETAUXVAL is configured separately by each consumer. This ensures the inline and external definitions compile the same logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep small platform helpers inline for callers while providing one external fallback definition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mdh1418
force-pushed
the
deduplicate-minipal-header-helpers
branch
from
August 13, 2026 01:53
4bc3b14 to
670f632
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
src/native/minipal/thread.h:92
minipal_get_current_thread_idis used from multiple C source files (e.g., System.Native). With external-linkageinlinein a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoringstatic inlinehere avoids potential link-time failures for non-inlined builds.
inline size_t minipal_get_current_thread_id(void)
src/native/minipal/thread.h:114
- Same linkage concern as
minipal_get_current_thread_id:minipal_set_thread_nameis called from other C translation units. If it stays header-defined, it should keep internal linkage (static inline) to avoid relying on C inline/linkage corner cases.
inline int minipal_set_thread_name(pthread_t thread, const char* name)
src/native/minipal/getexepath.h:188
- This block now calls
getauxvalbased only onAT_EXECFN, butgetauxvalavailability is already feature-tested viaHAVE_GETAUXVALin multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains whereAT_EXECFNis defined butgetauxvalis unavailable. Guard the fallback onHAVE_GETAUXVALas well.
#if defined(AT_EXECFN)
// fallback to AT_EXECFN, which does not work properly in rare cases
// when .NET process is set as interpreter (shebang).
const char* exePath = (const char *)(getauxval(AT_EXECFN));
if (exePath)
src/native/minipal/thread.c:17
- These
externdeclarations don’t provide a definition for the header-definedinlinefunctions and are redundant with the declarations/definitions already visible via#include "thread.h". They also become actively misleading if the header switches back tostatic inline(linkage mismatch). Consider removing them.
extern size_t minipal_get_current_thread_id_no_cache(void);
extern size_t minipal_get_current_thread_id(void);
extern int minipal_set_thread_name(pthread_t thread, const char* name);
3 tasks
jkotas
reviewed
Aug 13, 2026
jkotas
reviewed
Aug 13, 2026
Move executable path resolution, uncached thread ID lookup, and thread naming into their source files. Keep only the cached thread ID fast path inline, and configure getauxval availability directly for minipal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
|
Build breaks |
Use the MSVC-supported _strdup spelling in the Windows executable-path implementation to avoid C4996 when getexepath.c is compiled as part of minipal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jkotas
approved these changes
Aug 13, 2026
Member
Author
This was referenced Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #131991 (comment)
Deduplicate the helper functions currently defined with internal linkage in src/native/minipal headers.
The affected helpers remain defined as inline in their headers so callers can inline them, but paired .c files now provide one external fallback definition for cases where the compiler emits a call instead. In C, each paired source file does this by including the inline definition and then redeclaring the function with extern.
C inline linkage
A plain C inline definition does not necessarily emit an externally linkable function. At higher optimization levels, the compiler may substitute the header implementation directly at the call site, but at lower optimization levels, or whenever it chooses not to inline, the generated code may call an external symbol.
Each paired source file therefore follows this pattern:
The header supplies the function body, and the extern redeclaration causes that translation unit to provide the external definition required by non-inlined callers. This preserves access to the inline implementation while avoiding a private
staticcopy in every translation unit.Out-of-line helpers
Based on review feedback, the following helpers are not sufficiently performance-sensitive to justify retaining their implementations in headers:
Their implementations now live in getexepath.c and thread.c , and their headers contain declarations only.
minipal_get_current_thread_id remains inline because its common path is a TLS lookup and branch. It calls the out-of-line uncached implementation only when the TLS cache is empty.
Moving minipal_set_thread_name and the uncached thread-ID implementation into thread.c also keeps _GNU_SOURCE source-local. Arbitrary consumers of thread.h no longer compile code requiring GNU-only declarations.
Executable-path configuration
The executable-path implementation uses getauxval(AT_EXECFN) as a Linux fallback when /proc/self/exe cannot be resolved. Availability was previously determined by component-specific generated configuration headers, which were not available to minipal’s source file.
Minipal now performs its own getauxval capability check and exposes the result through minipalconfig.h . Because minipal_getexepath has one out-of-line implementation, all callers now use the same capability-tested behavior regardless of optimization level or consumer configuration.
CPUID linker symbol names
The CPUID fallback helpers retain their source-level names,
__cpuidand__cpuidex, to match the corresponding compiler intrinsics. Those names were harmless while the functions werestatic, because each definition had translation-unit-local linkage.Providing external fallback definitions under those names would export reserved double-underscore symbols and could collide with compiler headers or compatibility shims. Assembler-name labels are therefore used to assign minipal-owned linker names:
inline void __cpuid(...) __asm("minipal_cpuid");inline void __cpuidex(...) __asm("minipal_cpuidex");This preserves the existing source-level API while emitting the external symbols as minipal_cpuid and minipal_cpuidex . These labels are separate from the inline assembly inside the function bodies that executes the CPUID instruction.
Validation