Skip to content
This repository was archived by the owner on Nov 5, 2018. It is now read-only.

Revamp CachePadded #1

Merged
3 commits merged into from Oct 22, 2017
Merged

Revamp CachePadded #1

3 commits merged into from Oct 22, 2017

Conversation

ghost
Copy link

@ghost ghost commented Sep 27, 2017

Changes:

  • Remove ZerosValid.
  • Change cache line length to 64 bytes.
  • Use repr(align(64)) with the nightly feature in order to align to cache line length.
  • Implement Drop for CachePadded<T>.
  • Implement Clone for CachePadded<T>.
  • Implement better Debug for CachePadded<T>.
  • Implement From<T> for CachePadded<T>.
  • Write more tests.

@ghost ghost requested a review from jeehoonkang September 27, 2017 15:15
@arthurprs
Copy link

I'm not 100% up to date on the union story, but could we make the nightly version use union and accept arbitrary sized T?

@ghost
Copy link
Author

ghost commented Oct 14, 2017

Thanks for taking a look! Yeah, that's a good idea. I've pushed a commit with CachePadded that accepts arbitrarily sized Ts on nightly Rust.

@arthurprs
Copy link

Nice! I think this is the best way forward 👍

Copy link

@arthurprs arthurprs left a comment

Choose a reason for hiding this comment

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

Looks good. I'd be nice to have a doc line about the T size restriction when not using the nightly feature.

Copy link
Collaborator

@jeehoonkang jeehoonkang left a comment

Choose a reason for hiding this comment

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

It looks great!

As a pedantic mind, I want to clarify our assumption on the underlying C, Rust, LLVM semantics for CachePadded's correctness. I don't think a complete analysis should be done in this PR, but at least let's leave some comments.

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CachePadded {{ ... }}")
}
/// `[T; 0]` ensures correct alignment.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it a documented behavior?

Copy link
Author

Choose a reason for hiding this comment

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

I didn't find anything explicit on this issue, but FWIW, there's this: link

#[repr(align(64))]
#[allow(unions_with_drop_fields)]
union Inner<T> {
bytes: [u8; CACHE_LINE_BYTES],
Copy link
Collaborator

Choose a reason for hiding this comment

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

May I ask why do we need it here?

Choose a reason for hiding this comment

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

Good point, looks like align is enough in nightly (https://play.rust-lang.org/?gist=4c3841431f1d27ff7997eb4f2c2a2471&version=nightly) so I think we can get away without the union at all.

_marker: ([], PhantomData),
};
let p: *mut T = &mut *padded;
ptr::write(p, t);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I want to make sure that this write conforms to C's union semantics. (I'm assuming Rust's union is the same with C's union.) Unfortunately I don't know the exact definition in the standard C: I just know that there is a very complex rule that determines what is safe and what is unsafe use of unions. A good reference would be Krebber's thesis.

Even if it turned out to be inconformant to C, it's probably okay, because for now we only need to think of LLVM semantics. We don't need to think of the rules on unions when we turn off the -tbaa option (type-based alias analysis).

@ghost
Copy link
Author

ghost commented Oct 15, 2017

Changes:

  • changed union Inner<T> to struct Inner<T>
  • added a comment in the docs on size and alignment

@ghost
Copy link
Author

ghost commented Oct 21, 2017

@jeehoonkang Can we merge?

Copy link
Collaborator

@jeehoonkang jeehoonkang left a comment

Choose a reason for hiding this comment

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

Sorry for the delay. I like the change. Thanks!

data: UnsafeCell<[usize; CACHE_LINE]>,
_marker: ([Padding; 0], marker::PhantomData<T>),
}
cfg_if! {
Copy link
Collaborator

Choose a reason for hiding this comment

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

very neat :)

cfg_if! {
if #[cfg(feature = "nightly")] {
#[derive(Clone)]
#[repr(align(64))]
Copy link
Collaborator

Choose a reason for hiding this comment

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

We use a magic number here because we cannot use a constant, right?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, unfortunately.

Copy link

@arthurprs arthurprs left a comment

Choose a reason for hiding this comment

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

LGTM

@ghost ghost merged commit 3ad8298 into crossbeam-rs:master Oct 22, 2017
@ghost ghost deleted the revamp-cachepadded branch October 22, 2017 09:03
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants