remove version in all files
[dpdk.git] / lib / librte_eal / common / include / rte_atomic.h
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
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 
16  *       distribution.
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.
20  * 
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.
32  * 
33  */
34
35 #ifndef _RTE_ATOMIC_H_
36 #define _RTE_ATOMIC_H_
37
38 /**
39  * @file
40  * Atomic Operations
41  *
42  * This file defines a generic API for atomic
43  * operations. The implementation is architecture-specific.
44  *
45  * See lib/librte_eal/common/include/i686/arch/rte_atomic.h
46  * See lib/librte_eal/common/include/x86_64/arch/rte_atomic.h
47  */
48
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52
53 #include <stdint.h>
54
55 #include "arch/rte_atomic.h"
56
57
58 #ifdef __DOXYGEN__
59
60 /**
61  * General memory barrier.
62  *
63  * Guarantees that the LOAD and STORE operations generated before the
64  * barrier occur before the LOAD and STORE operations generated after.
65  */
66 #define rte_mb()  asm volatile("mfence;" : : : "memory")
67
68 /**
69  * Write memory barrier.
70  *
71  * Guarantees that the STORE operations generated before the barrier
72  * occur before the STORE operations generated after.
73  */
74 #define rte_wmb() asm volatile("sfence;" : : : "memory")
75
76 /**
77  * Read memory barrier.
78  *
79  * Guarantees that the LOAD operations generated before the barrier
80  * occur before the LOAD operations generated after.
81  */
82 #define rte_rmb() asm volatile("lfence;" : : : "memory")
83
84 /*------------------------- 16 bit atomic operations -------------------------*/
85
86 /**
87  * Atomic compare and set.
88  *
89  * (atomic) equivalent to:
90  *   if (*dst == exp)
91  *     *dst = src (all 16-bit words)
92  *
93  * @param dst
94  *   The destination location into which the value will be written.
95  * @param exp
96  *   The expected value.
97  * @param src
98  *   The new value.
99  * @return
100  *   Non-zero on success; 0 on failure.
101  */
102 static inline int
103 rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src);
104
105 /**
106  * The atomic counter structure.
107  */
108 typedef struct {
109         volatile int16_t cnt; /**< An internal counter value. */
110 } rte_atomic16_t;
111
112 /**
113  * Static initializer for an atomic counter.
114  */
115 #define RTE_ATOMIC16_INIT(val) { (val) }
116
117 /**
118  * Initialize an atomic counter.
119  *
120  * @param v
121  *   A pointer to the atomic counter.
122  */
123 static inline void
124 rte_atomic16_init(rte_atomic16_t *v)
125 {
126         v->cnt = 0;
127 }
128
129 /**
130  * Atomically read a 16-bit value from a counter.
131  *
132  * @param v
133  *   A pointer to the atomic counter.
134  * @return
135  *   The value of the counter.
136  */
137 static inline int16_t
138 rte_atomic16_read(const rte_atomic16_t *v);
139
140 /**
141  * Atomically set a counter to a 16-bit value.
142  *
143  * @param v
144  *   A pointer to the atomic counter.
145  * @param new_value
146  *   The new value for the counter.
147  */
148 static inline void
149 rte_atomic16_set(rte_atomic16_t *v, int16_t new_value);
150
151 /**
152  * Atomically add a 16-bit value to an atomic counter.
153  *
154  * @param v
155  *   A pointer to the atomic counter.
156  * @param inc
157  *   The value to be added to the counter.
158  */
159 static inline void
160 rte_atomic16_add(rte_atomic16_t *v, int16_t inc);
161
162 /**
163  * Atomically subtract a 16-bit value from an atomic counter.
164  *
165  * @param v
166  *   A pointer to the atomic counter.
167  * @param dec
168  *   The value to be subtracted from the counter.
169  */
170 static inline void
171 rte_atomic16_sub(rte_atomic16_t *v, int16_t dec);
172
173 /**
174  * Atomically increment a counter by one.
175  *
176  * @param v
177  *   A pointer to the atomic counter.
178  */
179 static inline void
180 rte_atomic16_inc(rte_atomic16_t *v);
181
182 /**
183  * Atomically decrement a counter by one.
184  *
185  * @param v
186  *   A pointer to the atomic counter.
187  */
188 static inline void
189 rte_atomic16_dec(rte_atomic16_t *v);
190
191 /**
192  * Atomically add a 16-bit value to a counter and return the result.
193  *
194  * Atomically adds the 16-bits value (inc) to the atomic counter (v) and
195  * returns the value of v after addition.
196  *
197  * @param v
198  *   A pointer to the atomic counter.
199  * @param inc
200  *   The value to be added to the counter.
201  * @return
202  *   The value of v after the addition.
203  */
204 static inline int16_t
205 rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc);
206
207 /**
208  * Atomically subtract a 16-bit value from a counter and return
209  * the result.
210  *
211  * Atomically subtracts the 16-bit value (inc) from the atomic counter
212  * (v) and returns the value of v after the subtraction.
213  *
214  * @param v
215  *   A pointer to the atomic counter.
216  * @param dec
217  *   The value to be subtracted from the counter.
218  * @return
219  *   The value of v after the subtraction.
220  */
221 static inline int16_t
222 rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec);
223
224 /**
225  * Atomically increment a 16-bit counter by one and test.
226  *
227  * Atomically increments the atomic counter (v) by one and returns true if
228  * the result is 0, or false in all other cases.
229  *
230  * @param v
231  *   A pointer to the atomic counter.
232  * @return
233  *   True if the result after the increment operation is 0; false otherwise.
234  */
235 static inline int
236 rte_atomic16_inc_and_test(rte_atomic16_t *v);
237
238 /**
239  * Atomically decrement a 16-bit counter by one and test.
240  *
241  * Atomically decrements the atomic counter (v) by one and returns true if
242  * the result is 0, or false in all other cases.
243  *
244  * @param v
245  *   A pointer to the atomic counter.
246  * @return
247  *   True if the result after the decrement operation is 0; false otherwise.
248  */
249 static inline int
250 rte_atomic16_dec_and_test(rte_atomic16_t *v);
251
252 /**
253  * Atomically test and set a 16-bit atomic counter.
254  *
255  * If the counter value is already set, return 0 (failed). Otherwise, set
256  * the counter value to 1 and return 1 (success).
257  *
258  * @param v
259  *   A pointer to the atomic counter.
260  * @return
261  *   0 if failed; else 1, success.
262  */
263 static inline int
264 rte_atomic16_test_and_set(rte_atomic16_t *v);
265
266 /**
267  * Atomically set a 16-bit counter to 0.
268  *
269  * @param v
270  *   A pointer to the atomic counter.
271  */
272 static inline void
273 rte_atomic16_clear(rte_atomic16_t *v);
274
275 /*------------------------- 32 bit atomic operations -------------------------*/
276
277 /**
278  * Atomic compare and set.
279  *
280  * (atomic) equivalent to:
281  *   if (*dst == exp)
282  *     *dst = src (all 32-bit words)
283  *
284  * @param dst
285  *   The destination location into which the value will be written.
286  * @param exp
287  *   The expected value.
288  * @param src
289  *   The new value.
290  * @return
291  *   Non-zero on success; 0 on failure.
292  */
293 static inline int
294 rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src);
295
296 /**
297  * The atomic counter structure.
298  */
299 typedef struct {
300         volatile int32_t cnt; /**< An internal counter value. */
301 } rte_atomic32_t;
302
303 /**
304  * Static initializer for an atomic counter.
305  */
306 #define RTE_ATOMIC32_INIT(val) { (val) }
307
308 /**
309  * Initialize an atomic counter.
310  *
311  * @param v
312  *   A pointer to the atomic counter.
313  */
314 static inline void
315 rte_atomic32_init(rte_atomic32_t *v);
316
317 /**
318  * Atomically read a 32-bit value from a counter.
319  *
320  * @param v
321  *   A pointer to the atomic counter.
322  * @return
323  *   The value of the counter.
324  */
325 static inline int32_t
326 rte_atomic32_read(const rte_atomic32_t *v);
327
328 /**
329  * Atomically set a counter to a 32-bit value.
330  *
331  * @param v
332  *   A pointer to the atomic counter.
333  * @param new_value
334  *   The new value for the counter.
335  */
336 static inline void
337 rte_atomic32_set(rte_atomic32_t *v, int32_t new_value);
338
339 /**
340  * Atomically add a 32-bit value to an atomic counter.
341  *
342  * @param v
343  *   A pointer to the atomic counter.
344  * @param inc
345  *   The value to be added to the counter.
346  */
347 static inline void
348 rte_atomic32_add(rte_atomic32_t *v, int32_t inc);
349
350 /**
351  * Atomically subtract a 32-bit value from an atomic counter.
352  *
353  * @param v
354  *   A pointer to the atomic counter.
355  * @param dec
356  *   The value to be subtracted from the counter.
357  */
358 static inline void
359 rte_atomic32_sub(rte_atomic32_t *v, int32_t dec);
360
361 /**
362  * Atomically increment a counter by one.
363  *
364  * @param v
365  *   A pointer to the atomic counter.
366  */
367 static inline void
368 rte_atomic32_inc(rte_atomic32_t *v);
369
370 /**
371  * Atomically decrement a counter by one.
372  *
373  * @param v
374  *   A pointer to the atomic counter.
375  */
376 static inline void
377 rte_atomic32_dec(rte_atomic32_t *v);
378
379 /**
380  * Atomically add a 32-bit value to a counter and return the result.
381  *
382  * Atomically adds the 32-bits value (inc) to the atomic counter (v) and
383  * returns the value of v after addition.
384  *
385  * @param v
386  *   A pointer to the atomic counter.
387  * @param inc
388  *   The value to be added to the counter.
389  * @return
390  *   The value of v after the addition.
391  */
392 static inline int32_t
393 rte_atomic32_add_return(rte_atomic32_t *v, int32_t inc);
394
395 /**
396  * Atomically subtract a 32-bit value from a counter and return
397  * the result.
398  *
399  * Atomically subtracts the 32-bit value (inc) from the atomic counter
400  * (v) and returns the value of v after the subtraction.
401  *
402  * @param v
403  *   A pointer to the atomic counter.
404  * @param dec
405  *   The value to be subtracted from the counter.
406  * @return
407  *   The value of v after the subtraction.
408  */
409 static inline int32_t
410 rte_atomic32_sub_return(rte_atomic32_t *v, int32_t dec);
411
412 /**
413  * Atomically increment a 32-bit counter by one and test.
414  *
415  * Atomically increments the atomic counter (v) by one and returns true if
416  * the result is 0, or false in all other cases.
417  *
418  * @param v
419  *   A pointer to the atomic counter.
420  * @return
421  *   True if the result after the increment operation is 0; false otherwise.
422  */
423 static inline int
424 rte_atomic32_inc_and_test(rte_atomic32_t *v);
425
426 /**
427  * Atomically decrement a 32-bit counter by one and test.
428  *
429  * Atomically decrements the atomic counter (v) by one and returns true if
430  * the result is 0, or false in all other cases.
431  *
432  * @param v
433  *   A pointer to the atomic counter.
434  * @return
435  *   True if the result after the decrement operation is 0; false otherwise.
436  */
437 static inline int
438 rte_atomic32_dec_and_test(rte_atomic32_t *v);
439
440 /**
441  * Atomically test and set a 32-bit atomic counter.
442  *
443  * If the counter value is already set, return 0 (failed). Otherwise, set
444  * the counter value to 1 and return 1 (success).
445  *
446  * @param v
447  *   A pointer to the atomic counter.
448  * @return
449  *   0 if failed; else 1, success.
450  */
451 static inline int
452 rte_atomic32_test_and_set(rte_atomic32_t *v);
453
454 /**
455  * Atomically set a 32-bit counter to 0.
456  *
457  * @param v
458  *   A pointer to the atomic counter.
459  */
460 static inline void
461 rte_atomic32_clear(rte_atomic32_t *v);
462
463 /*------------------------- 64 bit atomic operations -------------------------*/
464
465 /**
466  * An atomic compare and set function used by the mutex functions.
467  * (atomic) equivalent to:
468  *   if (*dst == exp)
469  *     *dst = src (all 64-bit words)
470  *
471  * @param dst
472  *   The destination into which the value will be written.
473  * @param exp
474  *   The expected value.
475  * @param src
476  *   The new value.
477  * @return
478  *   Non-zero on success; 0 on failure.
479  */
480 static inline int
481 rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src);
482
483 /**
484  * The atomic counter structure.
485  */
486 typedef struct {
487         volatile int64_t cnt;  /**< Internal counter value. */
488 } rte_atomic64_t;
489
490 /**
491  * Static initializer for an atomic counter.
492  */
493 #define RTE_ATOMIC64_INIT(val) { (val) }
494
495 /**
496  * Initialize the atomic counter.
497  *
498  * @param v
499  *   A pointer to the atomic counter.
500  */
501 static inline void
502 rte_atomic64_init(rte_atomic64_t *v);
503
504 /**
505  * Atomically read a 64-bit counter.
506  *
507  * @param v
508  *   A pointer to the atomic counter.
509  * @return
510  *   The value of the counter.
511  */
512 static inline int64_t
513 rte_atomic64_read(rte_atomic64_t *v);
514
515 /**
516  * Atomically set a 64-bit counter.
517  *
518  * @param v
519  *   A pointer to the atomic counter.
520  * @param new_value
521  *   The new value of the counter.
522  */
523 static inline void
524 rte_atomic64_set(rte_atomic64_t *v, int64_t new_value);
525
526 /**
527  * Atomically add a 64-bit value to a counter.
528  *
529  * @param v
530  *   A pointer to the atomic counter.
531  * @param inc
532  *   The value to be added to the counter.
533  */
534 static inline void
535 rte_atomic64_add(rte_atomic64_t *v, int64_t inc);
536
537 /**
538  * Atomically subtract a 64-bit value from a counter.
539  *
540  * @param v
541  *   A pointer to the atomic counter.
542  * @param dec
543  *   The value to be subtracted from the counter.
544  */
545 static inline void
546 rte_atomic64_sub(rte_atomic64_t *v, int64_t dec);
547
548 /**
549  * Atomically increment a 64-bit counter by one and test.
550  *
551  * @param v
552  *   A pointer to the atomic counter.
553  */
554 static inline void
555 rte_atomic64_inc(rte_atomic64_t *v);
556
557 /**
558  * Atomically decrement a 64-bit counter by one and test.
559  *
560  * @param v
561  *   A pointer to the atomic counter.
562  */
563 static inline void
564 rte_atomic64_dec(rte_atomic64_t *v);
565
566 /**
567  * Add a 64-bit value to an atomic counter and return the result.
568  *
569  * Atomically adds the 64-bit value (inc) to the atomic counter (v) and
570  * returns the value of v after the addition.
571  *
572  * @param v
573  *   A pointer to the atomic counter.
574  * @param inc
575  *   The value to be added to the counter.
576  * @return
577  *   The value of v after the addition.
578  */
579 static inline int64_t
580 rte_atomic64_add_return(rte_atomic64_t *v, int64_t inc);
581
582 /**
583  * Subtract a 64-bit value from an atomic counter and return the result.
584  *
585  * Atomically subtracts the 64-bit value (dec) from the atomic counter (v)
586  * and returns the value of v after the subtraction.
587  *
588  * @param v
589  *   A pointer to the atomic counter.
590  * @param dec
591  *   The value to be subtracted from the counter.
592  * @return
593  *   The value of v after the subtraction.
594  */
595 static inline int64_t
596 rte_atomic64_sub_return(rte_atomic64_t *v, int64_t dec);
597
598 /**
599  * Atomically increment a 64-bit counter by one and test.
600  *
601  * Atomically increments the atomic counter (v) by one and returns
602  * true if the result is 0, or false in all other cases.
603  *
604  * @param v
605  *   A pointer to the atomic counter.
606  * @return
607  *   True if the result after the addition is 0; false otherwise.
608  */
609 static inline int
610 rte_atomic64_inc_and_test(rte_atomic64_t *v);
611
612 /**
613  * Atomically decrement a 64-bit counter by one and test.
614  *
615  * Atomically decrements the atomic counter (v) by one and returns true if
616  * the result is 0, or false in all other cases.
617  *
618  * @param v
619  *   A pointer to the atomic counter.
620  * @return
621  *   True if the result after subtraction is 0; false otherwise.
622  */
623 static inline int
624 rte_atomic64_dec_and_test(rte_atomic64_t *v);
625
626 /**
627  * Atomically test and set a 64-bit atomic counter.
628  *
629  * If the counter value is already set, return 0 (failed). Otherwise, set
630  * the counter value to 1 and return 1 (success).
631  *
632  * @param v
633  *   A pointer to the atomic counter.
634  * @return
635  *   0 if failed; else 1, success.
636  */
637 static inline int
638 rte_atomic64_test_and_set(rte_atomic64_t *v);
639
640 /**
641  * Atomically set a 64-bit counter to 0.
642  *
643  * @param v
644  *   A pointer to the atomic counter.
645  */
646 static inline void
647 rte_atomic64_clear(rte_atomic64_t *v);
648
649 #endif /* __DOXYGEN__ */
650
651
652 #ifdef __cplusplus
653 }
654 #endif
655
656 #endif /* _RTE_ATOMIC_H_ */