diff options
author | Jakub Vaněk <linuxtardis@gmail.com> | 2024-06-11 18:26:30 +0000 |
---|---|---|
committer | Jakub Vaněk <linuxtardis@gmail.com> | 2024-06-11 18:26:30 +0000 |
commit | f5e61ef0a7318ea2492f4af81f0dbe81c5be816e (patch) | |
tree | 7513a3808f945e0121dd98141432cac427aeffed | |
parent | f35d95772308d2c9981d07e54379d94fbec0d044 (diff) |
orconce: Fix typo in GCC __sync-based implementation
The __sync_val_compare_and_swap() function is defined as [1]:
> type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...)
However, the pre-C11 orc_once_enter() function is calling the function like
__sync_val_compare_and_swap(ptr, newval, oldval). This breaks the orconce
implementation: the atomic variable is never set to the initialized state
and so the initialization function is called every time orc_once_enter() is called.
This bug was originally discovered through Buildroot. GStreamer packages are
currently build with -std=c99 or -std=gnu99 there. These flags disable
the C11 orconce codepath and instead the old __sync codepath is selected.
The ultimate effect of this was that all elements relying on ORC (e.g. videotestsrc,
videoconvert) were slowed down significantly by repeated recompiling of the
ORC programs.
[1]: https://gcc.gnu.org/onlinedocs/gcc-12.3.0/gcc/_005f_005fsync-Builtins.html
Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/185>
-rw-r--r-- | orc/orconce.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/orc/orconce.h b/orc/orconce.h index 2be3623..b7df237 100644 --- a/orc/orconce.h +++ b/orc/orconce.h @@ -106,7 +106,7 @@ static inline orc_bool orc_once_enter(OrcOnce *once, void **value) { /* we use 0 for not initialized, 1 for initialized and 3 for currently * being initialized */ - inited = __sync_val_compare_and_swap(&once->inited, 3, 0); + inited = __sync_val_compare_and_swap(&once->inited, 0, 3); /* if the value was previously initialized then just return here */ if (inited == 1) { *value = once->value; |