-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Possible bugs in __STREXW
and __LDREXW
in cmsis_armcc.h and cmsis_armclang.h
#1623
Comments
Hi @henrla, There should be no difference in exposure to undefined behaviour when using low-level instructions within a block of C/C++ code. My reading of the advice is to not rely on C/C++ code around exclusive access and rather implement the whole portion in assembly. As a reference you might want to take a look into the bunch of The downside of inline assembly is to be not compiler agnostic anymore. This might not be a big issue because Arm Compiler 6, IAR, and GCC, all accept inline GNU Assembly. Another option would be to rely on standard C library which received atomic support in C11 and C++11. One just needs to be careful when using C/C++ atomics and compile for targets without exclusive access support. Compilation can fail at link stage due to missing low level implementations. One would need to provide implementations that fit the purpose, e.g., using interrupt locks or rtos mutexes to achieve atomicity. Cheers, |
Hi @JonatanAntoni, Thank you for your swift reply. If I understand correctly, you are interpreting the documentation of the intrinsics for exclusive load and store in arm and armclang, to also apply for the assembly instructions It was my understanding that the functions Thank you Henrik |
Hi @henrla, They are basically intended to be used in C/C++ code. But if the overall code gives the expected behaviour goes far beyond CMSIS visibility. Hence, it's totally up to the user to check if the defines from CMSIS can be used successfully or if one needs to go for another solution. In RTX5 we don't rely on the intrinsics but give the full implementation in inline assembly. RTX5 was developed for C99 and without considering C11 features. In EventRecorder we decided to go for C11 and Cheers, |
Thank you for your swift reply @JonatanAntoni. If I want to use To me, it sounds like their limitation should be documented in CMSIS. |
Hi @henrla, Sure, we can add the links you provided earlier into the documentation. I guess, you'd need to inspect the disassembly to know if the compiler inserted additional load/store instructions which would break the exclusive access. Could you enhance the docs and raise your proposal as a PR? That would be really helpful. Cheers, |
CMSIS includes the functions
__STREXW
and__LDREXW
.cmsis_armcc.h
In cmsis_armcc.h, they are defined using intrinsics like this:
While in the arm documentation, the following is stated with regards to the two intrinsic calls:
"The compiler does not guarantee to preserve the state of the exclusive monitor. It might generate load and store instructions between the LDREX instruction generated for the __ldrex intrinsic and the STREX instruction generated for the __strex intrinsic. Because memory accesses can clear the exclusive monitor, code using the __ldrex and __strex intrinsics can have unexpected behavior. Where LDREX and STREX instructions are needed, ARM recommends using embedded assembly."
Reference: https://developer.arm.com/documentation/dui0472/k/Compiler-specific-Features/--ldrex-intrinsic
This statement casts doubt on whether
__STREXW
and__LDREXW
works as intended for armcc. Is there a rationale or a specific use-case of the__strex
and__ldrex
intrinsics? Or are the intrinsics currently expected to have unexpected behavior?cmsis_armclang.h
In cmsis_armclang.h, they are defined like this:
While in the armclang documentation, the following is stated with regards to the two intrinsic calls:
"Note that the compiler does not guarantee it will not insert stores which clear the exclusive monitor in between an ldrex type operation and its paired strex. In practice this is only usually a risk when the extra store is on the same cache line as the variable being modified and Clang will only insert stack stores on its own, so it is best not to use these operations on variables with automatic storage duration."
Reference: https://clang.llvm.org/docs/LanguageExtensions.html
This statement casts doubt on whether
__STREXW
and__LDREXW
works as intended for armclang. Is there a rationale or a specific use-case intention of the armclang intrinsics, or is unexpected behavior expected?Assembly is used in the gcc implementation, so it should work as intended. My concern is with regards to the implementation for armcc and armclang.
Thank you.
The text was updated successfully, but these errors were encountered: