__sync_val_compare_and_swap vs __sync_bool_compare_and_swap

荒凉一梦 提交于 2019-12-05 13:02:35

The operation provided by __sync_val_compare_and_swap can always be implemented in terms of __sync_bool_compare_and_swap (and of course the other direction is obviously possible), so in terms of power the two are equivalent. However implementing __sync_val_compare_and_swap in terms of __sync_bool_compare_and_swap is not very efficient. It looks something like:

for (;;) {
    bool success = __sync_bool_compare_and_swap(ptr, oldval, newval);
    if (success) return oldval;
    type tmp = *ptr;
    __sync_synchronize();
    if (tmp != oldval) return tmp;
}

The extra work is needed because you could observe failure of __sync_bool_compare_and_swap but then read a new value from *ptr that happens to match oldval.

As for why you might prefer the __sync_val_compare_and_swap behavior, the value that caused failure may give you a starting point to retry the operation more efficiently or might indicate a meaningful cause of the failure for some operation that won't be "retried". As an example, see the code for pthread_spin_trylock in musl libc (for which I am the author):

http://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_spin_trylock.c?id=afbcac6826988d12d9a874359cab735049c17500

There a_cas is equivalent to __sync_val_compare_and_swap. In some ways this is a stupid example since it's just saving a branch or conditional move by using the old value, but there are other situations where multiple old values are possible and knowing the one that caused the operation to fail matters.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!