Skip to content
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

Add GNU/Hurd support #993

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open

Add GNU/Hurd support #993

wants to merge 1 commit into from

Conversation

sthibaul
Copy link

No description provided.


static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr)
{
return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think these ancient GCC __sync_* builtins should be used in new code at all. In general jack2's atomic code is pretty bad by modern standards; it's full of sus volatile sprinkled everywhere and relies on inline asm, making it janky and most likely slower than it should (thanks to the cache flushing caused by volatile).

Both C and C++ have really good standard atomics support that would serve the purpose much better, but that would be out of scope for this PR. IMHO at the very least this should use the slightly less outdated __atomic_* GCC builtins, assuming Clang also supports those. Can't remember. It wouldn't be as nice as std::atomic but a step in the right direction.

Copy link
Author

Choose a reason for hiding this comment

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

volatile by itself doesn't imply cache flushing. But synchronization memory coherency properties do indeed.

What is CAS() supposed to provide as property? __atomic_* indeed allows to specify something more precise than a full barrier, but without knowing what it should be (and from a quick look to the existing code it seems it's a full barrier that is needed), using __atomic_* won't be any better than the linux port's __sync_* that I replicated for coherency. If I start using __atomic_* in the gnu port, somebody who will be fixing all these os-specific pieces might start wondering why the gnu port is different from the linux port. Is that really what we want?

Copy link
Author

@sthibaul sthibaul Dec 25, 2024

Choose a reason for hiding this comment

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

using __atomic_* won't be any better than the linux port's __sync_* that I replicated for coherency

(Apparently __atomic_* would allow to drop the memory barrier on comparison failure. In the cases where CAS is used (while loops until success) that won't change anything).

that I replicated for coherency

What I also fear is that if I make the gnu port depart from the strong guarantee of the linux version, people might start producing code that actually require the strong guarantee and work on linux but be bogus on the gnu port.

Copy link
Author

Choose a reason for hiding this comment

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

To make progress at all, I have updated to use the __atomic_* equivalent of __sync_*

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
@imaami
Copy link
Contributor

imaami commented Jan 1, 2025

volatile by itself doesn't imply cache flushing. But synchronization memory coherency properties do indeed.

You're correct, thanks for pointing that out. My understanding distils to "if it's not memory-mapped I/O or signals it doesn't need volatile" and I'm sure I get the intricacies wrong in one way or another.

The change looks good to me. I tried to figure out if there might be possible pitfalls going from __sync_* to __atomic_* by reading glibc sources, but since it's so heavily layered with macros it proved more difficult than just casually browsing a repo. Looking elsewhere, at least glib seems to treat __atomic_compare_exchange_n with __ATOMIC_SEQ_CST as equivalent to __sync_bool_compare_and_swap:

https://github.com/GNOME/glib/blob/68388cf7f753d91686d2a50d74e760d28dab27a3/glib/gatomic.h#L176
https://github.com/GNOME/glib/blob/68388cf7f753d91686d2a50d74e760d28dab27a3/glib/gatomic.h#L402

Side note: I feel an urge to start chipping away at the entire atomic mess, or at least the parts that are very clearly unnecessary. I'm mainly referring to INC_ATOMIC and DEC_ATOMIC here, as they have very limited actual use and can be replaced with standard std::atomic increment and decrement. These don't even need CAS.

Copy link
Contributor

@imaami imaami left a comment

Choose a reason for hiding this comment

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

LGTM, approving this (for what it's worth, not being a project admin myself)

@sthibaul
Copy link
Author

sthibaul commented Jan 1, 2025

if there might be possible pitfalls going from __sync_* to __atomic_*

It is clear from the gcc source for __sync_*: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/builtins.cc;h=9d106405f79512fe3833c9a830a0f317937bd08a;hb=HEAD#l6575

so __sync_*_compare_and_swap are strictly equivalent to __atomic_compare_and_swap with no weak and SEQ_CST

@imaami
Copy link
Contributor

imaami commented Jan 1, 2025

if there might be possible pitfalls going from __sync_* to __atomic_*

It is clear from the gcc source for __sync_*: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/builtins.cc;h=9d106405f79512fe3833c9a830a0f317937bd08a;hb=HEAD#l6575

so __sync_*_compare_and_swap are strictly equivalent to __atomic_compare_and_swap with no weak and SEQ_CST

OK, thanks. Also I just realized I said glibc when I meant gcc sources; brain fart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants