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

Refactor Atomic#swap for reference-like types #14402

Closed

Conversation

HertzDevil
Copy link
Contributor

There is no need to use LibC::SizeT here since we could obtain the actual type with a typeof.

@straight-shoota straight-shoota added this to the 1.13.0 milestone Mar 26, 2024
address = atomicrmw(:xchg, pointerof(@value).as(LibC::SizeT*), LibC::SizeT.new(value.as(Void*).address), ordering)
Pointer(T).new(address).as(T)
address = atomicrmw(:xchg, pointerof(@value).as(typeof(@value.object_id)*), value.object_id, ordering)
Pointer(Void).new(address).as(T)
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless I'm mistaken #object_id is always casted to 64-bit, whatever of the architecture (32 or 64-bit) which would lead to an expensive DWCAS on i686, and is likely disabled by LLVM by default anyway. I'm not sure about ARM.

I'd keep the cast as SizeT.

Copy link
Member

Choose a reason for hiding this comment

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

Hm, good point. Maybe we would want #object_id to actually be of platform-specific width?
Crystal itself just doesn't have a SizeT type yet, so it's just been the default UInt64 for now.

However, thinking a bit more about this #object_id could be overriden by any type (for whatever reason). So taking the address directly is actually a bit more robust.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, yes, #object_id should be arch-specific. Casting to Void* and using the address seems more robust to me.

But now I'm not sure we don't cast Pointer#address as UInt64 too...

edit: hence the explicit cast to SizeT.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the return type of Pointer#address is documented as UInt64. But I believe the underlying LLVMBuildPtrToInt actually casts to an integer of the same width as a pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

LLVMBuildPtrToInt takes a target type, which is currently hardcoded to i64:

def codegen_primitive_pointer_address(node, target_def, call_args)
ptr2int call_args[0], llvm_context.int64
end

@HertzDevil HertzDevil marked this pull request as draft March 27, 2024 02:45
@HertzDevil HertzDevil removed this from the 1.13.0 milestone Mar 27, 2024
@HertzDevil HertzDevil closed this Apr 8, 2024
@HertzDevil HertzDevil deleted the refactor/atomic-swap branch April 10, 2024 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants