-
Notifications
You must be signed in to change notification settings - Fork 4.1k
feat: Add full RISC-V 64-bit architecture support #3125
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| // Copyright 2024 The Apache Software Foundation. All rights reserved. | ||
| // Use of this source code is governed by the Apache License, Version 2.0 | ||
| // that can be found in the LICENSE file. | ||
|
|
||
| // This file is an internal atomic implementation, use butil/atomicops.h instead. | ||
| // RISC-V architecture specific atomic operations implementation using GCC intrinsics. | ||
|
|
||
| #ifndef BUTIL_ATOMICOPS_INTERNALS_RISCV_GCC_H_ | ||
| #define BUTIL_ATOMICOPS_INTERNALS_RISCV_GCC_H_ | ||
|
|
||
| namespace butil { | ||
| namespace subtle { | ||
|
|
||
| inline void MemoryBarrier() { | ||
| __asm__ __volatile__ ("fence" ::: "memory"); // NOLINT | ||
| } | ||
|
|
||
| // RISC-V atomic operations using GCC built-in functions | ||
| // These are implemented using the standard GCC atomic built-ins which | ||
| // are supported on RISC-V since GCC 7.1+ | ||
|
|
||
| inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | ||
| Atomic32 old_value, | ||
| Atomic32 new_value) { | ||
| Atomic32 prev_value; | ||
| do { | ||
| if (__sync_bool_compare_and_swap(ptr, old_value, new_value)) | ||
| return old_value; | ||
| prev_value = *ptr; | ||
| } while (prev_value == old_value); | ||
| return prev_value; | ||
| } | ||
|
|
||
| inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, | ||
| Atomic32 new_value) { | ||
| Atomic32 old_value; | ||
| do { | ||
| old_value = *ptr; | ||
| } while (!__sync_bool_compare_and_swap(ptr, old_value, new_value)); | ||
| return old_value; | ||
| } | ||
|
|
||
| inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, | ||
| Atomic32 increment) { | ||
| return Barrier_AtomicIncrement(ptr, increment); | ||
| } | ||
|
|
||
| inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, | ||
| Atomic32 increment) { | ||
| for (;;) { | ||
| // Atomic exchange the old value with an incremented one. | ||
| Atomic32 old_value = *ptr; | ||
| Atomic32 new_value = old_value + increment; | ||
| if (__sync_bool_compare_and_swap(ptr, old_value, new_value)) { | ||
| // The exchange took place as expected. | ||
| return new_value; | ||
| } | ||
| // Otherwise, *ptr changed mid-loop and we need to retry. | ||
| } | ||
| } | ||
|
|
||
| inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, | ||
| Atomic32 old_value, | ||
| Atomic32 new_value) { | ||
| // Since NoBarrier_CompareAndSwap uses __sync_bool_compare_and_swap, which | ||
| // is a full memory barrier, none is needed here or below in Release. | ||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | ||
| } | ||
|
|
||
| inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, | ||
| Atomic32 old_value, | ||
| Atomic32 new_value) { | ||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | ||
| } | ||
|
|
||
| inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { | ||
| *ptr = value; | ||
| } | ||
|
|
||
| inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | ||
| *ptr = value; | ||
| MemoryBarrier(); | ||
| } | ||
|
|
||
| inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { | ||
| MemoryBarrier(); | ||
| *ptr = value; | ||
| } | ||
|
|
||
| inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { | ||
| return *ptr; | ||
| } | ||
|
|
||
| inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { | ||
| Atomic32 value = *ptr; | ||
| MemoryBarrier(); | ||
| return value; | ||
| } | ||
|
|
||
| inline Atomic32 Release_Load(volatile const Atomic32* ptr) { | ||
| MemoryBarrier(); | ||
| return *ptr; | ||
| } | ||
|
|
||
| // 64-bit versions of the operations. | ||
| // See the 32-bit versions for comments. | ||
|
|
||
| inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, | ||
| Atomic64 old_value, | ||
| Atomic64 new_value) { | ||
| Atomic64 prev_value; | ||
| do { | ||
| if (__sync_bool_compare_and_swap(ptr, old_value, new_value)) | ||
| return old_value; | ||
| prev_value = *ptr; | ||
| } while (prev_value == old_value); | ||
| return prev_value; | ||
| } | ||
|
|
||
| inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, | ||
| Atomic64 new_value) { | ||
| Atomic64 old_value; | ||
| do { | ||
| old_value = *ptr; | ||
| } while (!__sync_bool_compare_and_swap(ptr, old_value, new_value)); | ||
| return old_value; | ||
| } | ||
|
|
||
| inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, | ||
| Atomic64 increment) { | ||
| return Barrier_AtomicIncrement(ptr, increment); | ||
| } | ||
|
|
||
| inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, | ||
| Atomic64 increment) { | ||
| for (;;) { | ||
| // Atomic exchange the old value with an incremented one. | ||
| Atomic64 old_value = *ptr; | ||
| Atomic64 new_value = old_value + increment; | ||
| if (__sync_bool_compare_and_swap(ptr, old_value, new_value)) { | ||
| // The exchange took place as expected. | ||
| return new_value; | ||
| } | ||
| // Otherwise, *ptr changed mid-loop and we need to retry. | ||
| } | ||
| } | ||
|
|
||
| inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, | ||
| Atomic64 old_value, | ||
| Atomic64 new_value) { | ||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | ||
| } | ||
|
|
||
| inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, | ||
| Atomic64 old_value, | ||
| Atomic64 new_value) { | ||
| return NoBarrier_CompareAndSwap(ptr, old_value, new_value); | ||
| } | ||
|
|
||
| inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { | ||
| *ptr = value; | ||
| } | ||
|
|
||
| inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { | ||
| *ptr = value; | ||
| MemoryBarrier(); | ||
| } | ||
|
|
||
| inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { | ||
| MemoryBarrier(); | ||
| *ptr = value; | ||
| } | ||
|
|
||
| inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { | ||
| return *ptr; | ||
| } | ||
|
|
||
| inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { | ||
| Atomic64 value = *ptr; | ||
| MemoryBarrier(); | ||
| return value; | ||
| } | ||
|
|
||
| inline Atomic64 Release_Load(volatile const Atomic64* ptr) { | ||
| MemoryBarrier(); | ||
| return *ptr; | ||
| } | ||
|
|
||
| } // namespace butil::subtle | ||
| } // namespace butil | ||
|
|
||
| #endif // BUTIL_ATOMICOPS_INTERNALS_RISCV_GCC_H_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.