LCOV - code coverage report
Current view: top level - aws-c-common/include/aws/common - atomics_gnu.inl (source / functions) Hit Total Coverage
Test: all_fuzz.info Lines: 15 76 19.7 %
Date: 2021-04-23 16:28:21 Functions: 9 187 4.8 %

          Line data    Source code
       1             : #ifndef AWS_COMMON_ATOMICS_GNU_INL
       2             : #define AWS_COMMON_ATOMICS_GNU_INL
       3             : 
       4             : /**
       5             :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       6             :  * SPDX-License-Identifier: Apache-2.0.
       7             :  */
       8             : 
       9             : /* These are implicitly included, but help with editor highlighting */
      10             : #include <aws/common/atomics.h>
      11             : #include <aws/common/common.h>
      12             : 
      13             : #include <stdint.h>
      14             : #include <stdlib.h>
      15             : 
      16             : AWS_EXTERN_C_BEGIN
      17             : 
      18             : #ifdef __clang__
      19             : #    pragma clang diagnostic push
      20             : #    pragma clang diagnostic ignored "-Wc11-extensions"
      21             : #else
      22             : #    pragma GCC diagnostic push
      23             : #    pragma GCC diagnostic ignored "-Wpedantic"
      24             : #endif
      25             : 
      26             : typedef size_t aws_atomic_impl_int_t;
      27             : 
      28      130000 : static inline int aws_atomic_priv_xlate_order(enum aws_memory_order order) {
      29      130000 :     switch (order) {
      30           0 :         case aws_memory_order_relaxed:
      31           0 :             return __ATOMIC_RELAXED;
      32           0 :         case aws_memory_order_acquire:
      33           0 :             return __ATOMIC_ACQUIRE;
      34           0 :         case aws_memory_order_release:
      35           0 :             return __ATOMIC_RELEASE;
      36           0 :         case aws_memory_order_acq_rel:
      37           0 :             return __ATOMIC_ACQ_REL;
      38      130000 :         case aws_memory_order_seq_cst:
      39      130000 :             return __ATOMIC_SEQ_CST;
      40           0 :         default: /* Unknown memory order */
      41           0 :             abort();
      42      130000 :     }
      43      130000 : }
      44             : 
      45             : /**
      46             :  * Initializes an atomic variable with an integer value. This operation should be done before any
      47             :  * other operations on this atomic variable, and must be done before attempting any parallel operations.
      48             :  */
      49             : AWS_STATIC_IMPL
      50           0 : void aws_atomic_init_int(volatile struct aws_atomic_var *var, size_t n) {
      51           0 :     AWS_ATOMIC_VAR_INTVAL(var) = n;
      52           0 : }
      53             : 
      54             : /**
      55             :  * Initializes an atomic variable with a pointer value. This operation should be done before any
      56             :  * other operations on this atomic variable, and must be done before attempting any parallel operations.
      57             :  */
      58             : AWS_STATIC_IMPL
      59       15838 : void aws_atomic_init_ptr(volatile struct aws_atomic_var *var, void *p) {
      60       15838 :     AWS_ATOMIC_VAR_PTRVAL(var) = p;
      61       15838 : }
      62             : 
      63             : /**
      64             :  * Reads an atomic var as an integer, using the specified ordering, and returns the result.
      65             :  */
      66             : AWS_STATIC_IMPL
      67           0 : size_t aws_atomic_load_int_explicit(volatile const struct aws_atomic_var *var, enum aws_memory_order memory_order) {
      68           0 :     return __atomic_load_n(&AWS_ATOMIC_VAR_INTVAL(var), aws_atomic_priv_xlate_order(memory_order));
      69           0 : }
      70             : 
      71             : /**
      72             :  * Reads an atomic var as a pointer, using the specified ordering, and returns the result.
      73             :  */
      74             : AWS_STATIC_IMPL
      75      104756 : void *aws_atomic_load_ptr_explicit(volatile const struct aws_atomic_var *var, enum aws_memory_order memory_order) {
      76      104756 :     return __atomic_load_n(&AWS_ATOMIC_VAR_PTRVAL(var), aws_atomic_priv_xlate_order(memory_order));
      77      104756 : }
      78             : 
      79             : /**
      80             :  * Stores an integer into an atomic var, using the specified ordering.
      81             :  */
      82             : AWS_STATIC_IMPL
      83           0 : void aws_atomic_store_int_explicit(volatile struct aws_atomic_var *var, size_t n, enum aws_memory_order memory_order) {
      84           0 :     __atomic_store_n(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(memory_order));
      85           0 : }
      86             : 
      87             : /**
      88             :  * Stores an pointer into an atomic var, using the specified ordering.
      89             :  */
      90             : AWS_STATIC_IMPL
      91       25244 : void aws_atomic_store_ptr_explicit(volatile struct aws_atomic_var *var, void *p, enum aws_memory_order memory_order) {
      92       25244 :     __atomic_store_n(&AWS_ATOMIC_VAR_PTRVAL(var), p, aws_atomic_priv_xlate_order(memory_order));
      93       25244 : }
      94             : 
      95             : /**
      96             :  * Exchanges an integer with the value in an atomic_var, using the specified ordering.
      97             :  * Returns the value that was previously in the atomic_var.
      98             :  */
      99             : AWS_STATIC_IMPL
     100             : size_t aws_atomic_exchange_int_explicit(
     101             :     volatile struct aws_atomic_var *var,
     102             :     size_t n,
     103           0 :     enum aws_memory_order memory_order) {
     104           0 :     return __atomic_exchange_n(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(memory_order));
     105           0 : }
     106             : 
     107             : /**
     108             :  * Exchanges a pointer with the value in an atomic_var, using the specified ordering.
     109             :  * Returns the value that was previously in the atomic_var.
     110             :  */
     111             : AWS_STATIC_IMPL
     112             : void *aws_atomic_exchange_ptr_explicit(
     113             :     volatile struct aws_atomic_var *var,
     114             :     void *p,
     115           0 :     enum aws_memory_order memory_order) {
     116           0 :     return __atomic_exchange_n(&AWS_ATOMIC_VAR_PTRVAL(var), p, aws_atomic_priv_xlate_order(memory_order));
     117           0 : }
     118             : 
     119             : /**
     120             :  * Atomically compares *var to *expected; if they are equal, atomically sets *var = desired. Otherwise, *expected is set
     121             :  * to the value in *var. On success, the memory ordering used was order_success; otherwise, it was order_failure.
     122             :  * order_failure must be no stronger than order_success, and must not be release or acq_rel.
     123             :  */
     124             : AWS_STATIC_IMPL
     125             : bool aws_atomic_compare_exchange_int_explicit(
     126             :     volatile struct aws_atomic_var *var,
     127             :     size_t *expected,
     128             :     size_t desired,
     129             :     enum aws_memory_order order_success,
     130           0 :     enum aws_memory_order order_failure) {
     131           0 :     return __atomic_compare_exchange_n(
     132           0 :         &AWS_ATOMIC_VAR_INTVAL(var),
     133           0 :         expected,
     134           0 :         desired,
     135           0 :         false,
     136           0 :         aws_atomic_priv_xlate_order(order_success),
     137           0 :         aws_atomic_priv_xlate_order(order_failure));
     138           0 : }
     139             : 
     140             : /**
     141             :  * Atomically compares *var to *expected; if they are equal, atomically sets *var = desired. Otherwise, *expected is set
     142             :  * to the value in *var. On success, the memory ordering used was order_success; otherwise, it was order_failure.
     143             :  * order_failure must be no stronger than order_success, and must not be release or acq_rel.
     144             :  */
     145             : AWS_STATIC_IMPL
     146             : bool aws_atomic_compare_exchange_ptr_explicit(
     147             :     volatile struct aws_atomic_var *var,
     148             :     void **expected,
     149             :     void *desired,
     150             :     enum aws_memory_order order_success,
     151           0 :     enum aws_memory_order order_failure) {
     152           0 :     return __atomic_compare_exchange_n(
     153           0 :         &AWS_ATOMIC_VAR_PTRVAL(var),
     154           0 :         expected,
     155           0 :         desired,
     156           0 :         false,
     157           0 :         aws_atomic_priv_xlate_order(order_success),
     158           0 :         aws_atomic_priv_xlate_order(order_failure));
     159           0 : }
     160             : 
     161             : /**
     162             :  * Atomically adds n to *var, and returns the previous value of *var.
     163             :  */
     164             : AWS_STATIC_IMPL
     165           0 : size_t aws_atomic_fetch_add_explicit(volatile struct aws_atomic_var *var, size_t n, enum aws_memory_order order) {
     166           0 :     return __atomic_fetch_add(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(order));
     167           0 : }
     168             : 
     169             : /**
     170             :  * Atomically subtracts n from *var, and returns the previous value of *var.
     171             :  */
     172             : AWS_STATIC_IMPL
     173           0 : size_t aws_atomic_fetch_sub_explicit(volatile struct aws_atomic_var *var, size_t n, enum aws_memory_order order) {
     174           0 :     return __atomic_fetch_sub(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(order));
     175           0 : }
     176             : 
     177             : /**
     178             :  * Atomically ORs n with *var, and returns the previous value of *var.
     179             :  */
     180             : AWS_STATIC_IMPL
     181           0 : size_t aws_atomic_fetch_or_explicit(volatile struct aws_atomic_var *var, size_t n, enum aws_memory_order order) {
     182           0 :     return __atomic_fetch_or(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(order));
     183           0 : }
     184             : 
     185             : /**
     186             :  * Atomically ANDs n with *var, and returns the previous value of *var.
     187             :  */
     188             : AWS_STATIC_IMPL
     189           0 : size_t aws_atomic_fetch_and_explicit(volatile struct aws_atomic_var *var, size_t n, enum aws_memory_order order) {
     190           0 :     return __atomic_fetch_and(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(order));
     191           0 : }
     192             : 
     193             : /**
     194             :  * Atomically XORs n with *var, and returns the previous value of *var.
     195             :  */
     196             : AWS_STATIC_IMPL
     197           0 : size_t aws_atomic_fetch_xor_explicit(volatile struct aws_atomic_var *var, size_t n, enum aws_memory_order order) {
     198           0 :     return __atomic_fetch_xor(&AWS_ATOMIC_VAR_INTVAL(var), n, aws_atomic_priv_xlate_order(order));
     199           0 : }
     200             : 
     201             : /**
     202             :  * Provides the same reordering guarantees as an atomic operation with the specified memory order, without
     203             :  * needing to actually perform an atomic operation.
     204             :  */
     205             : AWS_STATIC_IMPL
     206           0 : void aws_atomic_thread_fence(enum aws_memory_order order) {
     207           0 :     __atomic_thread_fence(order);
     208           0 : }
     209             : 
     210             : #ifdef __clang__
     211             : #    pragma clang diagnostic pop
     212             : #else
     213             : #    pragma GCC diagnostic pop
     214             : #endif
     215             : 
     216             : #define AWS_ATOMICS_HAVE_THREAD_FENCE
     217             : AWS_EXTERN_C_END
     218             : #endif /* AWS_COMMON_ATOMICS_GNU_INL */

Generated by: LCOV version 1.13