Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions platform/linux-generic/arch/aarch64/cpu_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,13 @@ static void _odp_sys_info_print_acle_flags(void)
_ODP_PRINT("%s\n", ndef);
#endif

_ODP_PRINT(" __ARM_FEATURE_WFXT ");
Copy link
Collaborator

Choose a reason for hiding this comment

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

See my comment in PR 2257 about commit message and merge commits.

#ifdef __ARM_FEATURE_WFXT
_ODP_PRINT("%i\n", __ARM_FEATURE_WFXT);
#else
_ODP_PRINT("%s\n", ndef);
#endif

_ODP_PRINT("\n");
}

Expand Down
26 changes: 26 additions & 0 deletions platform/linux-generic/arch/aarch64/odp/api/abi/wait_until.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,32 @@ _odp_wait_until_equal_acq_u32(odp_atomic_u32_t *addr, uint32_t expected)
} while (expected != value);
}

static inline void
_odp_wait_until_equal_rel_u32(odp_atomic_u32_t *addr, uint32_t expected)
Copy link
Collaborator

Choose a reason for hiding this comment

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

How is this function supposed/allowed to be different from _odp_wait_until_equal_32()? What does the rel part of this function indicate? In ODP, rel in a function name implies release memory ordering, but I cannot see what release ordering would mean in a function that does not stores. Or does ldxr synchronize with acquire loads in other threads? Even if it does, I am not sure providing a release type function would be useful. It could also be cumbersome for a generic C implementation, but since such is not provided in this PR, then why is this even a separate function in this aarch64 specific implementation?

{
uint32_t value;
uint32_t *var = &addr->v;

__asm__ volatile("sevl" : : : "memory");
do {
#ifdef __ARM_FEATURE_WFXT
__asm__ volatile("wfet %x0" : : "r"(100) : "memory");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why would WFET be useful here and better than WFE? If it is useful, then why not make the same change in the existing _odp_wait_until_equal_acq_u32() function?

#else
__asm__ volatile("wfe" : : : "memory");
#endif
__asm__ volatile("ldxr %w0, [%1]"
: "=&r" (value)
: "r" (var)
: "memory");
} while (expected != value);
}

static inline void
_odp_wait_until_equal_32(odp_atomic_u32_t *addr, uint32_t expected)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we even need this function with a relaxed memory order? Aren't most (practically all?) concievable uses such that acquire is required? Maybe there is not need to introduce this new function until there is an actual user of it.

{
_odp_wait_until_equal_rel_u32(addr, expected);
}

#ifdef __cplusplus
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ _odp_wait_until_equal_acq_u32(odp_atomic_u32_t *addr, uint32_t expected)
odp_cpu_pause();
}

static inline void
_odp_wait_until_equal_u32(odp_atomic_u32_t *addr, uint32_t expected)
{
while (odp_atomic_load_u32(addr) != expected)
odp_cpu_pause();
}
#ifdef __cplusplus
}
#endif
Expand Down