| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: atomic.h,v 1.1.2.8 2013/07/24 02:28:36 riastradh Exp $ */ | | 1 | /* $NetBSD: atomic.h,v 1.1.2.9 2013/07/24 03:35:50 riastradh Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2013 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Taylor R. Campbell. | | 8 | * by Taylor R. Campbell. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -51,51 +51,90 @@ atomic_read(atomic_t *atomic) | | | @@ -51,51 +51,90 @@ atomic_read(atomic_t *atomic) |
51 | | | 51 | |
52 | static inline void | | 52 | static inline void |
53 | atomic_set(atomic_t *atomic, int value) | | 53 | atomic_set(atomic_t *atomic, int value) |
54 | { | | 54 | { |
55 | atomic->a_u.au_int = value; | | 55 | atomic->a_u.au_int = value; |
56 | } | | 56 | } |
57 | | | 57 | |
58 | static inline void | | 58 | static inline void |
59 | atomic_add(int addend, atomic_t *atomic) | | 59 | atomic_add(int addend, atomic_t *atomic) |
60 | { | | 60 | { |
61 | atomic_add_int(&atomic->a_u.au_uint, addend); | | 61 | atomic_add_int(&atomic->a_u.au_uint, addend); |
62 | } | | 62 | } |
63 | | | 63 | |
| | | 64 | static inline void |
| | | 65 | atomic_sub(int subtrahend, atomic_t *atomic) |
| | | 66 | { |
| | | 67 | atomic_add_int(&atomic->a_u.au_uint, -subtrahend); |
| | | 68 | } |
| | | 69 | |
64 | static inline int | | 70 | static inline int |
65 | atomic_add_return(int addend, atomic_t *atomic) | | 71 | atomic_add_return(int addend, atomic_t *atomic) |
66 | { | | 72 | { |
67 | return (int)atomic_add_int_nv(&atomic->a_u.au_uint, addend); | | 73 | return (int)atomic_add_int_nv(&atomic->a_u.au_uint, addend); |
68 | } | | 74 | } |
69 | | | 75 | |
70 | static inline void | | 76 | static inline void |
71 | atomic_inc(atomic_t *atomic) | | 77 | atomic_inc(atomic_t *atomic) |
72 | { | | 78 | { |
73 | atomic_inc_uint(&atomic->a_u.au_uint); | | 79 | atomic_inc_uint(&atomic->a_u.au_uint); |
74 | } | | 80 | } |
75 | | | 81 | |
76 | static inline void | | 82 | static inline void |
77 | atomic_dec(atomic_t *atomic) | | 83 | atomic_dec(atomic_t *atomic) |
78 | { | | 84 | { |
79 | atomic_dec_uint(&atomic->a_u.au_uint); | | 85 | atomic_dec_uint(&atomic->a_u.au_uint); |
80 | } | | 86 | } |
81 | | | 87 | |
82 | static inline int | | 88 | static inline int |
83 | atomic_dec_and_test(atomic_t *atomic) | | 89 | atomic_dec_and_test(atomic_t *atomic) |
84 | { | | 90 | { |
85 | return (-1 == (int)atomic_dec_uint_nv(&atomic->a_u.au_uint)); | | 91 | return (-1 == (int)atomic_dec_uint_nv(&atomic->a_u.au_uint)); |
86 | } | | 92 | } |
87 | | | 93 | |
88 | static inline void | | 94 | static inline void |
| | | 95 | atomic_set_mask(unsigned long mask, atomic_t *atomic) |
| | | 96 | { |
| | | 97 | atomic_or_uint(&atomic->a_u.au_uint, mask); |
| | | 98 | } |
| | | 99 | |
| | | 100 | static inline void |
| | | 101 | atomic_clear_mask(unsigned long mask, atomic_t *atomic) |
| | | 102 | { |
| | | 103 | atomic_and_uint(&atomic->a_u.au_uint, ~mask); |
| | | 104 | } |
| | | 105 | |
| | | 106 | static inline int |
| | | 107 | atomic_add_unless(atomic_t *atomic, int addend, int zero) |
| | | 108 | { |
| | | 109 | int value; |
| | | 110 | |
| | | 111 | do { |
| | | 112 | value = atomic->a_u.au_int; |
| | | 113 | if (value == zero) |
| | | 114 | return 0; |
| | | 115 | } while (atomic_cas_uint(&atomic->a_u.au_uint, value, (value + addend)) |
| | | 116 | != value); |
| | | 117 | |
| | | 118 | return 1; |
| | | 119 | } |
| | | 120 | |
| | | 121 | static inline int |
| | | 122 | atomic_inc_not_zero(atomic_t *atomic) |
| | | 123 | { |
| | | 124 | return atomic_add_unless(atomic, 1, 0); |
| | | 125 | } |
| | | 126 | |
| | | 127 | static inline void |
89 | set_bit(unsigned long bit, volatile unsigned long *ptr) | | 128 | set_bit(unsigned long bit, volatile unsigned long *ptr) |
90 | { | | 129 | { |
91 | atomic_or_ulong(ptr, (1 << bit)); | | 130 | atomic_or_ulong(ptr, (1 << bit)); |
92 | } | | 131 | } |
93 | | | 132 | |
94 | static inline void | | 133 | static inline void |
95 | clear_bit(unsigned long bit, volatile unsigned long *ptr) | | 134 | clear_bit(unsigned long bit, volatile unsigned long *ptr) |
96 | { | | 135 | { |
97 | atomic_and_ulong(ptr, ~(1 << bit)); | | 136 | atomic_and_ulong(ptr, ~(1 << bit)); |
98 | } | | 137 | } |
99 | | | 138 | |
100 | static inline void | | 139 | static inline void |
101 | change_bit(unsigned long bit, volatile unsigned long *ptr) | | 140 | change_bit(unsigned long bit, volatile unsigned long *ptr) |