4 * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * version: DPDK.L.1.2.3-3
36 #ifndef _RTE_ATOMIC_H_
37 #define _RTE_ATOMIC_H_
43 * This file defines a generic API for atomic
44 * operations. The implementation is architecture-specific.
46 * See lib/librte_eal/common/include/i686/arch/rte_atomic.h
47 * See lib/librte_eal/common/include/x86_64/arch/rte_atomic.h
56 #include "arch/rte_atomic.h"
62 * General memory barrier.
64 * Guarantees that the LOAD and STORE operations generated before the
65 * barrier occur before the LOAD and STORE operations generated after.
67 #define rte_mb() asm volatile("mfence;" : : : "memory")
70 * Write memory barrier.
72 * Guarantees that the STORE operations generated before the barrier
73 * occur before the STORE operations generated after.
75 #define rte_wmb() asm volatile("sfence;" : : : "memory")
78 * Read memory barrier.
80 * Guarantees that the LOAD operations generated before the barrier
81 * occur before the LOAD operations generated after.
83 #define rte_rmb() asm volatile("lfence;" : : : "memory")
85 /*------------------------- 16 bit atomic operations -------------------------*/
88 * Atomic compare and set.
90 * (atomic) equivalent to:
92 * *dst = src (all 16-bit words)
95 * The destination location into which the value will be written.
101 * Non-zero on success; 0 on failure.
104 rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src);
107 * The atomic counter structure.
110 volatile int16_t cnt; /**< An internal counter value. */
114 * Static initializer for an atomic counter.
116 #define RTE_ATOMIC16_INIT(val) { (val) }
119 * Initialize an atomic counter.
122 * A pointer to the atomic counter.
125 rte_atomic16_init(rte_atomic16_t *v)
131 * Atomically read a 16-bit value from a counter.
134 * A pointer to the atomic counter.
136 * The value of the counter.
138 static inline int16_t
139 rte_atomic16_read(const rte_atomic16_t *v);
142 * Atomically set a counter to a 16-bit value.
145 * A pointer to the atomic counter.
147 * The new value for the counter.
150 rte_atomic16_set(rte_atomic16_t *v, int16_t new_value);
153 * Atomically add a 16-bit value to an atomic counter.
156 * A pointer to the atomic counter.
158 * The value to be added to the counter.
161 rte_atomic16_add(rte_atomic16_t *v, int16_t inc);
164 * Atomically subtract a 16-bit value from an atomic counter.
167 * A pointer to the atomic counter.
169 * The value to be subtracted from the counter.
172 rte_atomic16_sub(rte_atomic16_t *v, int16_t dec);
175 * Atomically increment a counter by one.
178 * A pointer to the atomic counter.
181 rte_atomic16_inc(rte_atomic16_t *v);
184 * Atomically decrement a counter by one.
187 * A pointer to the atomic counter.
190 rte_atomic16_dec(rte_atomic16_t *v);
193 * Atomically add a 16-bit value to a counter and return the result.
195 * Atomically adds the 16-bits value (inc) to the atomic counter (v) and
196 * returns the value of v after addition.
199 * A pointer to the atomic counter.
201 * The value to be added to the counter.
203 * The value of v after the addition.
205 static inline int16_t
206 rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc);
209 * Atomically subtract a 16-bit value from a counter and return
212 * Atomically subtracts the 16-bit value (inc) from the atomic counter
213 * (v) and returns the value of v after the subtraction.
216 * A pointer to the atomic counter.
218 * The value to be subtracted from the counter.
220 * The value of v after the subtraction.
222 static inline int16_t
223 rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec);
226 * Atomically increment a 16-bit counter by one and test.
228 * Atomically increments the atomic counter (v) by one and returns true if
229 * the result is 0, or false in all other cases.
232 * A pointer to the atomic counter.
234 * True if the result after the increment operation is 0; false otherwise.
237 rte_atomic16_inc_and_test(rte_atomic16_t *v);
240 * Atomically decrement a 16-bit counter by one and test.
242 * Atomically decrements the atomic counter (v) by one and returns true if
243 * the result is 0, or false in all other cases.
246 * A pointer to the atomic counter.
248 * True if the result after the decrement operation is 0; false otherwise.
251 rte_atomic16_dec_and_test(rte_atomic16_t *v);
254 * Atomically test and set a 16-bit atomic counter.
256 * If the counter value is already set, return 0 (failed). Otherwise, set
257 * the counter value to 1 and return 1 (success).
260 * A pointer to the atomic counter.
262 * 0 if failed; else 1, success.
265 rte_atomic16_test_and_set(rte_atomic16_t *v);
268 * Atomically set a 16-bit counter to 0.
271 * A pointer to the atomic counter.
274 rte_atomic16_clear(rte_atomic16_t *v);
276 /*------------------------- 32 bit atomic operations -------------------------*/
279 * Atomic compare and set.
281 * (atomic) equivalent to:
283 * *dst = src (all 32-bit words)
286 * The destination location into which the value will be written.
288 * The expected value.
292 * Non-zero on success; 0 on failure.
295 rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src);
298 * The atomic counter structure.
301 volatile int32_t cnt; /**< An internal counter value. */
305 * Static initializer for an atomic counter.
307 #define RTE_ATOMIC32_INIT(val) { (val) }
310 * Initialize an atomic counter.
313 * A pointer to the atomic counter.
316 rte_atomic32_init(rte_atomic32_t *v);
319 * Atomically read a 32-bit value from a counter.
322 * A pointer to the atomic counter.
324 * The value of the counter.
326 static inline int32_t
327 rte_atomic32_read(const rte_atomic32_t *v);
330 * Atomically set a counter to a 32-bit value.
333 * A pointer to the atomic counter.
335 * The new value for the counter.
338 rte_atomic32_set(rte_atomic32_t *v, int32_t new_value);
341 * Atomically add a 32-bit value to an atomic counter.
344 * A pointer to the atomic counter.
346 * The value to be added to the counter.
349 rte_atomic32_add(rte_atomic32_t *v, int32_t inc);
352 * Atomically subtract a 32-bit value from an atomic counter.
355 * A pointer to the atomic counter.
357 * The value to be subtracted from the counter.
360 rte_atomic32_sub(rte_atomic32_t *v, int32_t dec);
363 * Atomically increment a counter by one.
366 * A pointer to the atomic counter.
369 rte_atomic32_inc(rte_atomic32_t *v);
372 * Atomically decrement a counter by one.
375 * A pointer to the atomic counter.
378 rte_atomic32_dec(rte_atomic32_t *v);
381 * Atomically add a 32-bit value to a counter and return the result.
383 * Atomically adds the 32-bits value (inc) to the atomic counter (v) and
384 * returns the value of v after addition.
387 * A pointer to the atomic counter.
389 * The value to be added to the counter.
391 * The value of v after the addition.
393 static inline int32_t
394 rte_atomic32_add_return(rte_atomic32_t *v, int32_t inc);
397 * Atomically subtract a 32-bit value from a counter and return
400 * Atomically subtracts the 32-bit value (inc) from the atomic counter
401 * (v) and returns the value of v after the subtraction.
404 * A pointer to the atomic counter.
406 * The value to be subtracted from the counter.
408 * The value of v after the subtraction.
410 static inline int32_t
411 rte_atomic32_sub_return(rte_atomic32_t *v, int32_t dec);
414 * Atomically increment a 32-bit counter by one and test.
416 * Atomically increments the atomic counter (v) by one and returns true if
417 * the result is 0, or false in all other cases.
420 * A pointer to the atomic counter.
422 * True if the result after the increment operation is 0; false otherwise.
425 rte_atomic32_inc_and_test(rte_atomic32_t *v);
428 * Atomically decrement a 32-bit counter by one and test.
430 * Atomically decrements the atomic counter (v) by one and returns true if
431 * the result is 0, or false in all other cases.
434 * A pointer to the atomic counter.
436 * True if the result after the decrement operation is 0; false otherwise.
439 rte_atomic32_dec_and_test(rte_atomic32_t *v);
442 * Atomically test and set a 32-bit atomic counter.
444 * If the counter value is already set, return 0 (failed). Otherwise, set
445 * the counter value to 1 and return 1 (success).
448 * A pointer to the atomic counter.
450 * 0 if failed; else 1, success.
453 rte_atomic32_test_and_set(rte_atomic32_t *v);
456 * Atomically set a 32-bit counter to 0.
459 * A pointer to the atomic counter.
462 rte_atomic32_clear(rte_atomic32_t *v);
464 /*------------------------- 64 bit atomic operations -------------------------*/
467 * An atomic compare and set function used by the mutex functions.
468 * (atomic) equivalent to:
470 * *dst = src (all 64-bit words)
473 * The destination into which the value will be written.
475 * The expected value.
479 * Non-zero on success; 0 on failure.
482 rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src);
485 * The atomic counter structure.
488 volatile int64_t cnt; /**< Internal counter value. */
492 * Static initializer for an atomic counter.
494 #define RTE_ATOMIC64_INIT(val) { (val) }
497 * Initialize the atomic counter.
500 * A pointer to the atomic counter.
503 rte_atomic64_init(rte_atomic64_t *v);
506 * Atomically read a 64-bit counter.
509 * A pointer to the atomic counter.
511 * The value of the counter.
513 static inline int64_t
514 rte_atomic64_read(rte_atomic64_t *v);
517 * Atomically set a 64-bit counter.
520 * A pointer to the atomic counter.
522 * The new value of the counter.
525 rte_atomic64_set(rte_atomic64_t *v, int64_t new_value);
528 * Atomically add a 64-bit value to a counter.
531 * A pointer to the atomic counter.
533 * The value to be added to the counter.
536 rte_atomic64_add(rte_atomic64_t *v, int64_t inc);
539 * Atomically subtract a 64-bit value from a counter.
542 * A pointer to the atomic counter.
544 * The value to be subtracted from the counter.
547 rte_atomic64_sub(rte_atomic64_t *v, int64_t dec);
550 * Atomically increment a 64-bit counter by one and test.
553 * A pointer to the atomic counter.
556 rte_atomic64_inc(rte_atomic64_t *v);
559 * Atomically decrement a 64-bit counter by one and test.
562 * A pointer to the atomic counter.
565 rte_atomic64_dec(rte_atomic64_t *v);
568 * Add a 64-bit value to an atomic counter and return the result.
570 * Atomically adds the 64-bit value (inc) to the atomic counter (v) and
571 * returns the value of v after the addition.
574 * A pointer to the atomic counter.
576 * The value to be added to the counter.
578 * The value of v after the addition.
580 static inline int64_t
581 rte_atomic64_add_return(rte_atomic64_t *v, int64_t inc);
584 * Subtract a 64-bit value from an atomic counter and return the result.
586 * Atomically subtracts the 64-bit value (dec) from the atomic counter (v)
587 * and returns the value of v after the subtraction.
590 * A pointer to the atomic counter.
592 * The value to be subtracted from the counter.
594 * The value of v after the subtraction.
596 static inline int64_t
597 rte_atomic64_sub_return(rte_atomic64_t *v, int64_t dec);
600 * Atomically increment a 64-bit counter by one and test.
602 * Atomically increments the atomic counter (v) by one and returns
603 * true if the result is 0, or false in all other cases.
606 * A pointer to the atomic counter.
608 * True if the result after the addition is 0; false otherwise.
611 rte_atomic64_inc_and_test(rte_atomic64_t *v);
614 * Atomically decrement a 64-bit counter by one and test.
616 * Atomically decrements the atomic counter (v) by one and returns true if
617 * the result is 0, or false in all other cases.
620 * A pointer to the atomic counter.
622 * True if the result after subtraction is 0; false otherwise.
625 rte_atomic64_dec_and_test(rte_atomic64_t *v);
628 * Atomically test and set a 64-bit atomic counter.
630 * If the counter value is already set, return 0 (failed). Otherwise, set
631 * the counter value to 1 and return 1 (success).
634 * A pointer to the atomic counter.
636 * 0 if failed; else 1, success.
639 rte_atomic64_test_and_set(rte_atomic64_t *v);
642 * Atomically set a 64-bit counter to 0.
645 * A pointer to the atomic counter.
648 rte_atomic64_clear(rte_atomic64_t *v);
650 #endif /* __DOXYGEN__ */
657 #endif /* _RTE_ATOMIC_H_ */