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

make Atomic*::min/max work on armv5te #52586

Closed
wants to merge 2 commits into from

Conversation

llogiq
Copy link
Contributor

@llogiq llogiq commented Jul 21, 2018

r? @kennytm

This fixes #52586

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 21, 2018
@llogiq
Copy link
Contributor Author

llogiq commented Jul 21, 2018

cc @infinity0

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:04:33]    Compiling unwind v0.0.0 (file:///checkout/src/libunwind)
[0m
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34]      |
[00:04:34] 1568 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1585 | / atomic_int! {
[00:04:34] 1586 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1587 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1588 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1595 | |     i8 AtomicI8 ATOMIC_I8_INIT
[00:04:34] 15961608 | |     u8 AtomicU8 ATOMIC_U8_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1522:35
[00:04:34]      |
[00:04:34] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1598 | / atomic_int! {
[00:04:34] 1599 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1600 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1601 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1608 | |     u8 AtomicU8 ATOMIC_U8_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34]      |
[00:04:34] 1568 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1598 | / atomic_int! {
[00:04:34] 1599 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1600 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1601 | |     unstable(featu| |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1608 | |     u8 AtomicU8 ATOMIC_U8_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1517:35
[00:04:34]      |
[00:04:34] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1611 | / atomic_int! {
[00:04:34] 1612 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1613 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1614 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1621 | |     i16 AtomicI16 ATOMIC_I16_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1522:35
[00:04:34]      |
[00:04:34] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1611 | / atomic_int! {
[00:04:34] 1612 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1613 | ,
[00:04:34] 1613 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1614 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1621 | |     i16 AtomicI16 ATOMIC_I16_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1573:35
[00:04:34]      |
[00:04:34] 1573 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1611 | / atomic_int! {
[00:04:34] 1612 | 1625 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1626 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1627 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1634 | |     u16 AtomicU16 ATOMIC_U16_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1522:35
[00:04:34]      |
[00:04:34] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1624 | / atomic_int! {
[00:04:34] 1625 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1626 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1627 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1634 | |     u16 AtomicU16 ATOMIC_U16_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34]      |
[00:04:34] 1568 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] [0mexpected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1624 | / atomic_int! {
[00:04:34] 1625 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1626 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1627 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1634 | |     u16 AtomicU16 ATOMIC_U16_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1517:35
[00:04:34]      |
[00:04:34] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |er: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1637 | / atomic_int! {
[00:04:34] 1638 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1639 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1640 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1647 | |     i32 AtomicI32 ATOMIC_I32_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34] 1568 |
[00:04:34] 1568 |
[00:04:34] 1573 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1637 | / atomic_int! {
[00:04:34] 1638 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1639 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1640 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1647 | |     i32 AtomicI32 ATOMIC_I32_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> f `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1522:35
[00:04:34]      |
[00:04:34] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1650 | / atomic_int! {
[00:04:34] 1651 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1652 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1653 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1660 | |     u32 AtomicU32 ATOMIC_U32_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34]      |
[00:04:34] 1568 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1650 | / atomic_int! {
[00:04:34] 1651 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1652 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1653 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1660 | |     u32 AtomicU32 ATOMIC_U32_INIT
[00:04:34] 1661 | | }
[00:04:34]      |      unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1686 | |     u64 AtomicU64 ATOMIC_U64_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1522:35
[00:04:34]      |
[00:04:34] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1676 | / atomic_int! {
[00:04:34] 1677 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1678 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] nstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1679 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1686 | |     u64 AtomicU64 ATOMIC_U64_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1573:35
[00:04:34]      |
[00:04:34] 1573 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1676 | / atomic_int! {
[00:04:34] 1677 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1678 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] 1679 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:04:34] ...    |
[00:04:34] 1686 | |     u64 AtomicU64 ATOMIC_U64_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1517:35
[00:04:34]      |
[00:04:34] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1689 | / atomic_int!{
[00:04:34] 1690 | |     stable(feature| |     stable(feature = "rust1", since = "1.0.0"),
[00:04:34] 1691 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:04:34] 1692 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:04:34] ...    |
[00:04:34] 1699 | |     isize AtomicIsize ATOMIC_ISIZE_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34]      |
[00:04:34] 1568 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1689 | / 1689 | / atomic_int!{
[00:04:34] 1690 | |     stable(feature = "rust1", since = "1.0.0"),
[00:04:34] 1691 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:04:34] 1692 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:04:34] ...    |
[00:04:34] 1699 | |     isize AtomicIsize ATOMIC_ISIZE_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1517:35
[00:04:34]      |
[00:04:34] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` 0m^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1702 | / atomic_int!{
[00:04:34] 1703 | |     stable(feature = "rust1", since = "1.0.0"),
[00:04:34] 1704 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:04:34] 1705 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:04:34] ...    |
[00:04:34] 1712 | |     usize AtomicUsize ATOMIC_USIZE_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
[00:04:34] 
[00:04:34] error: expected one of `::` or `:`, found `,`
[00:04:34]     --> libcore/sync/atomic.rs:1568:35
[00:04:34]      |
[00:04:34] 1568 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:04:34]       val: $int_type, order: Ordering) -> $int_type {
[00:04:34]      |                                     ^ expected one of `::` or `:` here
[00:04:34] ...
[00:04:34] 1702 | / atomic_int!{
[00:04:34] 1703 | |     stable(feature = "rust1", since = "1.0.0"),
[00:04:34] 1704 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:04:34] 1705 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:04:34] ...    |
[00:04:34] 1712 | |     usize AtomicUsize ATOMIC_USIZE_INIT
[00:04:34]      | |_- in this macro invocation
[00:04:34] 
ux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu
251928 ./src/llvm/test
---
154820 ./.git/modules/src
149112 ./src/llvm-emscripten/test
145348 ./obj/build/bootstrap/debug/incremental
130536 ./obj/build/bootstrap/debug/incremental/bootstrap-2fbxwhl9tnp02
130532 ./obj/build/bootstrap/debug/incremental/bootstrap-2fbxwhl9tnp02/s-f340zc3czn-uvtz2u-2iqfvo5raelnm
97532 ./obj/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends
77368 ./.git/modules/src/tools
71508 ./src/llvm/lib
65412 ./src/llvm-emscripten/test/CodeGen

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@kennytm
Copy link
Member

kennytm commented Jul 21, 2018

@llogiq What do you mean by fixing #52586 (which is this PR)...

@nagisa
Copy link
Member

nagisa commented Jul 21, 2018

Probably #52493

Copy link
Member

@nagisa nagisa left a comment

Choose a reason for hiding this comment

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

I feel that ideally we’d add the __atomic_* functions to compiler-rt/compiler-builtins, but fixing it here for a quick fix seems fine here as well.

Perhaps add a TODO?

#[cfg(target_arch = "arm5vte")]
#[inline(always)]
fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
self.fetch_update(|v| Some(v.max(val)), order, order).unwrap()
Copy link
Member

Choose a reason for hiding this comment

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

You need to specially handle the order and derive correct orders for fetch_order here.

Namely, fetch_order of fetch_update does not permit AcqRel or Release as an ordering here, but the fetch_max permits all orderings.

#[cfg(target_arch = "arm5vte")]
#[inline(always)]
fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
self.fetch_update(|v| Some(v.min(val)), order, order).unwrap()
Copy link
Member

Choose a reason for hiding this comment

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

Similarly here re orderings.

@nagisa
Copy link
Member

nagisa commented Jul 21, 2018

So, here’s a question now.

Supposedly we are exposing Atomics only to targets that support them in hardware. ARMv5 does not have any native hardware support for atomics. Why are the types exposed then?

cc @alexcrichton

@llogiq
Copy link
Contributor Author

llogiq commented Jul 21, 2018

I'm a bit puzzled: If armv5te doesn't support atomics in hardware, how do the tests work at all? How can we extend the tests to ensure this works?

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_fold:start:make-all
travis_time:start:19cf8718
make -j 4 all
[00:03:47]     Finished dev [unoptimized] target(s) in 0.25s
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1517:35
[00:03:50]      |
[00:03:50] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1585 | / atomic_int! {
[00:03:50] 1586 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1587 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1588 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1595 | |     i8 AtomicI8 ATOMIC_I8_INIT
[00:03:50]      | |_-[0m
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1517:35
[00:03:50]      |
[00:03:50] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1598 | / atomic_int! {
[00:03:50] 1599 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1600 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1601 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1608 | |     u8 AtomicU8 ATOMIC_U8_INIT
[00:03:50] 1609    u8 AtomicU8 ATOMIC_U8_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1517:35
[00:03:50]      |
[00:03:50] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1611 | / atomic_int! {
[00:03:50] 1612 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1613 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1614 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1621 | |     i16 AtomicI16 ATOMIC_I16_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1611 | / atomic_int! {
[00:03:50] 1612 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1613 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1614 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1621 | |     i16 AtomicI16 ATOMIC_I16_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1517:35
[00:03:50]      |
[00:03:50] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1624 | / atomic_int! {
[00:03:50] 1625 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1626 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1627 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1634 | |     u16 AtomicU16 ATOMIC_U16_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1624 | / atomic_int! {
[00:03:50] 1625 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1626 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1627 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1634 | |     u16 AtomicU16 ATOMIC_U16_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1517:35
[00:03:50]      |
[00:03:50] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1637 | / atomic_int! {
[00:03:50] 1638 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1639 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1640 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1647 | |     i32 AtomicI32 ATOMIC_I32_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1637 | / atomic_int! {
[00:03:50] 1638 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1639 [38
[00:03:50] 1664 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1665 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1666 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1673 | |     i64 AtomicI64 ATOMIC_I64_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] 1663 50] ...
[00:03:50] 1663 50] ...
[00:03:50] 1676 | / atomic_int! {
[00:03:50] 1677 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1678 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1679 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1686 | |     u64 AtomicU64 ATOMIC_U64_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1676 | / atomic_int! {
[00:03:50] 1677 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1678 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] 1679 | |     unstable(feature = "integer_atomics", issue = "32976"),
[00:03:50] ...    |
[00:03:50] 1686 | |     u64 AtomicU64 ATOMIC_U64_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1517:35
[00:03:50]      |
[00:03:50] 1517 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1689 | / atomic_int!{
[00:03:50] 1690 | |     stable(feature = "rust1", since = "1.0.0"),
[00:03:50] 1691 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:03:50] 1692 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:03:50] ...    |
[00:03:50] 1699 | |     isize AtomicIsize ATOMIC_ISIZE_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_38;5;12m|                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1702 | / atomic_int!{
[00:03:50] 1703 | |     stable(feature = "rust1", since = "1.0.0"),
[00:03:50] 1704 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:03:50] 1705 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:03:50] ...    |
[00:03:50] 1712 | |     usize AtomicUsize ATOMIC_USIZE_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
[00:03:50] 
[00:03:50] error: expected one of `::` or `:`, found `,`
[00:03:50]     --> libcore/sync/atomic.rs:1522:35
[00:03:50]      |
[00:03:50] 1522 |                       fn inner(&self, val: $int_type, order: Ordering) -> $int_type {
[00:03:50]      |                                     ^ expected one of `::` or `:` here
[00:03:50] ...
[00:03:50] 1702 | / atomic_int!{
[00:03:50] 1703 | |     stable(feature = "rust1", since = "1.0.0"),
[00:03:50] 1704 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:03:50] 1705 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:03:50] ...    |
[00:03:50] 1712 | |     usize AtomicUsize ATOMIC_USIZE_INIT
[00:03:50]      | |_- in this macro invocation
[00:03:50] 
.git/modules/src/tools/lld
31024 ./src/llvm/test/tools

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@nagisa
Copy link
Member

nagisa commented Jul 21, 2018

I have no idea. Even the most trivial store and swap operations generate library calls to __sync_lock_test_and_set which are provided by compiler-builtins despite its readme saying:

Rust only exposes atomic types on platforms that support them, and therefore does not need to fall back to software implementations.

@japaric
Copy link
Member

japaric commented Jul 21, 2018

@llogiq

#[cfg(not(target_arch = "armv5te"))]

"armv5te" is not a value that the built-in target_arch cfg supports. target_arch has value "arm" for the armv5te-unknown-linux-gnueabi target. These are all the cfg values for that target:

$ rustc --print cfg --target armv5te-unknown-linux-gnueabi
debug_assertions
target_arch="arm"
target_endian="little"
target_env="gnu"
target_family="unix"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="8"
target_has_atomic="cas"
target_has_atomic="ptr"
target_os="linux"
target_pointer_width="32"
target_thread_local
target_vendor="unknown"
unix

And these are the cfg values for arm-unknown-linux-gnueabi target, which supports ARMv6+:

$ rustc --print cfg --target arm-unknown-linux-gnueabi
debug_assertions
target_arch="arm"
target_endian="little"
target_env="gnu"
target_family="unix"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="cas"
target_has_atomic="ptr"
target_os="linux"
target_pointer_width="32"
target_thread_local
target_vendor="unknown"
unix

Right now, there's no way built-in way to differentiate the armv5 from the armv6 subarchitecture.

@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 21, 2018
@llogiq
Copy link
Contributor Author

llogiq commented Jul 22, 2018

@japaric so the correct way to solve this would be to change the armv5te-unknown-linux-gnueabi target definition to remove the target_has_atomic cfgs?

@nagisa
Copy link
Member

nagisa commented Jul 26, 2018

I think that is the correct approach, yes.

@japaric
Copy link
Member

japaric commented Jul 26, 2018

@nagisa

Supposedly we are exposing Atomics only to targets that support them in hardware

We are exposing atomics only to targets that support them as a whole. On its own, ARMv5 doesn't have the instructions required for a CAS loop, but Linux provides kernel helpers (*) to implement CAS loops on that architecture. So "ARMv5 Linux" having atomic_cas: true in its spec is correct; whereas, an "ARMv5 bare metal" target should have atomic_cas: false.

(*) The compiler-builtins crate exposes the Linux kernel helpers as the symbols that LLVM emits calls of when lowering e.g. intrinsics::atomic_xchg.

@llogiq

so the correct way to solve this would be to change the armv5te-unknown-linux-gnueabi target definition to remove the target_has_atomic cfgs?

I don't know what the problem that needs solving is; I was simply commenting that target_arch = "armv5te" doesn't exist. But changing atomic_cas to false for the ARMv5 Linux target would break existing builds for that target.

To be able to conditionally compile different code for ARMv5 you would probably need to a "v6" target feature (For an example, see #52120 which adds the "mclas" target feature) and use something like #[cfg(all(target_arch = "arm", not(target_feature = "v6"))].

@nagisa
Copy link
Member

nagisa commented Jul 26, 2018

The compiler-builtins crate exposes the Linux kernel helpers as the symbols that LLVM emits calls of when lowering e.g. intrinsics::atomic_xchg.

Care to point where exactly?

@japaric
Copy link
Member

japaric commented Jul 26, 2018

@nagisa
Copy link
Member

nagisa commented Jul 27, 2018

So the right fix would be to add the necessary functions there.

@llogiq
Copy link
Contributor Author

llogiq commented Jul 31, 2018

@nagisa What functions are necessary besides __cmp_xchg?

@kennytm
Copy link
Member

kennytm commented Aug 1, 2018

r? @nagisa

@rust-highfive rust-highfive assigned nagisa and unassigned kennytm Aug 1, 2018
@nagisa
Copy link
Member

nagisa commented Aug 1, 2018

@llogiq LLVM calls the __sync_fetch_and_{,u}{min,max} family of functions for this operation. Amusingly those operations seem to be already present in the file linked by @japaric above, so not sure why stuff does not work:

atomic_rmw!(__sync_fetch_and_max_1, i8, |a: i8, b: i8| if a > b { a } else { b });
atomic_rmw!(__sync_fetch_and_max_2, i16, |a: i16, b: i16| if a > b { a } else { b });
atomic_rmw!(__sync_fetch_and_max_4, i32, |a: i32, b: i32| if a > b { a } else { b });

atomic_rmw!(__sync_fetch_and_umax_1, u8, |a: u8, b: u8| if a > b { a } else { b });
atomic_rmw!(__sync_fetch_and_umax_2, u16, |a: u16, b: u16| if a > b { a } else { b });
atomic_rmw!(__sync_fetch_and_umax_4, u32, |a: u32, b: u32| if a > b { a } else { b });

atomic_rmw!(__sync_fetch_and_min_1, i8, |a: i8, b: i8| if a < b { a } else { b });
atomic_rmw!(__sync_fetch_and_min_2, i16, |a: i16, b: i16| if a < b { a } else { b });
atomic_rmw!(__sync_fetch_and_min_4, i32, |a: i32, b: i32| if a < b { a } else { b });

atomic_rmw!(__sync_fetch_and_umin_1, u8, |a: u8, b: u8| if a < b { a } else { b });
atomic_rmw!(__sync_fetch_and_umin_2, u16, |a: u16, b: u16| if a < b { a } else { b });
atomic_rmw!(__sync_fetch_and_umin_4, u32, |a: u32, b: u32| if a < b { a } else { b });

@llogiq
Copy link
Contributor Author

llogiq commented Aug 1, 2018

Maybe LLVM tries to generate the wrong instructions? Something breaks, but we're in the dark what it is. Maybe we could look into the assembly.

@nagisa
Copy link
Member

nagisa commented Aug 1, 2018

Well below is what gets generated for AtomicUsize::max(...)

atomic_max_usize:
	.fnstart
	.save	{r11, lr}
	push	{r11, lr}
	.pad	#8
	sub	sp, sp, #8
	ldr	r0, [r0]
	ldr	r1, [r1]
	str	r0, [sp, #4]
	add	r0, sp, #4
	bl	__sync_fetch_and_umax_4
	add	sp, sp, #8
	pop	{r11, pc}

The genrated code is very similar for i16 (calls __sync_fetch_and_max_2) and different orderings do not affect the function called AFAICT.

@llogiq
Copy link
Contributor Author

llogiq commented Aug 1, 2018

That doesn't look very atomic to me, but I must confess that my ARM assembly knowledge is rusty at the moment.

@TimNN TimNN added A-allocators Area: Custom and system allocators and removed A-allocators Area: Custom and system allocators labels Aug 7, 2018
@TimNN
Copy link
Contributor

TimNN commented Aug 14, 2018

Ping from triage, @llogiq! What is the status of this? Is this blocked on some changes to the compiler built ins?

@llogiq
Copy link
Contributor Author

llogiq commented Aug 15, 2018

I'm afraid I'm out of my depth here. I thought I could circumvent the problem, but it appears that I'm not really understanding the root cause, and I have no ARM5 hardware at home to test on. Closing this.

@llogiq llogiq closed this Aug 15, 2018
@infinity0
Copy link
Contributor

Well we still have 40 failing tests on armv5te - and any rust code that depends on it won't compile on that platform, @nagisa any ideas?

@llogiq
Copy link
Contributor Author

llogiq commented Aug 16, 2018

@infinity0 maybe it would help to compile a similar code snippet with GCC and Clang and compare the resulting assembly?

@nagisa
Copy link
Member

nagisa commented Aug 16, 2018

@infinity0 I have no idea why __atomic* functions from the compiler-builtins are not visible to code, no.

My susipicion is that they are simply not exported for some reason.

@infinity0
Copy link
Contributor

@nagisa The build.rs for compiler_builtins is very specific and only includes the sync_and_fetch compiler-rt assembly implementations when being built on arm7, is that the problem?

@nagisa
Copy link
Member

nagisa commented Aug 16, 2018

Could be. As pointed out in comments above, there’s a pure-rust implementation here as well, but it is likely that those are not exported for some reason.

@infinity0
Copy link
Contributor

I'm very sketchy on my binary knowledge but I thought "exporting" was only for shared library symbols. In any case, building rust-lang/compiler-builtins@5b05a98 with --target armv5te-unknown-linux-gnueabi gives me:

(sid_armel-dchroot)infinity0@amdahl:~/compiler-builtins$ nm target/armv5te-unknown-linux-gnueabi/debug/libcompiler_builtins.rlib 2>/dev/null | grep sync_fetch
00000000 t _ZN17compiler_builtins9arm_linux21__sync_fetch_and_or_128_$u7b$$u7b$closure$u7d$$u7d$17h97cc3fa3810ae9f8E
00000000 t _ZN17compiler_builtins9arm_linux21__sync_fetch_and_or_128_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17hfa81fbd175d7c2d5E
00000000 t _ZN17compiler_builtins9arm_linux21__sync_fetch_and_or_228_$u7b$$u7b$closure$u7d$$u7d$17had8499e053cd0555E
00000000 t _ZN17compiler_builtins9arm_linux21__sync_fetch_and_or_228_$u7b$$u7b$closure$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$17h79069ba6ce60a99eE
[..]
00000000 T __sync_fetch_and_umax_1
00000000 T __sync_fetch_and_umax_2
00000000 T __sync_fetch_and_umax_4
00000000 T __sync_fetch_and_umin_1
00000000 T __sync_fetch_and_umin_2
00000000 T __sync_fetch_and_umin_4
00000000 T __sync_fetch_and_xor_1
00000000 T __sync_fetch_and_xor_2
00000000 T __sync_fetch_and_xor_4

whereas the same command nm for --target armv7-unknown-linux-gnu gives no output.

If anyone has any ideas on what to try please let me know, I have access to both armv5 and armv7 targets via Debian's porting machines.

@infinity0
Copy link
Contributor

The failing tests may be due to a Debian-specific patch that I forgot about - it was given to me by someone more familiar with architecture-specific porting issues. The ongoing discussion is here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=906520

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants