at v5.0-rc3 38 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Atomic operations usable in machine independent code */ 3#ifndef _LINUX_ATOMIC_H 4#define _LINUX_ATOMIC_H 5#include <linux/types.h> 6 7#include <asm/atomic.h> 8#include <asm/barrier.h> 9 10/* 11 * Relaxed variants of xchg, cmpxchg and some atomic operations. 12 * 13 * We support four variants: 14 * 15 * - Fully ordered: The default implementation, no suffix required. 16 * - Acquire: Provides ACQUIRE semantics, _acquire suffix. 17 * - Release: Provides RELEASE semantics, _release suffix. 18 * - Relaxed: No ordering guarantees, _relaxed suffix. 19 * 20 * For compound atomics performing both a load and a store, ACQUIRE 21 * semantics apply only to the load and RELEASE semantics only to the 22 * store portion of the operation. Note that a failed cmpxchg_acquire 23 * does -not- imply any memory ordering constraints. 24 * 25 * See Documentation/memory-barriers.txt for ACQUIRE/RELEASE definitions. 26 */ 27 28#ifndef atomic_read_acquire 29#define atomic_read_acquire(v) smp_load_acquire(&(v)->counter) 30#endif 31 32#ifndef atomic_set_release 33#define atomic_set_release(v, i) smp_store_release(&(v)->counter, (i)) 34#endif 35 36/* 37 * The idea here is to build acquire/release variants by adding explicit 38 * barriers on top of the relaxed variant. In the case where the relaxed 39 * variant is already fully ordered, no additional barriers are needed. 40 * 41 * If an architecture overrides __atomic_acquire_fence() it will probably 42 * want to define smp_mb__after_spinlock(). 43 */ 44#ifndef __atomic_acquire_fence 45#define __atomic_acquire_fence smp_mb__after_atomic 46#endif 47 48#ifndef __atomic_release_fence 49#define __atomic_release_fence smp_mb__before_atomic 50#endif 51 52#ifndef __atomic_pre_full_fence 53#define __atomic_pre_full_fence smp_mb__before_atomic 54#endif 55 56#ifndef __atomic_post_full_fence 57#define __atomic_post_full_fence smp_mb__after_atomic 58#endif 59 60#define __atomic_op_acquire(op, args...) \ 61({ \ 62 typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ 63 __atomic_acquire_fence(); \ 64 __ret; \ 65}) 66 67#define __atomic_op_release(op, args...) \ 68({ \ 69 __atomic_release_fence(); \ 70 op##_relaxed(args); \ 71}) 72 73#define __atomic_op_fence(op, args...) \ 74({ \ 75 typeof(op##_relaxed(args)) __ret; \ 76 __atomic_pre_full_fence(); \ 77 __ret = op##_relaxed(args); \ 78 __atomic_post_full_fence(); \ 79 __ret; \ 80}) 81 82/* atomic_add_return_relaxed */ 83#ifndef atomic_add_return_relaxed 84#define atomic_add_return_relaxed atomic_add_return 85#define atomic_add_return_acquire atomic_add_return 86#define atomic_add_return_release atomic_add_return 87 88#else /* atomic_add_return_relaxed */ 89 90#ifndef atomic_add_return_acquire 91#define atomic_add_return_acquire(...) \ 92 __atomic_op_acquire(atomic_add_return, __VA_ARGS__) 93#endif 94 95#ifndef atomic_add_return_release 96#define atomic_add_return_release(...) \ 97 __atomic_op_release(atomic_add_return, __VA_ARGS__) 98#endif 99 100#ifndef atomic_add_return 101#define atomic_add_return(...) \ 102 __atomic_op_fence(atomic_add_return, __VA_ARGS__) 103#endif 104#endif /* atomic_add_return_relaxed */ 105 106#ifndef atomic_inc 107#define atomic_inc(v) atomic_add(1, (v)) 108#endif 109 110/* atomic_inc_return_relaxed */ 111#ifndef atomic_inc_return_relaxed 112 113#ifndef atomic_inc_return 114#define atomic_inc_return(v) atomic_add_return(1, (v)) 115#define atomic_inc_return_relaxed(v) atomic_add_return_relaxed(1, (v)) 116#define atomic_inc_return_acquire(v) atomic_add_return_acquire(1, (v)) 117#define atomic_inc_return_release(v) atomic_add_return_release(1, (v)) 118#else /* atomic_inc_return */ 119#define atomic_inc_return_relaxed atomic_inc_return 120#define atomic_inc_return_acquire atomic_inc_return 121#define atomic_inc_return_release atomic_inc_return 122#endif /* atomic_inc_return */ 123 124#else /* atomic_inc_return_relaxed */ 125 126#ifndef atomic_inc_return_acquire 127#define atomic_inc_return_acquire(...) \ 128 __atomic_op_acquire(atomic_inc_return, __VA_ARGS__) 129#endif 130 131#ifndef atomic_inc_return_release 132#define atomic_inc_return_release(...) \ 133 __atomic_op_release(atomic_inc_return, __VA_ARGS__) 134#endif 135 136#ifndef atomic_inc_return 137#define atomic_inc_return(...) \ 138 __atomic_op_fence(atomic_inc_return, __VA_ARGS__) 139#endif 140#endif /* atomic_inc_return_relaxed */ 141 142/* atomic_sub_return_relaxed */ 143#ifndef atomic_sub_return_relaxed 144#define atomic_sub_return_relaxed atomic_sub_return 145#define atomic_sub_return_acquire atomic_sub_return 146#define atomic_sub_return_release atomic_sub_return 147 148#else /* atomic_sub_return_relaxed */ 149 150#ifndef atomic_sub_return_acquire 151#define atomic_sub_return_acquire(...) \ 152 __atomic_op_acquire(atomic_sub_return, __VA_ARGS__) 153#endif 154 155#ifndef atomic_sub_return_release 156#define atomic_sub_return_release(...) \ 157 __atomic_op_release(atomic_sub_return, __VA_ARGS__) 158#endif 159 160#ifndef atomic_sub_return 161#define atomic_sub_return(...) \ 162 __atomic_op_fence(atomic_sub_return, __VA_ARGS__) 163#endif 164#endif /* atomic_sub_return_relaxed */ 165 166#ifndef atomic_dec 167#define atomic_dec(v) atomic_sub(1, (v)) 168#endif 169 170/* atomic_dec_return_relaxed */ 171#ifndef atomic_dec_return_relaxed 172 173#ifndef atomic_dec_return 174#define atomic_dec_return(v) atomic_sub_return(1, (v)) 175#define atomic_dec_return_relaxed(v) atomic_sub_return_relaxed(1, (v)) 176#define atomic_dec_return_acquire(v) atomic_sub_return_acquire(1, (v)) 177#define atomic_dec_return_release(v) atomic_sub_return_release(1, (v)) 178#else /* atomic_dec_return */ 179#define atomic_dec_return_relaxed atomic_dec_return 180#define atomic_dec_return_acquire atomic_dec_return 181#define atomic_dec_return_release atomic_dec_return 182#endif /* atomic_dec_return */ 183 184#else /* atomic_dec_return_relaxed */ 185 186#ifndef atomic_dec_return_acquire 187#define atomic_dec_return_acquire(...) \ 188 __atomic_op_acquire(atomic_dec_return, __VA_ARGS__) 189#endif 190 191#ifndef atomic_dec_return_release 192#define atomic_dec_return_release(...) \ 193 __atomic_op_release(atomic_dec_return, __VA_ARGS__) 194#endif 195 196#ifndef atomic_dec_return 197#define atomic_dec_return(...) \ 198 __atomic_op_fence(atomic_dec_return, __VA_ARGS__) 199#endif 200#endif /* atomic_dec_return_relaxed */ 201 202 203/* atomic_fetch_add_relaxed */ 204#ifndef atomic_fetch_add_relaxed 205#define atomic_fetch_add_relaxed atomic_fetch_add 206#define atomic_fetch_add_acquire atomic_fetch_add 207#define atomic_fetch_add_release atomic_fetch_add 208 209#else /* atomic_fetch_add_relaxed */ 210 211#ifndef atomic_fetch_add_acquire 212#define atomic_fetch_add_acquire(...) \ 213 __atomic_op_acquire(atomic_fetch_add, __VA_ARGS__) 214#endif 215 216#ifndef atomic_fetch_add_release 217#define atomic_fetch_add_release(...) \ 218 __atomic_op_release(atomic_fetch_add, __VA_ARGS__) 219#endif 220 221#ifndef atomic_fetch_add 222#define atomic_fetch_add(...) \ 223 __atomic_op_fence(atomic_fetch_add, __VA_ARGS__) 224#endif 225#endif /* atomic_fetch_add_relaxed */ 226 227/* atomic_fetch_inc_relaxed */ 228#ifndef atomic_fetch_inc_relaxed 229 230#ifndef atomic_fetch_inc 231#define atomic_fetch_inc(v) atomic_fetch_add(1, (v)) 232#define atomic_fetch_inc_relaxed(v) atomic_fetch_add_relaxed(1, (v)) 233#define atomic_fetch_inc_acquire(v) atomic_fetch_add_acquire(1, (v)) 234#define atomic_fetch_inc_release(v) atomic_fetch_add_release(1, (v)) 235#else /* atomic_fetch_inc */ 236#define atomic_fetch_inc_relaxed atomic_fetch_inc 237#define atomic_fetch_inc_acquire atomic_fetch_inc 238#define atomic_fetch_inc_release atomic_fetch_inc 239#endif /* atomic_fetch_inc */ 240 241#else /* atomic_fetch_inc_relaxed */ 242 243#ifndef atomic_fetch_inc_acquire 244#define atomic_fetch_inc_acquire(...) \ 245 __atomic_op_acquire(atomic_fetch_inc, __VA_ARGS__) 246#endif 247 248#ifndef atomic_fetch_inc_release 249#define atomic_fetch_inc_release(...) \ 250 __atomic_op_release(atomic_fetch_inc, __VA_ARGS__) 251#endif 252 253#ifndef atomic_fetch_inc 254#define atomic_fetch_inc(...) \ 255 __atomic_op_fence(atomic_fetch_inc, __VA_ARGS__) 256#endif 257#endif /* atomic_fetch_inc_relaxed */ 258 259/* atomic_fetch_sub_relaxed */ 260#ifndef atomic_fetch_sub_relaxed 261#define atomic_fetch_sub_relaxed atomic_fetch_sub 262#define atomic_fetch_sub_acquire atomic_fetch_sub 263#define atomic_fetch_sub_release atomic_fetch_sub 264 265#else /* atomic_fetch_sub_relaxed */ 266 267#ifndef atomic_fetch_sub_acquire 268#define atomic_fetch_sub_acquire(...) \ 269 __atomic_op_acquire(atomic_fetch_sub, __VA_ARGS__) 270#endif 271 272#ifndef atomic_fetch_sub_release 273#define atomic_fetch_sub_release(...) \ 274 __atomic_op_release(atomic_fetch_sub, __VA_ARGS__) 275#endif 276 277#ifndef atomic_fetch_sub 278#define atomic_fetch_sub(...) \ 279 __atomic_op_fence(atomic_fetch_sub, __VA_ARGS__) 280#endif 281#endif /* atomic_fetch_sub_relaxed */ 282 283/* atomic_fetch_dec_relaxed */ 284#ifndef atomic_fetch_dec_relaxed 285 286#ifndef atomic_fetch_dec 287#define atomic_fetch_dec(v) atomic_fetch_sub(1, (v)) 288#define atomic_fetch_dec_relaxed(v) atomic_fetch_sub_relaxed(1, (v)) 289#define atomic_fetch_dec_acquire(v) atomic_fetch_sub_acquire(1, (v)) 290#define atomic_fetch_dec_release(v) atomic_fetch_sub_release(1, (v)) 291#else /* atomic_fetch_dec */ 292#define atomic_fetch_dec_relaxed atomic_fetch_dec 293#define atomic_fetch_dec_acquire atomic_fetch_dec 294#define atomic_fetch_dec_release atomic_fetch_dec 295#endif /* atomic_fetch_dec */ 296 297#else /* atomic_fetch_dec_relaxed */ 298 299#ifndef atomic_fetch_dec_acquire 300#define atomic_fetch_dec_acquire(...) \ 301 __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__) 302#endif 303 304#ifndef atomic_fetch_dec_release 305#define atomic_fetch_dec_release(...) \ 306 __atomic_op_release(atomic_fetch_dec, __VA_ARGS__) 307#endif 308 309#ifndef atomic_fetch_dec 310#define atomic_fetch_dec(...) \ 311 __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__) 312#endif 313#endif /* atomic_fetch_dec_relaxed */ 314 315/* atomic_fetch_or_relaxed */ 316#ifndef atomic_fetch_or_relaxed 317#define atomic_fetch_or_relaxed atomic_fetch_or 318#define atomic_fetch_or_acquire atomic_fetch_or 319#define atomic_fetch_or_release atomic_fetch_or 320 321#else /* atomic_fetch_or_relaxed */ 322 323#ifndef atomic_fetch_or_acquire 324#define atomic_fetch_or_acquire(...) \ 325 __atomic_op_acquire(atomic_fetch_or, __VA_ARGS__) 326#endif 327 328#ifndef atomic_fetch_or_release 329#define atomic_fetch_or_release(...) \ 330 __atomic_op_release(atomic_fetch_or, __VA_ARGS__) 331#endif 332 333#ifndef atomic_fetch_or 334#define atomic_fetch_or(...) \ 335 __atomic_op_fence(atomic_fetch_or, __VA_ARGS__) 336#endif 337#endif /* atomic_fetch_or_relaxed */ 338 339/* atomic_fetch_and_relaxed */ 340#ifndef atomic_fetch_and_relaxed 341#define atomic_fetch_and_relaxed atomic_fetch_and 342#define atomic_fetch_and_acquire atomic_fetch_and 343#define atomic_fetch_and_release atomic_fetch_and 344 345#else /* atomic_fetch_and_relaxed */ 346 347#ifndef atomic_fetch_and_acquire 348#define atomic_fetch_and_acquire(...) \ 349 __atomic_op_acquire(atomic_fetch_and, __VA_ARGS__) 350#endif 351 352#ifndef atomic_fetch_and_release 353#define atomic_fetch_and_release(...) \ 354 __atomic_op_release(atomic_fetch_and, __VA_ARGS__) 355#endif 356 357#ifndef atomic_fetch_and 358#define atomic_fetch_and(...) \ 359 __atomic_op_fence(atomic_fetch_and, __VA_ARGS__) 360#endif 361#endif /* atomic_fetch_and_relaxed */ 362 363#ifndef atomic_andnot 364#define atomic_andnot(i, v) atomic_and(~(int)(i), (v)) 365#endif 366 367#ifndef atomic_fetch_andnot_relaxed 368 369#ifndef atomic_fetch_andnot 370#define atomic_fetch_andnot(i, v) atomic_fetch_and(~(int)(i), (v)) 371#define atomic_fetch_andnot_relaxed(i, v) atomic_fetch_and_relaxed(~(int)(i), (v)) 372#define atomic_fetch_andnot_acquire(i, v) atomic_fetch_and_acquire(~(int)(i), (v)) 373#define atomic_fetch_andnot_release(i, v) atomic_fetch_and_release(~(int)(i), (v)) 374#else /* atomic_fetch_andnot */ 375#define atomic_fetch_andnot_relaxed atomic_fetch_andnot 376#define atomic_fetch_andnot_acquire atomic_fetch_andnot 377#define atomic_fetch_andnot_release atomic_fetch_andnot 378#endif /* atomic_fetch_andnot */ 379 380#else /* atomic_fetch_andnot_relaxed */ 381 382#ifndef atomic_fetch_andnot_acquire 383#define atomic_fetch_andnot_acquire(...) \ 384 __atomic_op_acquire(atomic_fetch_andnot, __VA_ARGS__) 385#endif 386 387#ifndef atomic_fetch_andnot_release 388#define atomic_fetch_andnot_release(...) \ 389 __atomic_op_release(atomic_fetch_andnot, __VA_ARGS__) 390#endif 391 392#ifndef atomic_fetch_andnot 393#define atomic_fetch_andnot(...) \ 394 __atomic_op_fence(atomic_fetch_andnot, __VA_ARGS__) 395#endif 396#endif /* atomic_fetch_andnot_relaxed */ 397 398/* atomic_fetch_xor_relaxed */ 399#ifndef atomic_fetch_xor_relaxed 400#define atomic_fetch_xor_relaxed atomic_fetch_xor 401#define atomic_fetch_xor_acquire atomic_fetch_xor 402#define atomic_fetch_xor_release atomic_fetch_xor 403 404#else /* atomic_fetch_xor_relaxed */ 405 406#ifndef atomic_fetch_xor_acquire 407#define atomic_fetch_xor_acquire(...) \ 408 __atomic_op_acquire(atomic_fetch_xor, __VA_ARGS__) 409#endif 410 411#ifndef atomic_fetch_xor_release 412#define atomic_fetch_xor_release(...) \ 413 __atomic_op_release(atomic_fetch_xor, __VA_ARGS__) 414#endif 415 416#ifndef atomic_fetch_xor 417#define atomic_fetch_xor(...) \ 418 __atomic_op_fence(atomic_fetch_xor, __VA_ARGS__) 419#endif 420#endif /* atomic_fetch_xor_relaxed */ 421 422 423/* atomic_xchg_relaxed */ 424#ifndef atomic_xchg_relaxed 425#define atomic_xchg_relaxed atomic_xchg 426#define atomic_xchg_acquire atomic_xchg 427#define atomic_xchg_release atomic_xchg 428 429#else /* atomic_xchg_relaxed */ 430 431#ifndef atomic_xchg_acquire 432#define atomic_xchg_acquire(...) \ 433 __atomic_op_acquire(atomic_xchg, __VA_ARGS__) 434#endif 435 436#ifndef atomic_xchg_release 437#define atomic_xchg_release(...) \ 438 __atomic_op_release(atomic_xchg, __VA_ARGS__) 439#endif 440 441#ifndef atomic_xchg 442#define atomic_xchg(...) \ 443 __atomic_op_fence(atomic_xchg, __VA_ARGS__) 444#endif 445#endif /* atomic_xchg_relaxed */ 446 447/* atomic_cmpxchg_relaxed */ 448#ifndef atomic_cmpxchg_relaxed 449#define atomic_cmpxchg_relaxed atomic_cmpxchg 450#define atomic_cmpxchg_acquire atomic_cmpxchg 451#define atomic_cmpxchg_release atomic_cmpxchg 452 453#else /* atomic_cmpxchg_relaxed */ 454 455#ifndef atomic_cmpxchg_acquire 456#define atomic_cmpxchg_acquire(...) \ 457 __atomic_op_acquire(atomic_cmpxchg, __VA_ARGS__) 458#endif 459 460#ifndef atomic_cmpxchg_release 461#define atomic_cmpxchg_release(...) \ 462 __atomic_op_release(atomic_cmpxchg, __VA_ARGS__) 463#endif 464 465#ifndef atomic_cmpxchg 466#define atomic_cmpxchg(...) \ 467 __atomic_op_fence(atomic_cmpxchg, __VA_ARGS__) 468#endif 469#endif /* atomic_cmpxchg_relaxed */ 470 471#ifndef atomic_try_cmpxchg 472 473#define __atomic_try_cmpxchg(type, _p, _po, _n) \ 474({ \ 475 typeof(_po) __po = (_po); \ 476 typeof(*(_po)) __r, __o = *__po; \ 477 __r = atomic_cmpxchg##type((_p), __o, (_n)); \ 478 if (unlikely(__r != __o)) \ 479 *__po = __r; \ 480 likely(__r == __o); \ 481}) 482 483#define atomic_try_cmpxchg(_p, _po, _n) __atomic_try_cmpxchg(, _p, _po, _n) 484#define atomic_try_cmpxchg_relaxed(_p, _po, _n) __atomic_try_cmpxchg(_relaxed, _p, _po, _n) 485#define atomic_try_cmpxchg_acquire(_p, _po, _n) __atomic_try_cmpxchg(_acquire, _p, _po, _n) 486#define atomic_try_cmpxchg_release(_p, _po, _n) __atomic_try_cmpxchg(_release, _p, _po, _n) 487 488#else /* atomic_try_cmpxchg */ 489#define atomic_try_cmpxchg_relaxed atomic_try_cmpxchg 490#define atomic_try_cmpxchg_acquire atomic_try_cmpxchg 491#define atomic_try_cmpxchg_release atomic_try_cmpxchg 492#endif /* atomic_try_cmpxchg */ 493 494/* cmpxchg_relaxed */ 495#ifndef cmpxchg_relaxed 496#define cmpxchg_relaxed cmpxchg 497#define cmpxchg_acquire cmpxchg 498#define cmpxchg_release cmpxchg 499 500#else /* cmpxchg_relaxed */ 501 502#ifndef cmpxchg_acquire 503#define cmpxchg_acquire(...) \ 504 __atomic_op_acquire(cmpxchg, __VA_ARGS__) 505#endif 506 507#ifndef cmpxchg_release 508#define cmpxchg_release(...) \ 509 __atomic_op_release(cmpxchg, __VA_ARGS__) 510#endif 511 512#ifndef cmpxchg 513#define cmpxchg(...) \ 514 __atomic_op_fence(cmpxchg, __VA_ARGS__) 515#endif 516#endif /* cmpxchg_relaxed */ 517 518/* cmpxchg64_relaxed */ 519#ifndef cmpxchg64_relaxed 520#define cmpxchg64_relaxed cmpxchg64 521#define cmpxchg64_acquire cmpxchg64 522#define cmpxchg64_release cmpxchg64 523 524#else /* cmpxchg64_relaxed */ 525 526#ifndef cmpxchg64_acquire 527#define cmpxchg64_acquire(...) \ 528 __atomic_op_acquire(cmpxchg64, __VA_ARGS__) 529#endif 530 531#ifndef cmpxchg64_release 532#define cmpxchg64_release(...) \ 533 __atomic_op_release(cmpxchg64, __VA_ARGS__) 534#endif 535 536#ifndef cmpxchg64 537#define cmpxchg64(...) \ 538 __atomic_op_fence(cmpxchg64, __VA_ARGS__) 539#endif 540#endif /* cmpxchg64_relaxed */ 541 542/* xchg_relaxed */ 543#ifndef xchg_relaxed 544#define xchg_relaxed xchg 545#define xchg_acquire xchg 546#define xchg_release xchg 547 548#else /* xchg_relaxed */ 549 550#ifndef xchg_acquire 551#define xchg_acquire(...) __atomic_op_acquire(xchg, __VA_ARGS__) 552#endif 553 554#ifndef xchg_release 555#define xchg_release(...) __atomic_op_release(xchg, __VA_ARGS__) 556#endif 557 558#ifndef xchg 559#define xchg(...) __atomic_op_fence(xchg, __VA_ARGS__) 560#endif 561#endif /* xchg_relaxed */ 562 563/** 564 * atomic_fetch_add_unless - add unless the number is already a given value 565 * @v: pointer of type atomic_t 566 * @a: the amount to add to v... 567 * @u: ...unless v is equal to u. 568 * 569 * Atomically adds @a to @v, if @v was not already @u. 570 * Returns the original value of @v. 571 */ 572#ifndef atomic_fetch_add_unless 573static inline int atomic_fetch_add_unless(atomic_t *v, int a, int u) 574{ 575 int c = atomic_read(v); 576 577 do { 578 if (unlikely(c == u)) 579 break; 580 } while (!atomic_try_cmpxchg(v, &c, c + a)); 581 582 return c; 583} 584#endif 585 586/** 587 * atomic_add_unless - add unless the number is already a given value 588 * @v: pointer of type atomic_t 589 * @a: the amount to add to v... 590 * @u: ...unless v is equal to u. 591 * 592 * Atomically adds @a to @v, if @v was not already @u. 593 * Returns true if the addition was done. 594 */ 595static inline bool atomic_add_unless(atomic_t *v, int a, int u) 596{ 597 return atomic_fetch_add_unless(v, a, u) != u; 598} 599 600/** 601 * atomic_inc_not_zero - increment unless the number is zero 602 * @v: pointer of type atomic_t 603 * 604 * Atomically increments @v by 1, if @v is non-zero. 605 * Returns true if the increment was done. 606 */ 607#ifndef atomic_inc_not_zero 608#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 609#endif 610 611/** 612 * atomic_inc_and_test - increment and test 613 * @v: pointer of type atomic_t 614 * 615 * Atomically increments @v by 1 616 * and returns true if the result is zero, or false for all 617 * other cases. 618 */ 619#ifndef atomic_inc_and_test 620static inline bool atomic_inc_and_test(atomic_t *v) 621{ 622 return atomic_inc_return(v) == 0; 623} 624#endif 625 626/** 627 * atomic_dec_and_test - decrement and test 628 * @v: pointer of type atomic_t 629 * 630 * Atomically decrements @v by 1 and 631 * returns true if the result is 0, or false for all other 632 * cases. 633 */ 634#ifndef atomic_dec_and_test 635static inline bool atomic_dec_and_test(atomic_t *v) 636{ 637 return atomic_dec_return(v) == 0; 638} 639#endif 640 641/** 642 * atomic_sub_and_test - subtract value from variable and test result 643 * @i: integer value to subtract 644 * @v: pointer of type atomic_t 645 * 646 * Atomically subtracts @i from @v and returns 647 * true if the result is zero, or false for all 648 * other cases. 649 */ 650#ifndef atomic_sub_and_test 651static inline bool atomic_sub_and_test(int i, atomic_t *v) 652{ 653 return atomic_sub_return(i, v) == 0; 654} 655#endif 656 657/** 658 * atomic_add_negative - add and test if negative 659 * @i: integer value to add 660 * @v: pointer of type atomic_t 661 * 662 * Atomically adds @i to @v and returns true 663 * if the result is negative, or false when 664 * result is greater than or equal to zero. 665 */ 666#ifndef atomic_add_negative 667static inline bool atomic_add_negative(int i, atomic_t *v) 668{ 669 return atomic_add_return(i, v) < 0; 670} 671#endif 672 673#ifndef atomic_inc_unless_negative 674static inline bool atomic_inc_unless_negative(atomic_t *v) 675{ 676 int c = atomic_read(v); 677 678 do { 679 if (unlikely(c < 0)) 680 return false; 681 } while (!atomic_try_cmpxchg(v, &c, c + 1)); 682 683 return true; 684} 685#endif 686 687#ifndef atomic_dec_unless_positive 688static inline bool atomic_dec_unless_positive(atomic_t *v) 689{ 690 int c = atomic_read(v); 691 692 do { 693 if (unlikely(c > 0)) 694 return false; 695 } while (!atomic_try_cmpxchg(v, &c, c - 1)); 696 697 return true; 698} 699#endif 700 701/* 702 * atomic_dec_if_positive - decrement by 1 if old value positive 703 * @v: pointer of type atomic_t 704 * 705 * The function returns the old value of *v minus 1, even if 706 * the atomic variable, v, was not decremented. 707 */ 708#ifndef atomic_dec_if_positive 709static inline int atomic_dec_if_positive(atomic_t *v) 710{ 711 int dec, c = atomic_read(v); 712 713 do { 714 dec = c - 1; 715 if (unlikely(dec < 0)) 716 break; 717 } while (!atomic_try_cmpxchg(v, &c, dec)); 718 719 return dec; 720} 721#endif 722 723#define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c)) 724#define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c)) 725 726#ifdef CONFIG_GENERIC_ATOMIC64 727#include <asm-generic/atomic64.h> 728#endif 729 730#ifndef atomic64_read_acquire 731#define atomic64_read_acquire(v) smp_load_acquire(&(v)->counter) 732#endif 733 734#ifndef atomic64_set_release 735#define atomic64_set_release(v, i) smp_store_release(&(v)->counter, (i)) 736#endif 737 738/* atomic64_add_return_relaxed */ 739#ifndef atomic64_add_return_relaxed 740#define atomic64_add_return_relaxed atomic64_add_return 741#define atomic64_add_return_acquire atomic64_add_return 742#define atomic64_add_return_release atomic64_add_return 743 744#else /* atomic64_add_return_relaxed */ 745 746#ifndef atomic64_add_return_acquire 747#define atomic64_add_return_acquire(...) \ 748 __atomic_op_acquire(atomic64_add_return, __VA_ARGS__) 749#endif 750 751#ifndef atomic64_add_return_release 752#define atomic64_add_return_release(...) \ 753 __atomic_op_release(atomic64_add_return, __VA_ARGS__) 754#endif 755 756#ifndef atomic64_add_return 757#define atomic64_add_return(...) \ 758 __atomic_op_fence(atomic64_add_return, __VA_ARGS__) 759#endif 760#endif /* atomic64_add_return_relaxed */ 761 762#ifndef atomic64_inc 763#define atomic64_inc(v) atomic64_add(1, (v)) 764#endif 765 766/* atomic64_inc_return_relaxed */ 767#ifndef atomic64_inc_return_relaxed 768 769#ifndef atomic64_inc_return 770#define atomic64_inc_return(v) atomic64_add_return(1, (v)) 771#define atomic64_inc_return_relaxed(v) atomic64_add_return_relaxed(1, (v)) 772#define atomic64_inc_return_acquire(v) atomic64_add_return_acquire(1, (v)) 773#define atomic64_inc_return_release(v) atomic64_add_return_release(1, (v)) 774#else /* atomic64_inc_return */ 775#define atomic64_inc_return_relaxed atomic64_inc_return 776#define atomic64_inc_return_acquire atomic64_inc_return 777#define atomic64_inc_return_release atomic64_inc_return 778#endif /* atomic64_inc_return */ 779 780#else /* atomic64_inc_return_relaxed */ 781 782#ifndef atomic64_inc_return_acquire 783#define atomic64_inc_return_acquire(...) \ 784 __atomic_op_acquire(atomic64_inc_return, __VA_ARGS__) 785#endif 786 787#ifndef atomic64_inc_return_release 788#define atomic64_inc_return_release(...) \ 789 __atomic_op_release(atomic64_inc_return, __VA_ARGS__) 790#endif 791 792#ifndef atomic64_inc_return 793#define atomic64_inc_return(...) \ 794 __atomic_op_fence(atomic64_inc_return, __VA_ARGS__) 795#endif 796#endif /* atomic64_inc_return_relaxed */ 797 798 799/* atomic64_sub_return_relaxed */ 800#ifndef atomic64_sub_return_relaxed 801#define atomic64_sub_return_relaxed atomic64_sub_return 802#define atomic64_sub_return_acquire atomic64_sub_return 803#define atomic64_sub_return_release atomic64_sub_return 804 805#else /* atomic64_sub_return_relaxed */ 806 807#ifndef atomic64_sub_return_acquire 808#define atomic64_sub_return_acquire(...) \ 809 __atomic_op_acquire(atomic64_sub_return, __VA_ARGS__) 810#endif 811 812#ifndef atomic64_sub_return_release 813#define atomic64_sub_return_release(...) \ 814 __atomic_op_release(atomic64_sub_return, __VA_ARGS__) 815#endif 816 817#ifndef atomic64_sub_return 818#define atomic64_sub_return(...) \ 819 __atomic_op_fence(atomic64_sub_return, __VA_ARGS__) 820#endif 821#endif /* atomic64_sub_return_relaxed */ 822 823#ifndef atomic64_dec 824#define atomic64_dec(v) atomic64_sub(1, (v)) 825#endif 826 827/* atomic64_dec_return_relaxed */ 828#ifndef atomic64_dec_return_relaxed 829 830#ifndef atomic64_dec_return 831#define atomic64_dec_return(v) atomic64_sub_return(1, (v)) 832#define atomic64_dec_return_relaxed(v) atomic64_sub_return_relaxed(1, (v)) 833#define atomic64_dec_return_acquire(v) atomic64_sub_return_acquire(1, (v)) 834#define atomic64_dec_return_release(v) atomic64_sub_return_release(1, (v)) 835#else /* atomic64_dec_return */ 836#define atomic64_dec_return_relaxed atomic64_dec_return 837#define atomic64_dec_return_acquire atomic64_dec_return 838#define atomic64_dec_return_release atomic64_dec_return 839#endif /* atomic64_dec_return */ 840 841#else /* atomic64_dec_return_relaxed */ 842 843#ifndef atomic64_dec_return_acquire 844#define atomic64_dec_return_acquire(...) \ 845 __atomic_op_acquire(atomic64_dec_return, __VA_ARGS__) 846#endif 847 848#ifndef atomic64_dec_return_release 849#define atomic64_dec_return_release(...) \ 850 __atomic_op_release(atomic64_dec_return, __VA_ARGS__) 851#endif 852 853#ifndef atomic64_dec_return 854#define atomic64_dec_return(...) \ 855 __atomic_op_fence(atomic64_dec_return, __VA_ARGS__) 856#endif 857#endif /* atomic64_dec_return_relaxed */ 858 859 860/* atomic64_fetch_add_relaxed */ 861#ifndef atomic64_fetch_add_relaxed 862#define atomic64_fetch_add_relaxed atomic64_fetch_add 863#define atomic64_fetch_add_acquire atomic64_fetch_add 864#define atomic64_fetch_add_release atomic64_fetch_add 865 866#else /* atomic64_fetch_add_relaxed */ 867 868#ifndef atomic64_fetch_add_acquire 869#define atomic64_fetch_add_acquire(...) \ 870 __atomic_op_acquire(atomic64_fetch_add, __VA_ARGS__) 871#endif 872 873#ifndef atomic64_fetch_add_release 874#define atomic64_fetch_add_release(...) \ 875 __atomic_op_release(atomic64_fetch_add, __VA_ARGS__) 876#endif 877 878#ifndef atomic64_fetch_add 879#define atomic64_fetch_add(...) \ 880 __atomic_op_fence(atomic64_fetch_add, __VA_ARGS__) 881#endif 882#endif /* atomic64_fetch_add_relaxed */ 883 884/* atomic64_fetch_inc_relaxed */ 885#ifndef atomic64_fetch_inc_relaxed 886 887#ifndef atomic64_fetch_inc 888#define atomic64_fetch_inc(v) atomic64_fetch_add(1, (v)) 889#define atomic64_fetch_inc_relaxed(v) atomic64_fetch_add_relaxed(1, (v)) 890#define atomic64_fetch_inc_acquire(v) atomic64_fetch_add_acquire(1, (v)) 891#define atomic64_fetch_inc_release(v) atomic64_fetch_add_release(1, (v)) 892#else /* atomic64_fetch_inc */ 893#define atomic64_fetch_inc_relaxed atomic64_fetch_inc 894#define atomic64_fetch_inc_acquire atomic64_fetch_inc 895#define atomic64_fetch_inc_release atomic64_fetch_inc 896#endif /* atomic64_fetch_inc */ 897 898#else /* atomic64_fetch_inc_relaxed */ 899 900#ifndef atomic64_fetch_inc_acquire 901#define atomic64_fetch_inc_acquire(...) \ 902 __atomic_op_acquire(atomic64_fetch_inc, __VA_ARGS__) 903#endif 904 905#ifndef atomic64_fetch_inc_release 906#define atomic64_fetch_inc_release(...) \ 907 __atomic_op_release(atomic64_fetch_inc, __VA_ARGS__) 908#endif 909 910#ifndef atomic64_fetch_inc 911#define atomic64_fetch_inc(...) \ 912 __atomic_op_fence(atomic64_fetch_inc, __VA_ARGS__) 913#endif 914#endif /* atomic64_fetch_inc_relaxed */ 915 916/* atomic64_fetch_sub_relaxed */ 917#ifndef atomic64_fetch_sub_relaxed 918#define atomic64_fetch_sub_relaxed atomic64_fetch_sub 919#define atomic64_fetch_sub_acquire atomic64_fetch_sub 920#define atomic64_fetch_sub_release atomic64_fetch_sub 921 922#else /* atomic64_fetch_sub_relaxed */ 923 924#ifndef atomic64_fetch_sub_acquire 925#define atomic64_fetch_sub_acquire(...) \ 926 __atomic_op_acquire(atomic64_fetch_sub, __VA_ARGS__) 927#endif 928 929#ifndef atomic64_fetch_sub_release 930#define atomic64_fetch_sub_release(...) \ 931 __atomic_op_release(atomic64_fetch_sub, __VA_ARGS__) 932#endif 933 934#ifndef atomic64_fetch_sub 935#define atomic64_fetch_sub(...) \ 936 __atomic_op_fence(atomic64_fetch_sub, __VA_ARGS__) 937#endif 938#endif /* atomic64_fetch_sub_relaxed */ 939 940/* atomic64_fetch_dec_relaxed */ 941#ifndef atomic64_fetch_dec_relaxed 942 943#ifndef atomic64_fetch_dec 944#define atomic64_fetch_dec(v) atomic64_fetch_sub(1, (v)) 945#define atomic64_fetch_dec_relaxed(v) atomic64_fetch_sub_relaxed(1, (v)) 946#define atomic64_fetch_dec_acquire(v) atomic64_fetch_sub_acquire(1, (v)) 947#define atomic64_fetch_dec_release(v) atomic64_fetch_sub_release(1, (v)) 948#else /* atomic64_fetch_dec */ 949#define atomic64_fetch_dec_relaxed atomic64_fetch_dec 950#define atomic64_fetch_dec_acquire atomic64_fetch_dec 951#define atomic64_fetch_dec_release atomic64_fetch_dec 952#endif /* atomic64_fetch_dec */ 953 954#else /* atomic64_fetch_dec_relaxed */ 955 956#ifndef atomic64_fetch_dec_acquire 957#define atomic64_fetch_dec_acquire(...) \ 958 __atomic_op_acquire(atomic64_fetch_dec, __VA_ARGS__) 959#endif 960 961#ifndef atomic64_fetch_dec_release 962#define atomic64_fetch_dec_release(...) \ 963 __atomic_op_release(atomic64_fetch_dec, __VA_ARGS__) 964#endif 965 966#ifndef atomic64_fetch_dec 967#define atomic64_fetch_dec(...) \ 968 __atomic_op_fence(atomic64_fetch_dec, __VA_ARGS__) 969#endif 970#endif /* atomic64_fetch_dec_relaxed */ 971 972/* atomic64_fetch_or_relaxed */ 973#ifndef atomic64_fetch_or_relaxed 974#define atomic64_fetch_or_relaxed atomic64_fetch_or 975#define atomic64_fetch_or_acquire atomic64_fetch_or 976#define atomic64_fetch_or_release atomic64_fetch_or 977 978#else /* atomic64_fetch_or_relaxed */ 979 980#ifndef atomic64_fetch_or_acquire 981#define atomic64_fetch_or_acquire(...) \ 982 __atomic_op_acquire(atomic64_fetch_or, __VA_ARGS__) 983#endif 984 985#ifndef atomic64_fetch_or_release 986#define atomic64_fetch_or_release(...) \ 987 __atomic_op_release(atomic64_fetch_or, __VA_ARGS__) 988#endif 989 990#ifndef atomic64_fetch_or 991#define atomic64_fetch_or(...) \ 992 __atomic_op_fence(atomic64_fetch_or, __VA_ARGS__) 993#endif 994#endif /* atomic64_fetch_or_relaxed */ 995 996/* atomic64_fetch_and_relaxed */ 997#ifndef atomic64_fetch_and_relaxed 998#define atomic64_fetch_and_relaxed atomic64_fetch_and 999#define atomic64_fetch_and_acquire atomic64_fetch_and 1000#define atomic64_fetch_and_release atomic64_fetch_and 1001 1002#else /* atomic64_fetch_and_relaxed */ 1003 1004#ifndef atomic64_fetch_and_acquire 1005#define atomic64_fetch_and_acquire(...) \ 1006 __atomic_op_acquire(atomic64_fetch_and, __VA_ARGS__) 1007#endif 1008 1009#ifndef atomic64_fetch_and_release 1010#define atomic64_fetch_and_release(...) \ 1011 __atomic_op_release(atomic64_fetch_and, __VA_ARGS__) 1012#endif 1013 1014#ifndef atomic64_fetch_and 1015#define atomic64_fetch_and(...) \ 1016 __atomic_op_fence(atomic64_fetch_and, __VA_ARGS__) 1017#endif 1018#endif /* atomic64_fetch_and_relaxed */ 1019 1020#ifndef atomic64_andnot 1021#define atomic64_andnot(i, v) atomic64_and(~(long long)(i), (v)) 1022#endif 1023 1024#ifndef atomic64_fetch_andnot_relaxed 1025 1026#ifndef atomic64_fetch_andnot 1027#define atomic64_fetch_andnot(i, v) atomic64_fetch_and(~(long long)(i), (v)) 1028#define atomic64_fetch_andnot_relaxed(i, v) atomic64_fetch_and_relaxed(~(long long)(i), (v)) 1029#define atomic64_fetch_andnot_acquire(i, v) atomic64_fetch_and_acquire(~(long long)(i), (v)) 1030#define atomic64_fetch_andnot_release(i, v) atomic64_fetch_and_release(~(long long)(i), (v)) 1031#else /* atomic64_fetch_andnot */ 1032#define atomic64_fetch_andnot_relaxed atomic64_fetch_andnot 1033#define atomic64_fetch_andnot_acquire atomic64_fetch_andnot 1034#define atomic64_fetch_andnot_release atomic64_fetch_andnot 1035#endif /* atomic64_fetch_andnot */ 1036 1037#else /* atomic64_fetch_andnot_relaxed */ 1038 1039#ifndef atomic64_fetch_andnot_acquire 1040#define atomic64_fetch_andnot_acquire(...) \ 1041 __atomic_op_acquire(atomic64_fetch_andnot, __VA_ARGS__) 1042#endif 1043 1044#ifndef atomic64_fetch_andnot_release 1045#define atomic64_fetch_andnot_release(...) \ 1046 __atomic_op_release(atomic64_fetch_andnot, __VA_ARGS__) 1047#endif 1048 1049#ifndef atomic64_fetch_andnot 1050#define atomic64_fetch_andnot(...) \ 1051 __atomic_op_fence(atomic64_fetch_andnot, __VA_ARGS__) 1052#endif 1053#endif /* atomic64_fetch_andnot_relaxed */ 1054 1055/* atomic64_fetch_xor_relaxed */ 1056#ifndef atomic64_fetch_xor_relaxed 1057#define atomic64_fetch_xor_relaxed atomic64_fetch_xor 1058#define atomic64_fetch_xor_acquire atomic64_fetch_xor 1059#define atomic64_fetch_xor_release atomic64_fetch_xor 1060 1061#else /* atomic64_fetch_xor_relaxed */ 1062 1063#ifndef atomic64_fetch_xor_acquire 1064#define atomic64_fetch_xor_acquire(...) \ 1065 __atomic_op_acquire(atomic64_fetch_xor, __VA_ARGS__) 1066#endif 1067 1068#ifndef atomic64_fetch_xor_release 1069#define atomic64_fetch_xor_release(...) \ 1070 __atomic_op_release(atomic64_fetch_xor, __VA_ARGS__) 1071#endif 1072 1073#ifndef atomic64_fetch_xor 1074#define atomic64_fetch_xor(...) \ 1075 __atomic_op_fence(atomic64_fetch_xor, __VA_ARGS__) 1076#endif 1077#endif /* atomic64_fetch_xor_relaxed */ 1078 1079 1080/* atomic64_xchg_relaxed */ 1081#ifndef atomic64_xchg_relaxed 1082#define atomic64_xchg_relaxed atomic64_xchg 1083#define atomic64_xchg_acquire atomic64_xchg 1084#define atomic64_xchg_release atomic64_xchg 1085 1086#else /* atomic64_xchg_relaxed */ 1087 1088#ifndef atomic64_xchg_acquire 1089#define atomic64_xchg_acquire(...) \ 1090 __atomic_op_acquire(atomic64_xchg, __VA_ARGS__) 1091#endif 1092 1093#ifndef atomic64_xchg_release 1094#define atomic64_xchg_release(...) \ 1095 __atomic_op_release(atomic64_xchg, __VA_ARGS__) 1096#endif 1097 1098#ifndef atomic64_xchg 1099#define atomic64_xchg(...) \ 1100 __atomic_op_fence(atomic64_xchg, __VA_ARGS__) 1101#endif 1102#endif /* atomic64_xchg_relaxed */ 1103 1104/* atomic64_cmpxchg_relaxed */ 1105#ifndef atomic64_cmpxchg_relaxed 1106#define atomic64_cmpxchg_relaxed atomic64_cmpxchg 1107#define atomic64_cmpxchg_acquire atomic64_cmpxchg 1108#define atomic64_cmpxchg_release atomic64_cmpxchg 1109 1110#else /* atomic64_cmpxchg_relaxed */ 1111 1112#ifndef atomic64_cmpxchg_acquire 1113#define atomic64_cmpxchg_acquire(...) \ 1114 __atomic_op_acquire(atomic64_cmpxchg, __VA_ARGS__) 1115#endif 1116 1117#ifndef atomic64_cmpxchg_release 1118#define atomic64_cmpxchg_release(...) \ 1119 __atomic_op_release(atomic64_cmpxchg, __VA_ARGS__) 1120#endif 1121 1122#ifndef atomic64_cmpxchg 1123#define atomic64_cmpxchg(...) \ 1124 __atomic_op_fence(atomic64_cmpxchg, __VA_ARGS__) 1125#endif 1126#endif /* atomic64_cmpxchg_relaxed */ 1127 1128#ifndef atomic64_try_cmpxchg 1129 1130#define __atomic64_try_cmpxchg(type, _p, _po, _n) \ 1131({ \ 1132 typeof(_po) __po = (_po); \ 1133 typeof(*(_po)) __r, __o = *__po; \ 1134 __r = atomic64_cmpxchg##type((_p), __o, (_n)); \ 1135 if (unlikely(__r != __o)) \ 1136 *__po = __r; \ 1137 likely(__r == __o); \ 1138}) 1139 1140#define atomic64_try_cmpxchg(_p, _po, _n) __atomic64_try_cmpxchg(, _p, _po, _n) 1141#define atomic64_try_cmpxchg_relaxed(_p, _po, _n) __atomic64_try_cmpxchg(_relaxed, _p, _po, _n) 1142#define atomic64_try_cmpxchg_acquire(_p, _po, _n) __atomic64_try_cmpxchg(_acquire, _p, _po, _n) 1143#define atomic64_try_cmpxchg_release(_p, _po, _n) __atomic64_try_cmpxchg(_release, _p, _po, _n) 1144 1145#else /* atomic64_try_cmpxchg */ 1146#define atomic64_try_cmpxchg_relaxed atomic64_try_cmpxchg 1147#define atomic64_try_cmpxchg_acquire atomic64_try_cmpxchg 1148#define atomic64_try_cmpxchg_release atomic64_try_cmpxchg 1149#endif /* atomic64_try_cmpxchg */ 1150 1151/** 1152 * atomic64_fetch_add_unless - add unless the number is already a given value 1153 * @v: pointer of type atomic64_t 1154 * @a: the amount to add to v... 1155 * @u: ...unless v is equal to u. 1156 * 1157 * Atomically adds @a to @v, if @v was not already @u. 1158 * Returns the original value of @v. 1159 */ 1160#ifndef atomic64_fetch_add_unless 1161static inline long long atomic64_fetch_add_unless(atomic64_t *v, long long a, 1162 long long u) 1163{ 1164 long long c = atomic64_read(v); 1165 1166 do { 1167 if (unlikely(c == u)) 1168 break; 1169 } while (!atomic64_try_cmpxchg(v, &c, c + a)); 1170 1171 return c; 1172} 1173#endif 1174 1175/** 1176 * atomic64_add_unless - add unless the number is already a given value 1177 * @v: pointer of type atomic_t 1178 * @a: the amount to add to v... 1179 * @u: ...unless v is equal to u. 1180 * 1181 * Atomically adds @a to @v, if @v was not already @u. 1182 * Returns true if the addition was done. 1183 */ 1184static inline bool atomic64_add_unless(atomic64_t *v, long long a, long long u) 1185{ 1186 return atomic64_fetch_add_unless(v, a, u) != u; 1187} 1188 1189/** 1190 * atomic64_inc_not_zero - increment unless the number is zero 1191 * @v: pointer of type atomic64_t 1192 * 1193 * Atomically increments @v by 1, if @v is non-zero. 1194 * Returns true if the increment was done. 1195 */ 1196#ifndef atomic64_inc_not_zero 1197#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) 1198#endif 1199 1200/** 1201 * atomic64_inc_and_test - increment and test 1202 * @v: pointer of type atomic64_t 1203 * 1204 * Atomically increments @v by 1 1205 * and returns true if the result is zero, or false for all 1206 * other cases. 1207 */ 1208#ifndef atomic64_inc_and_test 1209static inline bool atomic64_inc_and_test(atomic64_t *v) 1210{ 1211 return atomic64_inc_return(v) == 0; 1212} 1213#endif 1214 1215/** 1216 * atomic64_dec_and_test - decrement and test 1217 * @v: pointer of type atomic64_t 1218 * 1219 * Atomically decrements @v by 1 and 1220 * returns true if the result is 0, or false for all other 1221 * cases. 1222 */ 1223#ifndef atomic64_dec_and_test 1224static inline bool atomic64_dec_and_test(atomic64_t *v) 1225{ 1226 return atomic64_dec_return(v) == 0; 1227} 1228#endif 1229 1230/** 1231 * atomic64_sub_and_test - subtract value from variable and test result 1232 * @i: integer value to subtract 1233 * @v: pointer of type atomic64_t 1234 * 1235 * Atomically subtracts @i from @v and returns 1236 * true if the result is zero, or false for all 1237 * other cases. 1238 */ 1239#ifndef atomic64_sub_and_test 1240static inline bool atomic64_sub_and_test(long long i, atomic64_t *v) 1241{ 1242 return atomic64_sub_return(i, v) == 0; 1243} 1244#endif 1245 1246/** 1247 * atomic64_add_negative - add and test if negative 1248 * @i: integer value to add 1249 * @v: pointer of type atomic64_t 1250 * 1251 * Atomically adds @i to @v and returns true 1252 * if the result is negative, or false when 1253 * result is greater than or equal to zero. 1254 */ 1255#ifndef atomic64_add_negative 1256static inline bool atomic64_add_negative(long long i, atomic64_t *v) 1257{ 1258 return atomic64_add_return(i, v) < 0; 1259} 1260#endif 1261 1262#ifndef atomic64_inc_unless_negative 1263static inline bool atomic64_inc_unless_negative(atomic64_t *v) 1264{ 1265 long long c = atomic64_read(v); 1266 1267 do { 1268 if (unlikely(c < 0)) 1269 return false; 1270 } while (!atomic64_try_cmpxchg(v, &c, c + 1)); 1271 1272 return true; 1273} 1274#endif 1275 1276#ifndef atomic64_dec_unless_positive 1277static inline bool atomic64_dec_unless_positive(atomic64_t *v) 1278{ 1279 long long c = atomic64_read(v); 1280 1281 do { 1282 if (unlikely(c > 0)) 1283 return false; 1284 } while (!atomic64_try_cmpxchg(v, &c, c - 1)); 1285 1286 return true; 1287} 1288#endif 1289 1290/* 1291 * atomic64_dec_if_positive - decrement by 1 if old value positive 1292 * @v: pointer of type atomic64_t 1293 * 1294 * The function returns the old value of *v minus 1, even if 1295 * the atomic64 variable, v, was not decremented. 1296 */ 1297#ifndef atomic64_dec_if_positive 1298static inline long long atomic64_dec_if_positive(atomic64_t *v) 1299{ 1300 long long dec, c = atomic64_read(v); 1301 1302 do { 1303 dec = c - 1; 1304 if (unlikely(dec < 0)) 1305 break; 1306 } while (!atomic64_try_cmpxchg(v, &c, dec)); 1307 1308 return dec; 1309} 1310#endif 1311 1312#define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c)) 1313#define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c)) 1314 1315#include <asm-generic/atomic-long.h> 1316 1317#endif /* _LINUX_ATOMIC_H */