-
Notifications
You must be signed in to change notification settings - Fork 1.9k
More aggsum optimizations. #12145
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
More aggsum optimizations. #12145
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -245,6 +245,49 @@ extern ulong_t atomic_swap_ulong(volatile ulong_t *, ulong_t); | |
extern uint64_t atomic_swap_64(volatile uint64_t *, uint64_t); | ||
#endif | ||
|
||
/* | ||
* Atomically read variable. | ||
*/ | ||
#define atomic_load_char(p) (*(volatile uchar_t *)(p)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know libspl's versions of these functions are okay being a bit loose, but I don't believe that volatile guarantees atomicity, that's just a common implementation side-effect. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. volatile does not provide atomicity, it only makes compiler to not optimize memory accesses. Atomicity is provided by machine register size, copied with single instruction. That is why there are #ifdef _LP64. This is a copy/paste from FreeBSD's atomic_common.h, used on all supported architectures, so I believe it to be correct. I have no opinion about __atomic builtins. When I written this, I haven't seen recent наб's commit to start using them in lib/libspl/atomic.c. It actually makes me wonder why they were not inlined here, but that is a different topic. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'll be nice to finally have proper wrappers for atomic loads and stores! This is functionality I know would be helpful elsewhere with some kstats which are a bit dodgy in this regard (though pretty harmless). Since it sounds like these are all well tested already on FreeBSD this seems fine to me. Though I wouldn't object to updating them to use the GCC atomic builtins for consistency in a similar fashion as was done for the other atomics. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure what is the point now to have all the atomics in separate C file, not inlined in the header. Is it supposed to improve compatibility when library is built with compiler supporting atomics and header is used by less capable? Previously it had sense, since alternative implementations were written in assembler. But now with compiler supposed to implement all of that -- what's the point? To troubles compiler/CPU with function calls? PS: On a second thought, some operations may require more complicated implementation where function call could have sense, but since compiler hides it from us, we have no way to differentiate. For trivial load/store/etc I'd prefer to not call functions for single machine instruction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well since this is only for |
||
#define atomic_load_short(p) (*(volatile ushort_t *)(p)) | ||
#define atomic_load_int(p) (*(volatile uint_t *)(p)) | ||
#define atomic_load_long(p) (*(volatile ulong_t *)(p)) | ||
#define atomic_load_ptr(p) (*(volatile __typeof(*p) *)(p)) | ||
#define atomic_load_8(p) (*(volatile uint8_t *)(p)) | ||
#define atomic_load_16(p) (*(volatile uint16_t *)(p)) | ||
#define atomic_load_32(p) (*(volatile uint32_t *)(p)) | ||
#ifdef _LP64 | ||
#define atomic_load_64(p) (*(volatile uint64_t *)(p)) | ||
#elif defined(_INT64_TYPE) | ||
extern uint64_t atomic_load_64(volatile uint64_t *); | ||
#endif | ||
|
||
/* | ||
* Atomically write variable. | ||
*/ | ||
#define atomic_store_char(p, v) \ | ||
(*(volatile uchar_t *)(p) = (uchar_t)(v)) | ||
#define atomic_store_short(p, v) \ | ||
(*(volatile ushort_t *)(p) = (ushort_t)(v)) | ||
#define atomic_store_int(p, v) \ | ||
(*(volatile uint_t *)(p) = (uint_t)(v)) | ||
#define atomic_store_long(p, v) \ | ||
(*(volatile ulong_t *)(p) = (ulong_t)(v)) | ||
#define atomic_store_ptr(p, v) \ | ||
(*(volatile __typeof(*p) *)(p) = (v)) | ||
#define atomic_store_8(p, v) \ | ||
(*(volatile uint8_t *)(p) = (uint8_t)(v)) | ||
#define atomic_store_16(p, v) \ | ||
(*(volatile uint16_t *)(p) = (uint16_t)(v)) | ||
#define atomic_store_32(p, v) \ | ||
(*(volatile uint32_t *)(p) = (uint32_t)(v)) | ||
#ifdef _LP64 | ||
#define atomic_store_64(p, v) \ | ||
(*(volatile uint64_t *)(p) = (uint64_t)(v)) | ||
#elif defined(_INT64_TYPE) | ||
extern void atomic_store_64(volatile uint64_t *, uint64_t); | ||
#endif | ||
|
||
/* | ||
* Perform an exclusive atomic bit set/clear on a target. | ||
* Returns 0 if bit was successfully set/cleared, or -1 | ||
|
Uh oh!
There was an error while loading. Please reload this page.