Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Deduplicate minipal header helpers - #132113

Merged
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers
Aug 13, 2026
Merged

Deduplicate minipal header helpers#132113
mdh1418 merged 6 commits into
dotnet:mainfrom
mdh1418:deduplicate-minipal-header-helpers

Conversation

@mdh1418

@mdh1418mdh1418 commented Aug 11, 2026

Copy link
Copy Markdown
Member

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:

#include "header.h"
extern return_type function(arguments);

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 static copy 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:

  •  minipal_getexepath 
  •  minipal_get_current_thread_id_no_cache 
  •  minipal_set_thread_name 

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, __cpuid and __cpuidex , to match the corresponding compiler intrinsics. Those names were harmless while the functions were static , 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

  • Built clr+libs+host for Linux x64 Debug.
  • Verified GCC and Clang C consumers link at -O0 using the external definitions.
  • Verified optimized consumers can use the inline definitions.
  • Verified C++ consumers use compatible C-linkage symbols.
  • Verified the minipal archive provides the expected external helper symbols.
  • Verified the shipped archives expose minipal_cpuid and minipal_cpuidex rather than strong __cpuid and __cpuidex symbols.
  • Verified no _SOURCE or _INLINE implementation-control macros remain.

@mdh1418
mdh1418 requested review from jkotas and a lite review from CopilotAugust 11, 2026 04:14
@github-actionsgithub-actionsBot added the area-PAL-coreclr only for closed issues label Aug 11, 2026
@azure-pipelines

Copy link
Copy Markdown
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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, and entrypoints helper implementations from headers to new .c files with exported prototypes.
  • Add minipal sources (*.c) to the minipal build and adjust System.IO.Compression.Native to link against minipal.
  • Introduce “SOURCE” macros for selective in-header vs out-of-line definitions (notably ospagesize.h and cpuid.h).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/native/minipal/thread.hReplaces header inlines with prototypes + shared TLS declaration.
src/native/minipal/thread.cNew implementation file for thread ID helpers and thread naming.
src/native/minipal/ospagesize.hAdds MINIPAL_OSPAGESIZE_* inline control macro for constant page-size platforms.
src/native/minipal/ospagesize.cRefactors to include header first and conditionally compile POSIX implementation.
src/native/minipal/getexepath.hReplaces header inline with prototype for external implementation.
src/native/minipal/getexepath.cNew implementation file for executable path resolution across platforms.
src/native/minipal/entrypoints.hReplaces header inline resolver with exported prototype.
src/native/minipal/entrypoints.cNew implementation file for minipal_resolve_dllimport.
src/native/minipal/cpuid.hAdds MINIPAL_CPUID_* inline control macro.
src/native/minipal/cpuid.cNew compilation unit to host cpuid fallback implementations.
src/native/minipal/CMakeLists.txtAdds new .c sources to minipal build outputs.
src/native/libs/System.IO.Compression.Native/CMakeLists.txtLinks System.IO.Compression.Native against minipal to satisfy new out-of-line symbols.

Comment threadsrc/native/minipal/ospagesize.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/cpuid.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
Comment threadsrc/native/minipal/getexepath.h Outdated
mdh1418and others added 4 commits August 12, 2026 19:40
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>
CopilotAI review requested due to automatic review settings August 13, 2026 01:53
@mdh1418
mdh1418force-pushed the deduplicate-minipal-header-helpers branch from 4bc3b14 to 670f632CompareAugust 13, 2026 01:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_id is used from multiple C source files (e.g., System.Native). With external-linkage inline in a header, builds can end up with multiple global definitions (or require a single out-of-line definition) depending on compiler/flags. Restoring static inline here 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_name is 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 getauxval based only on AT_EXECFN, but getauxval availability is already feature-tested via HAVE_GETAUXVAL in multiple native builds. Dropping the guard can cause compile/link failures on platforms/toolchains where AT_EXECFN is defined but getauxval is unavailable. Guard the fallback on HAVE_GETAUXVAL as 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 extern declarations don’t provide a definition for the header-defined inline functions and are redundant with the declarations/definitions already visible via #include "thread.h". They also become actively misleading if the header switches back to static 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);

Comment threadsrc/native/minipal/thread.h Outdated
Comment threadsrc/native/minipal/thread.c
Comment threadsrc/native/minipal/getexepath.h Outdated
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>
CopilotAI review requested due to automatic review settings August 13, 2026 16:40

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment threadsrc/native/minipal/cpuid.c
@jkotas

Copy link
Copy Markdown
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>
CopilotAI review requested due to automatic review settings August 13, 2026 20:27

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@mdh1418

Copy link
Copy Markdown
MemberAuthor

/ba-g "Build failures are #117486, #131925, and #132030"

@mdh1418
mdh1418 merged commit 691fd96 into dotnet:mainAug 13, 2026
156 of 160 checks passed
@mdh1418
mdh1418 deleted the deduplicate-minipal-header-helpers branch August 13, 2026 23:48
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Aug 14, 2026
mdh1418 added a commit that referenced this pull request Aug 18, 2026
Fixes#132391#132113 moved the minipal thread ID and naming helpers from `thread.h`
into the C translation unit `thread.c`. Mono’s Apple builds define
`_XOPEN_SOURCE`, which causes the Apple SDK’s `pthread.h` to hide the
Darwin-specific `pthread_threadid_np` and `pthread_setname_np`
declarations from C code.
Define `_DARWIN_C_SOURCE` before including pthread.h so those
declarations remain available.
Validated with a Release Mono build for iossimulator-arm64 .
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
steveisok pushed a commit that referenced this pull request Aug 18, 2026
Backport of #132421 to release/11.0-rc1
/cc @mdh1418
## Customer Impact
- [ ] Customer reported
- [x] Found internally
Breaks builds on apple platforms
## Regression
- [X] Yes
- [ ] No
Regression introduced by #132113
## Testing
Tested via building for Apple platforms on MacOS + CI jobs passed. In
the PR that introduced the regression, none of the Apple jobs failed
during build, so this issue was missed
## Risk
Low. This change only affects Apple platforms and code compiling
`thread.h`/`thread.c` so they recognize `pthread_threadid_np` and
`pthread_setname_np`
Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
Copilot-Session: 1d440598-bbbc-46c5-a5c7-cf48de85e62c
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-PAL-coreclronly for closed issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@mdh1418@jkotas@am11