[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: -latomics vs riscv64



On 31 Jan 2022, at 13:30, Mathieu Malaterre <malat@debian.org> wrote:
> 
> Jess,
> 
> On Mon, Jan 31, 2022 at 12:36 PM Jessica Clarke <jrtc27@debian.org> wrote:
>> 
>> On 31 Jan 2022, at 08:37, Mathieu Malaterre <malat@debian.org> wrote:
>>> 
>>> [cc me please]
>>> 
>>> Dear riscv64 porters,
>>> 
>>> I am trying to get JPEG-XL to compile on riscv64. After reading of:
>>> 
>>> * https://github.com/riscv-collab/riscv-gcc/issues/12
>>> 
>>> I am under the impression that the black magic to get -latomic passed
>>> on the linker line is handled somewhere in gcc spec file.
>>> 
>>> This also seems to be the case, per my reading of the log file at:
>>> 
>>> * https://buildd.debian.org/status/fetch.php?pkg=jpeg-xl&arch=riscv64&ver=0.7.0%7Egit20220120.0647da4%2Bds-3&stamp=1643404075&raw=0
>>> 
>>> The following c++11 code (1):
>>> 
>>> ```
>>> #include <atomic>
>>> #include <cstdint>
>>> std::atomic<uint64_t> num (0);
>>> int main() {
>>> uint64_t i = num.load(std::memory_order_relaxed);
>>> return 0;
>>> }
>>> ```
>>> 
>>> seems to compile and link nicely without the need for an explicit
>>> `-latomic`. However somewhere later during the compilation, I receive
>>> an error that:
>>> 
>>> /usr/bin/ld: libjxl_dec.so.0.7.0: undefined reference to `__atomic_fetch_and_1'
>>> /usr/bin/ld: libjxl_dec.so.0.7.0: undefined reference to `__atomic_fetch_or_1'
>>> 
>>> So now it seems that I need an explicit `-latomic`
>>> 
>>> Could someone please share his knowledge on -latomic on riscv64 Debian
>>> arch ? Please note that the above c++11 code rightfully fails to
>>> compile on armel/mipsel and powerpc which allow the buildsystem to
>>> detect the need for an explicit `-latomic` being added by cmake.
>> 
>> RISC-V only has 32-bit and 64-bit atomic instructions. GCC is supposed
>> to convert smaller atomics to those larger ones via masking and
>> shifting like LLVM, but it’s a known bug that it does not. This means
>> anything that wants to use atomics on 1-byte or 2-byte types needs
>> -latomic, but not 4-byte or 8-byte (though it does no harm).
> 
> Very interesting ! Thanks for the info.
> 
> I tried a shot in the dark to fix the issue, but it still fails (*).
> The code was:
> 
>     #include <atomic>
>     #include <cstdint>
>     std::atomic<uint8_t> n8 (0);
>     std::atomic<uint16_t> n16 (0);
>     std::atomic<uint32_t> n32 (0);
>     std::atomic<uint64_t> n64 (0);
>     int main() {
>       uint8_t i8 = n8.load(std::memory_order_relaxed);
>       uint16_t i16 = n16.load(std::memory_order_relaxed);
>       uint32_t i32 = n32.load(std::memory_order_relaxed);
>       uint64_t i64 = n64.load(std::memory_order_relaxed);
>       return 0;
>     }
> 
> I am giving up on riscv64 until there are porteboxes available.

Atomic loads are just compiled down to normal loads and fences which do
exist. It’s all the read-modify-write operations that cause issues,
e.g. fetch_add/or in your case.

If you want to test locally, qemu-user isn’t hard to set up, there are
instructions on the port’s wiki page I believe.

Jess


Reply to: