Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc] Support configurable errno modes #98287
[libc] Support configurable errno modes #98287
Changes from 4 commits
3c915c7
8a866a0
4ceb880
34f55c6
f4b0578
c03ff0e
28d2181
5959fb2
525ae6d
1ff0acc
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would probably be best to make the default value
LIBC_ERRNO_MODE_THREAD_LOCAL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree but the problem is that we currently don't have any mechanism to distinguish the overlay from the full build mode, and in the overlay mode we want to default to
LIBC_ERRNO_MODE_SYSTEM
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really think this needs to not only enumerate the modes but document what each one means. That would make this spot the right place to bikeshed the names, none of which I really like so far.
Perhaps:
UNDEFINED
: libc never stores a value;errno
macro uses get link-time failureEXTERNAL_ABI
: embedder must defineint *__llvm_libc_errno(void);
C functionTHREAD_LOCAL
: libc maintains per-thread state (requires C++thread_local
support for libc implementation code)SHARED_ATOMIC
: libc maintains anatomic_int
used by all threads, contrary to standard C semantics (requires use of atomics in libc implementation code, may produce libcalls an embedder must supply)SHARED_THREAD_UNSAFE
: libc maintains a plainint
used by all threads, contrary to standard C semantics unless always single-threaded; nothing prevents data racesSYSTEM_HEADER
: In overlay mode, system<errno.h>
errno
macro is used directly by libc. In fullbuild mode, effectively the same asEXTERNAL_ABI
(or perhaps we make it an error to choose this in fullbuild mode).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it makes sense to distinguish the "shared atomic" and "shared thread unsafe" modes? Right now these are only used by the GPU port which uses the atomic version. Specifically the only reason for the "shared thread unsafe" mode seems to be avoiding the use of atomics, but we already use those elsewhere so I'm not sure how useful that is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Today's "baremetal" is a very specific set of choices about an embedded-style use case. I'm confident that there will in the long run be embedded-style use cases that are purely single-threaded and want to avoid the overhead (or need for useless libcall stubs that do nothing) of atomics. I think it will certainly be the right thing for all libc code that might ever be useful in some minimal embedded context to be configurable to avoid atomics at the cost of any kind of thread safety. I don't think it will ever be wise enough to be acceptable to "achieve" that via hacks like
-DLIBC_THREAD_LOCAL=
or makingcpp::Atomic
configurable to itself not actually be atomic. Instead, I think each and every case (so far,rand
anderrno
) merits its own intentional and explicit configuration choice so in each context someone has to decide what semantics, and tradeoffs between formally standards-compliant and/or de facto norm semantics and other context-specific factors, are right for them.For today, it doesn't matter if we support everything that we should in principle support in terms of configuration options. The taxonomy above I think covers all the options for
errno
in particular that I anticipate we will support long term. The subset ofTHREAD_LOCAL
,SHARED_ATOMIC
, andSHARED_THREAD_UNSAFE
is probably a common vocabulary that makes sense for the broader general class of cases that includesrand
, while the other options here are idiosyncratic toerrno
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to update to
LIBC_NAMESPACE_DECL
when that stuff lands. (I'm not sure it technically matters as long as it was done in libc_errno.h, but I think uniformity it what we're going for regardless.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack, I expect this change is going to land after that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this mode should be called "SHARED_ATOMIC" or something like that. ISTM there should be another "SHARED_THREAD_UNSAFE" or the like that's just a plain variable.
Again, these variables should have names appropriate for a local linkage implementation detail, and it doesn't hurt to use different names specific to each different implementation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need a declaration here. It's already in
<errno.h>
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't include
errno.h
in the full build mode, should we?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a policy about using a
hdr/errno_macros.h
wrapper instead of doing it directly, but yeah. In some fashion, the authoritative header file declaration of any public ABI function you're defining really ought to be in scope in the implementation file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there may be a case to be made that there should be an
__llvm_libc_errno.h
in this directory to declare the function like we have for other public (ABI) functions. But then that would go with the__llvm_libc_errno.cpp
implementation file for just that function, which isn't what we want to do since we want it and theErrno
internal class implemented together.I'm not sure what the precedent is (or if there is any yet) for other non-functions in the API, i.e. having an
errno.h
that's responsible forerrno
inside the libc implementation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use https://github.com/llvm/llvm-project/blob/0b15f89182a4b2a4c46ad207fa2e282ad35f12ee/libc/src/errno/libc_errno.h for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That header has that name because it's implementing
LIBC_NAMESPACE::libc_errno
. It's true that today it does includehdr/errno_macros.h
, but that only defines theE*
constants (necessarily, i.e. in all build modes).That's a different issue from whether when there is a variable (or variable-like API, such as
errno
) in the public API, we have asymbol_name.h
header for it insrc/something/
like we do for functions in the public API.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only other case I can think of is https://github.com/llvm/llvm-project/blob/7868033d2e846fa30c20455ca819fad29d9d795e/libc/src/assert/assert.h which would suggest having
errno.h
in https://github.com/llvm/llvm-project/tree/7868033d2e846fa30c20455ca819fad29d9d795e/libc/src/errnoThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I introduced
src/errno/errno.h
in the latest revision.