/proc/self/cwd/external/boringssl/crypto/refcount.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2015, Google Inc. |
2 | | * |
3 | | * Permission to use, copy, modify, and/or distribute this software for any |
4 | | * purpose with or without fee is hereby granted, provided that the above |
5 | | * copyright notice and this permission notice appear in all copies. |
6 | | * |
7 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
8 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
10 | | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
11 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
12 | | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
13 | | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
14 | | |
15 | | #include "internal.h" |
16 | | |
17 | | #include <assert.h> |
18 | | #include <stdlib.h> |
19 | | |
20 | | |
21 | | // See comment above the typedef of CRYPTO_refcount_t about these tests. |
22 | | static_assert(alignof(CRYPTO_refcount_t) == alignof(CRYPTO_atomic_u32), |
23 | | "CRYPTO_refcount_t does not match CRYPTO_atomic_u32 alignment"); |
24 | | static_assert(sizeof(CRYPTO_refcount_t) == sizeof(CRYPTO_atomic_u32), |
25 | | "CRYPTO_refcount_t does not match CRYPTO_atomic_u32 size"); |
26 | | |
27 | | static_assert((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, |
28 | | "CRYPTO_REFCOUNT_MAX is incorrect"); |
29 | | |
30 | 213k | void CRYPTO_refcount_inc(CRYPTO_refcount_t *in_count) { |
31 | 213k | CRYPTO_atomic_u32 *count = (CRYPTO_atomic_u32 *)in_count; |
32 | 213k | uint32_t expected = CRYPTO_atomic_load_u32(count); |
33 | | |
34 | 213k | while (expected != CRYPTO_REFCOUNT_MAX) { |
35 | 213k | uint32_t new_value = expected + 1; |
36 | 213k | if (CRYPTO_atomic_compare_exchange_weak_u32(count, &expected, new_value)) { |
37 | 213k | break; |
38 | 213k | } |
39 | 213k | } |
40 | 213k | } |
41 | | |
42 | 293k | int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) { |
43 | 293k | CRYPTO_atomic_u32 *count = (CRYPTO_atomic_u32 *)in_count; |
44 | 293k | uint32_t expected = CRYPTO_atomic_load_u32(count); |
45 | | |
46 | 293k | for (;;) { |
47 | 293k | if (expected == 0) { |
48 | 0 | abort(); |
49 | 293k | } else if (expected == CRYPTO_REFCOUNT_MAX) { |
50 | 0 | return 0; |
51 | 293k | } else { |
52 | 293k | const uint32_t new_value = expected - 1; |
53 | 293k | if (CRYPTO_atomic_compare_exchange_weak_u32(count, &expected, |
54 | 293k | new_value)) { |
55 | 293k | return new_value == 0; |
56 | 293k | } |
57 | 293k | } |
58 | 293k | } |
59 | 293k | } |