Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/ntirpc/misc/abstract_atomic.h
$ cat -n /usr/include/ntirpc/misc/abstract_atomic.h 1 /* 2 * Copyright (c) 2012 Linux Box Corporation. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 /* Permission to relicense his contributions under the above license terms 27 * was given by Frank S. Filz, in #ganesha (freenode), on 08/08/2012. 28 */ 29 30 /** 31 * @file abstract_atomic.h 32 * @author Adam C. Emerson
33 * @author Frank S. Filz
34 * @brief Shim for compiler or library supplied atomic operations 35 * 36 * This file provides inline functions that provide atomic operations 37 * appropriate to the compiler being used. (Someone can add support 38 * for an appropriate library later on.) 39 * 40 * The types functions are provided for: 41 * 42 * ptrdiff_t (fetch and store only) 43 * time_t (fetch and store only) 44 * void* (fetch and store only) 45 * uintptr_t (fetch and store only) 46 * int64_t 47 * uint64_t 48 * int32_t 49 * uint21_t 50 * int16_t 51 * uint16_t 52 * int8_t 53 * uint8_t 54 * size_t 55 * 56 * The functions provided are (using int64_t for example): 57 * 58 * int64_t atomic_add_int64_t(int64_t *augend, int64_t addend) 59 * int64_t atomic_inc_int64_t(int64_t *var) 60 * int64_t atomic_sub_int64_t(int64_t *minuend, int64_t subtrahend) 61 * int64_t atomic_dec_int64_t(int64_t *var) 62 * int64_t atomic_postadd_int64_t(int64_t *augend, int64_t addend) 63 * int64_t atomic_postinc_int64_t(int64_t *var) 64 * int64_t atomic_postsub_int64_t(int64_t *minuend, int64_t subtrahend) 65 * int64_t atomic_postdec_int64_t(int64_t *var) 66 * int64_t atomic_fetch_int64_t(int64_t *var) 67 * void atomic_store_int64_t(int64_t *var, int64_t val) 68 * 69 * The following bit mask operations are provided for 70 * uint64_t, uint32_t, uint_16t, and uint8_t: 71 * 72 * uint64_t atomic_clear_uint64_t_bits(uint64_t *var, uint64_t bits) 73 * uint64_t atomic_set_uint64_t_bits(uint64_t *var, uint64_t bits) 74 * uint64_t atomic_postclear_uint64_t_bits(uint64_t *var, 75 * uint64_t atomic_postset_uint64_t_bits(uint64_t *var, 76 * 77 */ 78 79 #ifndef _ABSTRACT_ATOMIC_H 80 #define _ABSTRACT_ATOMIC_H 81 #include
82 #include
83 #include
84 85 #undef GCC_SYNC_FUNCTIONS 86 #undef GCC_ATOMIC_FUNCTIONS 87 88 #ifndef __GNUC__ 89 #error Please edit abstract_atomic.h and implement support for \ 90 non-GNU compilers. 91 #else /* __GNUC__ */ 92 #define ATOMIC_GCC_VERSION (__GNUC__ * 10000 \ 93 + __GNUC_MINOR__ * 100 \ 94 + __GNUC_PATCHLEVEL__) 95 96 #if ((ATOMIC_GCC_VERSION) >= 40700) 97 #define GCC_ATOMIC_FUNCTIONS 1 98 #elif ((ATOMIC_GCC_VERSION) >= 40100) 99 #define GCC_SYNC_FUNCTIONS 1 100 #else 101 #error This verison of GCC does not support atomics. 102 #endif /* Version check */ 103 #endif /* __GNUC__ */ 104 105 /* 106 * Preaddition, presubtraction, preincrement, predecrement (return the 107 * value after the operation, by analogy with the ++n preincrement 108 * operator.) 109 */ 110 111 /** 112 * @brief Atomically add to an int64_t 113 * 114 * This function atomically adds to the supplied value. 115 * 116 * @param[in,out] augend Number to be added to 117 * @param[in] addend Number to add 118 * 119 * @return The value after addition. 120 */ 121 122 #ifdef GCC_ATOMIC_FUNCTIONS 123 static inline int64_t atomic_add_int64_t(int64_t *augend, int64_t addend) 124 { 125 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 126 } 127 #elif defined(GCC_SYNC_FUNCTIONS) 128 static inline int64_t atomic_add_int64_t(int64_t *augend, int64_t addend) 129 { 130 return __sync_add_and_fetch(augend, addend); 131 } 132 #endif 133 134 /** 135 * @brief Atomically increment an int64_t 136 * 137 * This function atomically adds 1 to the supplied value. 138 * 139 * @param[in,out] var Pointer to the variable to modify 140 * 141 * @return The value after increment. 142 */ 143 144 static inline int64_t atomic_inc_int64_t(int64_t *var) 145 { 146 return atomic_add_int64_t(var, 1); 147 } 148 149 /** 150 * @brief Atomically subtract from an int64_t 151 * 152 * This function atomically subtracts from the supplied value. 153 * 154 * @param[in,out] minuend Number to be subtracted from 155 * @param[in] subtrahend Number to subtract 156 * 157 * @return The value after subtraction. 158 */ 159 160 #ifdef GCC_ATOMIC_FUNCTIONS 161 static inline int64_t atomic_sub_int64_t(int64_t *minuend, int64_t subtrahend) 162 { 163 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 164 } 165 #elif defined(GCC_SYNC_FUNCTIONS) 166 static inline int64_t atomic_sub_int64_t(int64_t *minuend, int64_t subtrahend) 167 { 168 return __sync_sub_and_fetch(minuend, subtrahend); 169 } 170 #endif 171 172 /** 173 * @brief Atomically decrement an int64_t 174 * 175 * This function atomically subtracts 1 from the supplied value. 176 * 177 * @param[in,out] var Pointer to the variable to modify 178 */ 179 180 static inline int64_t atomic_dec_int64_t(int64_t *var) 181 { 182 return atomic_sub_int64_t(var, 1); 183 } 184 185 /** 186 * @brief Atomically add to an int64_t 187 * 188 * This function atomically adds to the supplied value. 189 * 190 * @param[in,out] augend Number to be added to 191 * @param[in] addend Number to add 192 * 193 * @return The value after addition. 194 */ 195 196 #ifdef GCC_ATOMIC_FUNCTIONS 197 static inline uint64_t atomic_add_uint64_t(uint64_t *augend, uint64_t addend) 198 { 199 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 200 } 201 #elif defined(GCC_SYNC_FUNCTIONS) 202 static inline uint64_t atomic_add_uint64_t(uint64_t *augend, uint64_t addend) 203 { 204 return __sync_add_and_fetch(augend, addend); 205 } 206 #endif 207 208 /** 209 * @brief Atomically increment a uint64_t 210 * 211 * This function atomically adds 1 to the supplied value. 212 * 213 * @param[in,out] var Pointer to the variable to modify 214 * 215 * @return The value after increment. 216 */ 217 218 static inline uint64_t atomic_inc_uint64_t(uint64_t *var) 219 { 220 return atomic_add_uint64_t(var, 1); 221 } 222 223 /** 224 * @brief Atomically subtract from a uint64_t 225 * 226 * This function atomically subtracts from the supplied value. 227 * 228 * @param[in,out] minuend Number to be subtracted from 229 * @param[in] subtrahend Number to subtract 230 * 231 * @return The value after subtraction. 232 */ 233 234 #ifdef GCC_ATOMIC_FUNCTIONS 235 static inline uint64_t atomic_sub_uint64_t(uint64_t *minuend, 236 uint64_t subtrahend) 237 { 238 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 239 } 240 #elif defined(GCC_SYNC_FUNCTIONS) 241 static inline uint64_t atomic_sub_uint64_t(uint64_t *minuend, 242 uint64_t subtrahend) 243 { 244 return __sync_sub_and_fetch(minuend, subtrahend); 245 } 246 #endif 247 248 /** 249 * @brief Atomically decrement a uint64_t 250 * 251 * This function atomically subtracts 1 from the supplied value. 252 * 253 * @param[in,out] var Pointer to the variable to modify 254 * 255 * @return The value after decrement. 256 */ 257 258 static inline uint64_t atomic_dec_uint64_t(uint64_t *var) 259 { 260 return atomic_sub_uint64_t(var, 1); 261 } 262 263 /** 264 * @brief Atomically add to an int32_t 265 * 266 * This function atomically adds to the supplied value. 267 * 268 * @param[in,out] augend Number to be added to 269 * @param[in] addend Number to add 270 * 271 * @return The value after addition. 272 */ 273 274 #ifdef GCC_ATOMIC_FUNCTIONS 275 static inline int32_t atomic_add_int32_t(int32_t *augend, int32_t addend) 276 { 277 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 278 } 279 #elif defined(GCC_SYNC_FUNCTIONS) 280 static inline int32_t atomic_add_int32_t(int32_t *augend, int32_t addend) 281 { 282 return __sync_add_and_fetch(augend, addend); 283 } 284 #endif 285 286 /** 287 * @brief Atomically increment an int32_t 288 * 289 * This function atomically adds 1 to the supplied value. 290 * 291 * @param[in,out] var Pointer to the variable to modify 292 * 293 * @return The value after increment. 294 */ 295 296 static inline int32_t atomic_inc_int32_t(int32_t *var) 297 { 298 return atomic_add_int32_t(var, 1); 299 } 300 301 /** 302 * @brief Atomically subtract from an int32_t 303 * 304 * This function atomically subtracts from the supplied value. 305 * 306 * @param[in,out] minuend Number to be subtracted from 307 * @param[in] subtrahend Number to subtract 308 * 309 * @return The value after subtraction. 310 */ 311 312 #ifdef GCC_ATOMIC_FUNCTIONS 313 static inline int32_t atomic_sub_int32_t(int32_t *minuend, int32_t subtrahend) 314 { 315 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 316 } 317 #elif defined(GCC_SYNC_FUNCTIONS) 318 static inline int32_t atomic_sub_int32_t(int32_t *minuend, int32_t subtrahend) 319 { 320 return __sync_sub_and_fetch(minuend, subtrahend); 321 } 322 #endif 323 324 /** 325 * @brief Atomically decrement an int32_t 326 * 327 * This function atomically subtracts 1 from the supplied value. 328 * 329 * @param[in,out] var Pointer to the variable to modify 330 * 331 * @return The value after decrement. 332 */ 333 334 static inline int32_t atomic_dec_int32_t(int32_t *var) 335 { 336 return atomic_sub_int32_t(var, 1); 337 } 338 339 /** 340 * @brief Atomically add to a uint32_t 341 * 342 * This function atomically adds to the supplied value. 343 * 344 * @param[in,out] augend Number to be added to 345 * @param[in] addend Number to add 346 * 347 * @return The value after addition. 348 */ 349 350 #ifdef GCC_ATOMIC_FUNCTIONS 351 static inline uint32_t atomic_add_uint32_t(uint32_t *augend, uint32_t addend) 352 { 353 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 354 } 355 #elif defined(GCC_SYNC_FUNCTIONS) 356 static inline uint32_t atomic_add_uint32_t(uint32_t *augend, uint32_t addend) 357 { 358 return __sync_add_and_fetch(augend, addend); 359 } 360 #endif 361 362 /** 363 * @brief Atomically increment a uint32_t 364 * 365 * This function atomically adds 1 to the supplied value. 366 * 367 * @param[in,out] var Pointer to the variable to modify 368 * 369 * @return The value after increment. 370 */ 371 372 static inline uint32_t atomic_inc_uint32_t(uint32_t *var) 373 { 374 return atomic_add_uint32_t(var, 1); 375 } 376 377 /** 378 * @brief Atomically subtract from a uint32_t 379 * 380 * This function atomically subtracts from the supplied value. 381 * 382 * @param[in,out] var Pointer to the variable to modify 383 * 384 * @return The value after subtraction. 385 */ 386 387 #ifdef GCC_ATOMIC_FUNCTIONS 388 static inline uint32_t atomic_sub_uint32_t(uint32_t *var, uint32_t sub) 389 { 390 return __atomic_sub_fetch(var, sub, __ATOMIC_SEQ_CST); 391 } 392 #elif defined(GCC_SYNC_FUNCTIONS) 393 static inline uint32_t atomic_sub_uint32_t(uint32_t *var, uint32_t sub) 394 { 395 return __sync_sub_and_fetch(var, sub); 396 } 397 #endif 398 399 /** 400 * @brief Atomically decrement a uint32_t 401 * 402 * This function atomically subtracts 1 from the supplied value. 403 * 404 * @param[in,out] var Pointer to the variable to modify 405 * 406 * @return The value after decrement. 407 */ 408 409 static inline uint32_t atomic_dec_uint32_t(uint32_t *var) 410 { 411 return atomic_sub_uint32_t(var, 1); 412 } 413 414 /** 415 * @brief Atomically add to an int16_t 416 * 417 * This function atomically adds to the supplied value. 418 * 419 * @param[in,out] augend Number to be added to 420 * @param[in] addend Number to add 421 * 422 * @return The value after addition. 423 */ 424 425 #ifdef GCC_ATOMIC_FUNCTIONS 426 static inline int16_t atomic_add_int16_t(int16_t *augend, int16_t addend) 427 { 428 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 429 } 430 #elif defined(GCC_SYNC_FUNCTIONS) 431 static inline int16_t atomic_add_int16_t(int16_t *augend, int16_t addend) 432 { 433 return __sync_add_and_fetch(augend, addend); 434 } 435 #endif 436 437 /** 438 * @brief Atomically increment an int16_t 439 * 440 * This function atomically adds 1 to the supplied value. 441 * 442 * @param[in,out] var Pointer to the variable to modify 443 * 444 * @return The value after increment. 445 */ 446 447 static inline int16_t atomic_inc_int16_t(int16_t *var) 448 { 449 return atomic_add_int16_t(var, 1); 450 } 451 452 /** 453 * @brief Atomically subtract from an int16_t 454 * 455 * This function atomically subtracts from the supplied value. 456 * 457 * @param[in,out] minuend Number to be subtracted from 458 * @param[in] subtrahend Number to subtract 459 * 460 * @return The value after subtraction. 461 */ 462 463 #ifdef GCC_ATOMIC_FUNCTIONS 464 static inline int16_t atomic_sub_int16_t(int16_t *minuend, int16_t subtrahend) 465 { 466 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 467 } 468 #elif defined(GCC_SYNC_FUNCTIONS) 469 static inline int16_t atomic_sub_int16_t(int16_t *minuend, int16_t subtrahend) 470 { 471 return __sync_sub_and_fetch(minuend, subtrahend); 472 } 473 #endif 474 475 /** 476 * @brief Atomically decrement an int16_t 477 * 478 * This function atomically subtracts 1 from the supplied value. 479 * 480 * @param[in,out] var Pointer to the variable to modify 481 * 482 * @return The value after decrement. 483 */ 484 485 static inline int16_t atomic_dec_int16_t(int16_t *var) 486 { 487 return atomic_sub_int16_t(var, 1); 488 } 489 490 /** 491 * @brief Atomically add to a uint16_t 492 * 493 * This function atomically adds to the supplied value. 494 * 495 * @param[in,out] augend Number to be added to 496 * @param[in] addend Number to add 497 * 498 * @return The value after addition. 499 */ 500 501 #ifdef GCC_ATOMIC_FUNCTIONS 502 static inline uint16_t atomic_add_uint16_t(uint16_t *augend, uint16_t addend) 503 { 504 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 505 } 506 #elif defined(GCC_SYNC_FUNCTIONS) 507 static inline uint16_t atomic_add_uint16_t(uint16_t *augend, uint16_t addend) 508 { 509 return __sync_add_and_fetch(augend, addend); 510 } 511 #endif 512 513 /** 514 * @brief Atomically increment a uint16_t 515 * 516 * This function atomically adds 1 to the supplied value. 517 * 518 * @param[in,out] var Pointer to the variable to modify 519 * 520 * @return The value after increment. 521 */ 522 523 static inline uint16_t atomic_inc_uint16_t(uint16_t *var) 524 { 525 return atomic_add_uint16_t(var, 1); 526 } 527 528 /** 529 * @brief Atomically subtract from a uint16_t 530 * 531 * This function atomically subtracts from the supplied value. 532 * 533 * @param[in,out] minuend Number to be subtracted from 534 * @param[in] subtrahend Number to subtract 535 * 536 * @return The value after subtraction. 537 */ 538 539 #ifdef GCC_ATOMIC_FUNCTIONS 540 static inline uint16_t atomic_sub_uint16_t(uint16_t *minuend, 541 uint16_t subtrahend) 542 { 543 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 544 } 545 #elif defined(GCC_SYNC_FUNCTIONS) 546 static inline uint16_t atomic_sub_uint16_t(uint16_t *minuend, 547 uint16_t subtrahend) 548 { 549 return __sync_sub_and_fetch(minuend, subtrahend); 550 } 551 #endif 552 553 /** 554 * @brief Atomically decrement a uint16_t 555 * 556 * This function atomically subtracts 1 from the supplied value. 557 * 558 * @param[in,out] var Pointer to the variable to modify 559 * 560 * @return The value after decrement. 561 */ 562 563 static inline uint16_t atomic_dec_uint16_t(uint16_t *var) 564 { 565 return atomic_sub_uint16_t(var, 1); 566 } 567 568 /** 569 * @brief Atomically add to an int8_t 570 * 571 * This function atomically adds to the supplied value. 572 * 573 * @param[in,out] augend Number to be added to 574 * @param[in] addend Number to add 575 * 576 * @return The value after addition. 577 */ 578 579 #ifdef GCC_ATOMIC_FUNCTIONS 580 static inline int8_t atomic_add_int8_t(int8_t *augend, int8_t addend) 581 { 582 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 583 } 584 #elif defined(GCC_SYNC_FUNCTIONS) 585 static inline int8_t atomic_add_int8_t(int8_t *augend, int8_t addend) 586 { 587 return __sync_add_and_fetch(augend, addend); 588 } 589 #endif 590 591 /** 592 * @brief Atomically increment an int8_t 593 * 594 * This function atomically adds 1 to the supplied value. 595 * 596 * @param[in,out] var Pointer to the variable to modify 597 * 598 * @return The value after increment. 599 */ 600 601 static inline int8_t atomic_inc_int8_t(int8_t *var) 602 { 603 return atomic_add_int8_t(var, 1); 604 } 605 606 /** 607 * @brief Atomically subtract from an int8_t 608 * 609 * This function atomically subtracts from the supplied value. 610 * 611 * @param[in,out] minuend Number to be subtracted from 612 * @param[in] subtrahend Number to subtract 613 * 614 * @return The value after subtraction. 615 */ 616 617 #ifdef GCC_ATOMIC_FUNCTIONS 618 static inline int8_t atomic_sub_int8_t(int8_t *minuend, int8_t subtrahend) 619 { 620 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 621 } 622 #elif defined(GCC_SYNC_FUNCTIONS) 623 static inline int8_t atomic_sub_int8_t(int8_t *minuend, int8_t subtrahend) 624 { 625 return __sync_sub_and_fetch(minuend, subtrahend); 626 } 627 #endif 628 629 /** 630 * @brief Atomically decrement an int8_t 631 * 632 * This function atomically subtracts 1 from the supplied value. 633 * 634 * @param[in,out] var Pointer to the variable to modify 635 * 636 * @return The value after decrement. 637 */ 638 639 static inline int8_t atomic_dec_int8_t(int8_t *var) 640 { 641 return atomic_sub_int8_t(var, 1); 642 } 643 644 /** 645 * @brief Atomically add to a uint8_t 646 * 647 * This function atomically adds to the supplied value. 648 * 649 * @param[in,out] augend Number to be added to 650 * @param[in] addend Number to add 651 * 652 * @return The value after addition. 653 */ 654 655 #ifdef GCC_ATOMIC_FUNCTIONS 656 static inline uint8_t atomic_add_uint8_t(uint8_t *augend, int8_t addend) 657 { 658 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 659 } 660 #elif defined(GCC_SYNC_FUNCTIONS) 661 static inline uint8_t atomic_add_uint8_t(uint8_t *augend, int8_t addend) 662 { 663 return __sync_add_and_fetch(augend, addend); 664 } 665 #endif 666 667 /** 668 * @brief Atomically increment a uint8_t 669 * 670 * This function atomically adds 1 to the supplied value. 671 * 672 * @param[in,out] var Pointer to the variable to modify 673 * 674 * @return The value after increment. 675 */ 676 677 static inline uint8_t atomic_inc_uint8_t(uint8_t *var) 678 { 679 return atomic_add_uint8_t(var, 1); 680 } 681 682 /** 683 * @brief Atomically subtract from a uint8_t 684 * 685 * This function atomically subtracts from the supplied value. 686 * 687 * @param[in,out] minuend Number to be subtracted from 688 * @param[in] subtrahend Number to subtract 689 * 690 * @return The value after subtraction. 691 */ 692 693 #ifdef GCC_ATOMIC_FUNCTIONS 694 static inline uint8_t atomic_sub_uint8_t(uint8_t *minuend, uint8_t subtrahend) 695 { 696 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 697 } 698 #elif defined(GCC_SYNC_FUNCTIONS) 699 static inline uint8_t atomic_sub_uint8_t(uint8_t *minuend, uint8_t subtrahend) 700 { 701 return __sync_sub_and_fetch(minuend, subtrahend); 702 } 703 #endif 704 705 /** 706 * @brief Atomically decrement a uint8_t 707 * 708 * This function atomically subtracts 1 from the supplied value. 709 * 710 * @param[in,out] var Pointer to the variable to modify 711 * 712 * @return The value after decrement. 713 */ 714 715 static inline uint8_t atomic_dec_uint8_t(uint8_t *var) 716 { 717 return atomic_sub_uint8_t(var, 1); 718 } 719 720 /** 721 * @brief Atomically add to a size_t 722 * 723 * This function atomically adds to the supplied value. 724 * 725 * @param[in,out] augend Number to be added to 726 * @param[in] addend Number to add 727 * 728 * @return The value after addition. 729 */ 730 731 #ifdef GCC_ATOMIC_FUNCTIONS 732 static inline size_t atomic_add_size_t(size_t *augend, size_t addend) 733 { 734 return __atomic_add_fetch(augend, addend, __ATOMIC_SEQ_CST); 735 } 736 #elif defined(GCC_SYNC_FUNCTIONS) 737 static inline size_t atomic_add_size_t(size_t *augend, size_t addend) 738 { 739 return __sync_add_and_fetch(augend, addend); 740 } 741 #endif 742 743 /** 744 * @brief Atomically increment a size_t 745 * 746 * This function atomically adds 1 to the supplied value. 747 * 748 * @param[in,out] var Pointer to the variable to modify 749 * 750 * @return The value after increment. 751 */ 752 753 static inline size_t atomic_inc_size_t(size_t *var) 754 { 755 return atomic_add_size_t(var, 1); 756 } 757 758 /** 759 * @brief Atomically subtract from a size_t 760 * 761 * This function atomically subtracts from the supplied value. 762 * 763 * @param[in,out] minuend Number to be subtracted from 764 * @param[in] subtrahend Number to subtract 765 * 766 * @return The value after subtraction. 767 */ 768 769 #ifdef GCC_ATOMIC_FUNCTIONS 770 static inline size_t atomic_sub_size_t(size_t *minuend, size_t subtrahend) 771 { 772 return __atomic_sub_fetch(minuend, subtrahend, __ATOMIC_SEQ_CST); 773 } 774 #elif defined(GCC_SYNC_FUNCTIONS) 775 static inline size_t atomic_sub_size_t(size_t *minuend, size_t subtrahend) 776 { 777 return __sync_sub_and_fetch(minuend, subtrahend); 778 } 779 #endif 780 781 /** 782 * @brief Atomically decrement a size_t 783 * 784 * This function atomically subtracts 1 from the supplied value. 785 * 786 * @param[in,out] var Pointer to the variable to modify 787 * 788 * @return The value after decrement. 789 */ 790 791 static inline size_t atomic_dec_size_t(size_t *var) 792 { 793 return atomic_sub_size_t(var, 1); 794 } 795 796 /* 797 * Postaddition, postsubtraction, postincrement, postdecrement (return the 798 * value before the operation, by analogy with the n++ postincrement 799 * operator.) 800 */ 801 802 /** 803 * @brief Atomically add to an int64_t 804 * 805 * This function atomically adds to the supplied value. 806 * 807 * @param[in,out] augend Number to be added to 808 * @param[in] addend Number to add 809 * 810 * @return The value before addition. 811 */ 812 813 #ifdef GCC_ATOMIC_FUNCTIONS 814 static inline int64_t atomic_postadd_int64_t(int64_t *augend, int64_t addend) 815 { 816 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 817 } 818 #elif defined(GCC_SYNC_FUNCTIONS) 819 static inline int64_t atomic_postadd_int64_t(int64_t *augend, int64_t addend) 820 { 821 return __sync_fetch_and_add(augend, addend); 822 } 823 #endif 824 825 /** 826 * @brief Atomically increment an int64_t 827 * 828 * This function atomically adds 1 to the supplied value. 829 * 830 * @param[in,out] var Pointer to the variable to modify 831 * 832 * @return The value before increment. 833 */ 834 835 static inline int64_t atomic_postinc_int64_t(int64_t *var) 836 { 837 return atomic_postadd_int64_t(var, 1); 838 } 839 840 /** 841 * @brief Atomically subtract from an int64_t 842 * 843 * This function atomically subtracts from the supplied value. 844 * 845 * @param[in,out] minuend Number to be subtracted from 846 * @param[in] subtrahend Number to subtract 847 * 848 * @return The value before subtraction. 849 */ 850 851 #ifdef GCC_ATOMIC_FUNCTIONS 852 static inline int64_t atomic_postsub_int64_t(int64_t *minuend, 853 int64_t subtrahend) 854 { 855 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 856 } 857 #elif defined(GCC_SYNC_FUNCTIONS) 858 static inline int64_t atomic_postsub_int64_t(int64_t *minuend, 859 int64_t subtrahend) 860 { 861 return __sync_fetch_and_sub(minuend, subtrahend); 862 } 863 #endif 864 865 /** 866 * @brief Atomically decrement an int64_t 867 * 868 * This function atomically subtracts 1 from the supplied value. 869 * 870 * @param[in,out] var Pointer to the variable to modify 871 */ 872 873 static inline int64_t atomic_postdec_int64_t(int64_t *var) 874 { 875 return atomic_postsub_int64_t(var, 1); 876 } 877 878 /** 879 * @brief Atomically add to an int64_t 880 * 881 * This function atomically adds to the supplied value. 882 * 883 * @param[in,out] augend Number to be added to 884 * @param[in] addend Number to add 885 * 886 * @return The value before addition. 887 */ 888 889 #ifdef GCC_ATOMIC_FUNCTIONS 890 static inline uint64_t atomic_postadd_uint64_t(uint64_t *augend, 891 uint64_t addend) 892 { 893 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 894 } 895 #elif defined(GCC_SYNC_FUNCTIONS) 896 static inline uint64_t atomic_postadd_uint64_t(uint64_t *augend, 897 uint64_t addend) 898 { 899 return __sync_fetch_and_add(augend, addend); 900 } 901 #endif 902 903 /** 904 * @brief Atomically increment a uint64_t 905 * 906 * This function atomically adds 1 to the supplied value. 907 * 908 * @param[in,out] var Pointer to the variable to modify 909 * 910 * @return The value before increment. 911 */ 912 913 static inline uint64_t atomic_postinc_uint64_t(uint64_t *var) 914 { 915 return atomic_postadd_uint64_t(var, 1); 916 } 917 918 /** 919 * @brief Atomically subtract from a uint64_t 920 * 921 * This function atomically subtracts from the supplied value. 922 * 923 * @param[in,out] minuend Number to be subtracted from 924 * @param[in] subtrahend Number to subtract 925 * 926 * @return The value before subtraction. 927 */ 928 929 #ifdef GCC_ATOMIC_FUNCTIONS 930 static inline uint64_t atomic_postsub_uint64_t(uint64_t *minuend, 931 uint64_t subtrahend) 932 { 933 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 934 } 935 #elif defined(GCC_SYNC_FUNCTIONS) 936 static inline uint64_t atomic_postsub_uint64_t(uint64_t *minuend, 937 uint64_t subtrahend) 938 { 939 return __sync_fetch_and_sub(minuend, subtrahend); 940 } 941 #endif 942 943 /** 944 * @brief Atomically decrement a uint64_t 945 * 946 * This function atomically subtracts 1 from the supplied value. 947 * 948 * @param[in,out] var Pointer to the variable to modify 949 * 950 * @return The value before decrement. 951 */ 952 953 static inline uint64_t atomic_postdec_uint64_t(uint64_t *var) 954 { 955 return atomic_postsub_uint64_t(var, 1); 956 } 957 958 /** 959 * @brief Atomically add to an int32_t 960 * 961 * This function atomically adds to the supplied value. 962 * 963 * @param[in,out] augend Number to be added to 964 * @param[in] addend Number to add 965 * 966 * @return The value before addition. 967 */ 968 969 #ifdef GCC_ATOMIC_FUNCTIONS 970 static inline int32_t atomic_postadd_int32_t(int32_t *augend, int32_t addend) 971 { 972 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 973 } 974 #elif defined(GCC_SYNC_FUNCTIONS) 975 static inline int32_t atomic_postadd_int32_t(int32_t *augend, int32_t addend) 976 { 977 return __sync_fetch_and_add(augend, addend); 978 } 979 #endif 980 981 /** 982 * @brief Atomically increment an int32_t 983 * 984 * This function atomically adds 1 to the supplied value. 985 * 986 * @param[in,out] var Pointer to the variable to modify 987 * 988 * @return The value before increment. 989 */ 990 991 static inline int32_t atomic_postinc_int32_t(int32_t *var) 992 { 993 return atomic_postadd_int32_t(var, 1); 994 } 995 996 /** 997 * @brief Atomically subtract from an int32_t 998 * 999 * This function atomically subtracts from the supplied value. 1000 * 1001 * @param[in,out] minuend Number to be subtracted from 1002 * @param[in] subtrahend Number to subtract 1003 * 1004 * @return The value before subtraction. 1005 */ 1006 1007 #ifdef GCC_ATOMIC_FUNCTIONS 1008 static inline int32_t atomic_postsub_int32_t(int32_t *minuend, 1009 int32_t subtrahend) 1010 { 1011 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 1012 } 1013 #elif defined(GCC_SYNC_FUNCTIONS) 1014 static inline int32_t atomic_postsub_int32_t(int32_t *minuend, 1015 int32_t subtrahend) 1016 { 1017 return __sync_fetch_and_sub(minuend, subtrahend); 1018 } 1019 #endif 1020 1021 /** 1022 * @brief Atomically decrement an int32_t 1023 * 1024 * This function atomically subtracts 1 from the supplied value. 1025 * 1026 * @param[in,out] var Pointer to the variable to modify 1027 * 1028 * @return The value before decrement. 1029 */ 1030 1031 static inline int32_t atomic_postdec_int32_t(int32_t *var) 1032 { 1033 return atomic_postsub_int32_t(var, 1); 1034 } 1035 1036 /** 1037 * @brief Atomically add to a uint32_t 1038 * 1039 * This function atomically adds to the supplied value. 1040 * 1041 * @param[in,out] augend Number to be added to 1042 * @param[in] addend Number to add 1043 * 1044 * @return The value before addition. 1045 */ 1046 1047 #ifdef GCC_ATOMIC_FUNCTIONS 1048 static inline uint32_t atomic_postadd_uint32_t(uint32_t *augend, 1049 uint32_t addend) 1050 { 1051 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 1052 } 1053 #elif defined(GCC_SYNC_FUNCTIONS) 1054 static inline uint32_t atomic_postadd_uint32_t(uint32_t *augend, 1055 uint32_t addend) 1056 { 1057 return __sync_fetch_and_add(augend, addend); 1058 } 1059 #endif 1060 1061 /** 1062 * @brief Atomically increment a uint32_t 1063 * 1064 * This function atomically adds 1 to the supplied value. 1065 * 1066 * @param[in,out] var Pointer to the variable to modify 1067 * 1068 * @return The value before increment. 1069 */ 1070 1071 static inline uint32_t atomic_postinc_uint32_t(uint32_t *var) 1072 { 1073 return atomic_postadd_uint32_t(var, 1); 1074 } 1075 1076 /** 1077 * @brief Atomically subtract from a uint32_t 1078 * 1079 * This function atomically subtracts from the supplied value. 1080 * 1081 * @param[in,out] var Pointer to the variable to modify 1082 * 1083 * @return The value before subtraction. 1084 */ 1085 1086 #ifdef GCC_ATOMIC_FUNCTIONS 1087 static inline uint32_t atomic_postsub_uint32_t(uint32_t *var, uint32_t sub) 1088 { 1089 return __atomic_fetch_sub(var, sub, __ATOMIC_SEQ_CST); 1090 } 1091 #elif defined(GCC_SYNC_FUNCTIONS) 1092 static inline uint32_t atomic_postsub_uint32_t(uint32_t *var, uint32_t sub) 1093 { 1094 return __sync_fetch_and_sub(var, sub); 1095 } 1096 #endif 1097 1098 /** 1099 * @brief Atomically decrement a uint32_t 1100 * 1101 * This function atomically subtracts 1 from the supplied value. 1102 * 1103 * @param[in,out] var Pointer to the variable to modify 1104 * 1105 * @return The value before decrement. 1106 */ 1107 1108 static inline uint32_t atomic_postdec_uint32_t(uint32_t *var) 1109 { 1110 return atomic_postsub_uint32_t(var, 1); 1111 } 1112 1113 /** 1114 * @brief Atomically add to an int16_t 1115 * 1116 * This function atomically adds to the supplied value. 1117 * 1118 * @param[in,out] augend Number to be added to 1119 * @param[in] addend Number to add 1120 * 1121 * @return The value before addition. 1122 */ 1123 1124 #ifdef GCC_ATOMIC_FUNCTIONS 1125 static inline int16_t atomic_postadd_int16_t(int16_t *augend, int16_t addend) 1126 { 1127 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 1128 } 1129 #elif defined(GCC_SYNC_FUNCTIONS) 1130 static inline int16_t atomic_postadd_int16_t(int16_t *augend, int16_t addend) 1131 { 1132 return __sync_fetch_and_add(augend, addend); 1133 } 1134 #endif 1135 1136 /** 1137 * @brief Atomically increment an int16_t 1138 * 1139 * This function atomically adds 1 to the supplied value. 1140 * 1141 * @param[in,out] var Pointer to the variable to modify 1142 * 1143 * @return The value before increment. 1144 */ 1145 1146 static inline int16_t atomic_postinc_int16_t(int16_t *var) 1147 { 1148 return atomic_postadd_int16_t(var, 1); 1149 } 1150 1151 /** 1152 * @brief Atomically subtract from an int16_t 1153 * 1154 * This function atomically subtracts from the supplied value. 1155 * 1156 * @param[in,out] minuend Number to be subtracted from 1157 * @param[in] subtrahend Number to subtract 1158 * 1159 * @return The value before subtraction. 1160 */ 1161 1162 #ifdef GCC_ATOMIC_FUNCTIONS 1163 static inline int16_t atomic_postsub_int16_t(int16_t *minuend, 1164 int16_t subtrahend) 1165 { 1166 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 1167 } 1168 #elif defined(GCC_SYNC_FUNCTIONS) 1169 static inline int16_t atomic_postsub_int16_t(int16_t *minuend, 1170 int16_t subtrahend) 1171 { 1172 return __sync_fetch_and_sub(minuend, subtrahend); 1173 } 1174 #endif 1175 1176 /** 1177 * @brief Atomically decrement an int16_t 1178 * 1179 * This function atomically subtracts 1 from the supplied value. 1180 * 1181 * @param[in,out] var Pointer to the variable to modify 1182 * 1183 * @return The value before decrement. 1184 */ 1185 1186 static inline int16_t atomic_postdec_int16_t(int16_t *var) 1187 { 1188 return atomic_postsub_int16_t(var, 1); 1189 } 1190 1191 /** 1192 * @brief Atomically add to a uint16_t 1193 * 1194 * This function atomically adds to the supplied value. 1195 * 1196 * @param[in,out] augend Number to be added to 1197 * @param[in] addend Number to add 1198 * 1199 * @return The value before addition. 1200 */ 1201 1202 #ifdef GCC_ATOMIC_FUNCTIONS 1203 static inline uint16_t atomic_postadd_uint16_t(uint16_t *augend, 1204 uint16_t addend) 1205 { 1206 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 1207 } 1208 #elif defined(GCC_SYNC_FUNCTIONS) 1209 static inline uint16_t atomic_postadd_uint16_t(uint16_t *augend, 1210 uint16_t addend) 1211 { 1212 return __sync_fetch_and_add(augend, addend); 1213 } 1214 #endif 1215 1216 /** 1217 * @brief Atomically increment a uint16_t 1218 * 1219 * This function atomically adds 1 to the supplied value. 1220 * 1221 * @param[in,out] var Pointer to the variable to modify 1222 * 1223 * @return The value before increment. 1224 */ 1225 1226 static inline uint16_t atomic_postinc_uint16_t(uint16_t *var) 1227 { 1228 return atomic_postadd_uint16_t(var, 1); 1229 } 1230 1231 /** 1232 * @brief Atomically subtract from a uint16_t 1233 * 1234 * This function atomically subtracts from the supplied value. 1235 * 1236 * @param[in,out] minuend Number to be subtracted from 1237 * @param[in] subtrahend Number to subtract 1238 * 1239 * @return The value before subtraction. 1240 */ 1241 1242 #ifdef GCC_ATOMIC_FUNCTIONS 1243 static inline uint16_t atomic_postsub_uint16_t(uint16_t *minuend, 1244 uint16_t subtrahend) 1245 { 1246 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 1247 } 1248 #elif defined(GCC_SYNC_FUNCTIONS) 1249 static inline uint16_t atomic_postsub_uint16_t(uint16_t *minuend, 1250 uint16_t subtrahend) 1251 { 1252 return __sync_fetch_and_sub(minuend, subtrahend); 1253 } 1254 #endif 1255 1256 /** 1257 * @brief Atomically decrement a uint16_t 1258 * 1259 * This function atomically subtracts 1 from the supplied value. 1260 * 1261 * @param[in,out] var Pointer to the variable to modify 1262 * 1263 * @return The value before decrement. 1264 */ 1265 1266 static inline uint16_t atomic_postdec_uint16_t(uint16_t *var) 1267 { 1268 return atomic_postsub_uint16_t(var, 1); 1269 } 1270 1271 /** 1272 * @brief Atomically add to an int8_t 1273 * 1274 * This function atomically adds to the supplied value. 1275 * 1276 * @param[in,out] augend Number to be added to 1277 * @param[in] addend Number to add 1278 * 1279 * @return The value before addition. 1280 */ 1281 1282 #ifdef GCC_ATOMIC_FUNCTIONS 1283 static inline int8_t atomic_postadd_int8_t(int8_t *augend, int8_t addend) 1284 { 1285 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 1286 } 1287 #elif defined(GCC_SYNC_FUNCTIONS) 1288 static inline int8_t atomic_postadd_int8_t(int8_t *augend, int8_t addend) 1289 { 1290 return __sync_fetch_and_add(augend, addend); 1291 } 1292 #endif 1293 1294 /** 1295 * @brief Atomically increment an int8_t 1296 * 1297 * This function atomically adds 1 to the supplied value. 1298 * 1299 * @param[in,out] var Pointer to the variable to modify 1300 * 1301 * @return The value before increment. 1302 */ 1303 1304 static inline int8_t atomic_postinc_int8_t(int8_t *var) 1305 { 1306 return atomic_postadd_int8_t(var, 1); 1307 } 1308 1309 /** 1310 * @brief Atomically subtract from an int8_t 1311 * 1312 * This function atomically subtracts from the supplied value. 1313 * 1314 * @param[in,out] minuend Number to be subtracted from 1315 * @param[in] subtrahend Number to subtract 1316 * 1317 * @return The value before subtraction. 1318 */ 1319 1320 #ifdef GCC_ATOMIC_FUNCTIONS 1321 static inline int8_t atomic_postsub_int8_t(int8_t *minuend, int8_t subtrahend) 1322 { 1323 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 1324 } 1325 #elif defined(GCC_SYNC_FUNCTIONS) 1326 static inline int8_t atomic_postsub_int8_t(int8_t *minuend, int8_t subtrahend) 1327 { 1328 return __sync_fetch_and_sub(minuend, subtrahend); 1329 } 1330 #endif 1331 1332 /** 1333 * @brief Atomically decrement an int8_t 1334 * 1335 * This function atomically subtracts 1 from the supplied value. 1336 * 1337 * @param[in,out] var Pointer to the variable to modify 1338 * 1339 * @return The value before decrement. 1340 */ 1341 1342 static inline int8_t atomic_postdec_int8_t(int8_t *var) 1343 { 1344 return atomic_postsub_int8_t(var, 1); 1345 } 1346 1347 /** 1348 * @brief Atomically add to a uint8_t 1349 * 1350 * This function atomically adds to the supplied value. 1351 * 1352 * @param[in,out] augend Number to be added to 1353 * @param[in] addend Number to add 1354 * 1355 * @return The value before addition. 1356 */ 1357 1358 #ifdef GCC_ATOMIC_FUNCTIONS 1359 static inline uint8_t atomic_postadd_uint8_t(uint8_t *augend, uint8_t addend) 1360 { 1361 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 1362 } 1363 #elif defined(GCC_SYNC_FUNCTIONS) 1364 static inline uint8_t atomic_postadd_uint8_t(uint8_t *augend, uint8_t addend) 1365 { 1366 return __sync_fetch_and_add(augend, addend); 1367 } 1368 #endif 1369 1370 /** 1371 * @brief Atomically increment a uint8_t 1372 * 1373 * This function atomically adds 1 to the supplied value. 1374 * 1375 * @param[in,out] var Pointer to the variable to modify 1376 * 1377 * @return The value before increment. 1378 */ 1379 1380 static inline uint8_t atomic_postinc_uint8_t(uint8_t *var) 1381 { 1382 return atomic_postadd_uint8_t(var, 1); 1383 } 1384 1385 /** 1386 * @brief Atomically subtract from a uint8_t 1387 * 1388 * This function atomically subtracts from the supplied value. 1389 * 1390 * @param[in,out] minuend Number to be subtracted from 1391 * @param[in] subtrahend Number to subtract 1392 * 1393 * @return The value before subtraction. 1394 */ 1395 1396 #ifdef GCC_ATOMIC_FUNCTIONS 1397 static inline uint8_t atomic_postsub_uint8_t(uint8_t *minuend, 1398 uint8_t subtrahend) 1399 { 1400 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 1401 } 1402 #elif defined(GCC_SYNC_FUNCTIONS) 1403 static inline uint8_t atomic_postsub_uint8_t(uint8_t *minuend, 1404 uint8_t subtrahend) 1405 { 1406 return __sync_fetch_and_sub(minuend, subtrahend); 1407 } 1408 #endif 1409 1410 /** 1411 * @brief Atomically decrement a uint8_t 1412 * 1413 * This function atomically subtracts 1 from the supplied value. 1414 * 1415 * @param[in,out] var Pointer to the variable to modify 1416 * 1417 * @return The value before decrement. 1418 */ 1419 1420 static inline uint8_t atomic_postdec_uint8_t(uint8_t *var) 1421 { 1422 return atomic_postsub_uint8_t(var, 1); 1423 } 1424 1425 /** 1426 * @brief Atomically add to a size_t 1427 * 1428 * This function atomically adds to the supplied value. 1429 * 1430 * @param[in,out] augend Number to be added to 1431 * @param[in] addend Number to add 1432 * 1433 * @return The value before addition. 1434 */ 1435 1436 #ifdef GCC_ATOMIC_FUNCTIONS 1437 static inline size_t atomic_postadd_size_t(size_t *augend, size_t addend) 1438 { 1439 return __atomic_fetch_add(augend, addend, __ATOMIC_SEQ_CST); 1440 } 1441 #elif defined(GCC_SYNC_FUNCTIONS) 1442 static inline size_t atomic_postadd_size_t(size_t *augend, size_t addend) 1443 { 1444 return __sync_fetch_and_add(augend, addend); 1445 } 1446 #endif 1447 1448 /** 1449 * @brief Atomically increment a size_t 1450 * 1451 * This function atomically adds 1 to the supplied value. 1452 * 1453 * @param[in,out] var Pointer to the variable to modify 1454 * 1455 * @return The value before increment. 1456 */ 1457 1458 static inline size_t atomic_postinc_size_t(size_t *var) 1459 { 1460 return atomic_postadd_size_t(var, 1); 1461 } 1462 1463 /** 1464 * @brief Atomically subtract from a size_t 1465 * 1466 * This function atomically subtracts from the supplied value. 1467 * 1468 * @param[in,out] minuend Number to be subtracted from 1469 * @param[in] subtrahend Number to subtract 1470 * 1471 * @return The value before subtraction. 1472 */ 1473 1474 #ifdef GCC_ATOMIC_FUNCTIONS 1475 static inline size_t atomic_postsub_size_t(size_t *minuend, size_t subtrahend) 1476 { 1477 return __atomic_fetch_sub(minuend, subtrahend, __ATOMIC_SEQ_CST); 1478 } 1479 #elif defined(GCC_SYNC_FUNCTIONS) 1480 static inline size_t atomic_postsub_size_t(size_t *minuend, size_t subtrahend) 1481 { 1482 return __sync_fetch_and_sub(minuend, subtrahend); 1483 } 1484 #endif 1485 1486 /** 1487 * @brief Atomically decrement a size_t 1488 * 1489 * This function atomically subtracts 1 from the supplied value. 1490 * 1491 * @param[in,out] var Pointer to the variable to modify 1492 * 1493 * @return The value before decrement. 1494 */ 1495 1496 static inline size_t atomic_postdec_size_t(size_t *var) 1497 { 1498 return atomic_postsub_size_t(var, 1); 1499 } 1500 1501 /* 1502 * Preclear and preset bits (return the value after the operation, by 1503 * analogy with the ++n preincrement operator.) 1504 */ 1505 1506 /** 1507 * @brief Atomically clear bits in a uint64_t 1508 * 1509 * This function atomic clears the bits indicated. 1510 * 1511 * @param[in,out] var Pointer to the value to modify 1512 * @param[in] bits Bits to clear 1513 * 1514 * @return The value after clearing. 1515 */ 1516 1517 #ifdef GCC_ATOMIC_FUNCTIONS 1518 static inline uint64_t atomic_clear_uint64_t_bits(uint64_t *var, uint64_t bits) 1519 { 1520 return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); 1521 } 1522 #elif defined(GCC_SYNC_FUNCTIONS) 1523 static inline uint64_t atomic_clear_uint64_t_bits(uint64_t *var, uint64_t bits) 1524 { 1525 return __sync_and_and_fetch(var, ~bits); 1526 } 1527 #endif 1528 1529 /** 1530 * @brief Atomically set bits in a uint64_t 1531 * 1532 * This function atomic clears the bits indicated. 1533 * 1534 * @param[in,out] var Pointer to the value to modify 1535 * @param[in] bits Bits to set 1536 * 1537 * @return The value after setting. 1538 */ 1539 1540 #ifdef GCC_ATOMIC_FUNCTIONS 1541 static inline uint64_t atomic_set_uint64_t_bits(uint64_t *var, uint64_t bits) 1542 { 1543 return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); 1544 } 1545 #elif defined(GCC_SYNC_FUNCTIONS) 1546 static inline uint64_t atomic_set_uint64_t_bits(uint64_t *var, uint64_t bits) 1547 { 1548 return __sync_or_and_fetch(var, bits); 1549 } 1550 #endif 1551 1552 /** 1553 * @brief Atomically clear bits in a uint32_t 1554 * 1555 * This function atomic clears the bits indicated. 1556 * 1557 * @param[in,out] var Pointer to the value to modify 1558 * @param[in] bits Bits to clear 1559 * 1560 * @return The value after clearing. 1561 */ 1562 1563 #ifdef GCC_ATOMIC_FUNCTIONS 1564 static inline uint32_t atomic_clear_uint32_t_bits(uint32_t *var, uint32_t bits) 1565 { 1566 return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); 1567 } 1568 #elif defined(GCC_SYNC_FUNCTIONS) 1569 static inline uint32_t atomic_clear_uint32_t_bits(uint32_t *var, uint32_t bits) 1570 { 1571 return __sync_and_and_fetch(var, ~bits); 1572 } 1573 #endif 1574 1575 /** 1576 * @brief Atomically set bits in a uint32_t 1577 * 1578 * This function atomic clears the bits indicated. 1579 * 1580 * @param[in,out] var Pointer to the value to modify 1581 * @param[in] bits Bits to set 1582 * 1583 * @return The value after setting. 1584 */ 1585 1586 #ifdef GCC_ATOMIC_FUNCTIONS 1587 static inline uint32_t atomic_set_uint32_t_bits(uint32_t *var, uint32_t bits) 1588 { 1589 return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); 1590 } 1591 #elif defined(GCC_SYNC_FUNCTIONS) 1592 static inline uint32_t atomic_set_uint32_t_bits(uint32_t *var, uint32_t bits) 1593 { 1594 return __sync_or_and_fetch(var, bits); 1595 } 1596 #endif 1597 1598 /** 1599 * @brief Atomically clear bits in a uint16_t 1600 * 1601 * This function atomic clears the bits indicated. 1602 * 1603 * @param[in,out] var Pointer to the value to modify 1604 * @param[in] bits Bits to clear 1605 * 1606 * @return The value after clearing. 1607 */ 1608 1609 #ifdef GCC_ATOMIC_FUNCTIONS 1610 static inline uint16_t atomic_clear_uint16_t_bits(uint16_t *var, uint16_t bits) 1611 { 1612 return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); 1613 } 1614 #elif defined(GCC_SYNC_FUNCTIONS) 1615 static inline uint16_t atomic_clear_uint16_t_bits(uint16_t *var, uint16_t bits) 1616 { 1617 return __sync_and_and_fetch(var, ~bits); 1618 } 1619 #endif 1620 1621 /** 1622 * @brief Atomically set bits in a uint16_t 1623 * 1624 * This function atomic clears the bits indicated. 1625 * 1626 * @param[in,out] var Pointer to the value to modify 1627 * @param[in] bits Bits to set 1628 * 1629 * @return The value after setting. 1630 */ 1631 1632 #ifdef GCC_ATOMIC_FUNCTIONS 1633 static inline uint16_t atomic_set_uint16_t_bits(uint16_t *var, uint16_t bits) 1634 { 1635 return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); 1636 } 1637 #elif defined(GCC_SYNC_FUNCTIONS) 1638 static inline uint16_t atomic_set_uint16_t_bits(uint16_t *var, uint16_t bits) 1639 { 1640 return __sync_or_and_fetch(var, bits); 1641 } 1642 #endif 1643 1644 /** 1645 * @brief Atomically clear bits in a uint8_t 1646 * 1647 * This function atomic clears the bits indicated. 1648 * 1649 * @param[in,out] var Pointer to the value to modify 1650 * @param[in] bits Bits to clear 1651 * 1652 * @return The value after clearing. 1653 */ 1654 1655 #ifdef GCC_ATOMIC_FUNCTIONS 1656 static inline uint8_t atomic_clear_uint8_t_bits(uint8_t *var, uint8_t bits) 1657 { 1658 return __atomic_and_fetch(var, ~bits, __ATOMIC_SEQ_CST); 1659 } 1660 #elif defined(GCC_SYNC_FUNCTIONS) 1661 static inline uint8_t atomic_clear_uint8_t_bits(uint8_t *var, uint8_t bits) 1662 { 1663 return __sync_and_and_fetch(var, ~bits); 1664 } 1665 #endif 1666 1667 /** 1668 * @brief Atomically set bits in a uint8_t 1669 * 1670 * This function atomic clears the bits indicated. 1671 * 1672 * @param[in,out] var Pointer to the value to modify 1673 * @param[in] bits Bits to set 1674 * 1675 * @return The value after setting. 1676 */ 1677 1678 #ifdef GCC_ATOMIC_FUNCTIONS 1679 static inline uint8_t atomic_set_uint8_t_bits(uint8_t *var, uint8_t bits) 1680 { 1681 return __atomic_or_fetch(var, bits, __ATOMIC_SEQ_CST); 1682 } 1683 #elif defined(GCC_SYNC_FUNCTIONS) 1684 static inline uint8_t atomic_set_uint8_t_bits(uint8_t *var, uint8_t bits) 1685 { 1686 return __sync_or_and_fetch(var, bits); 1687 } 1688 #endif 1689 1690 /* 1691 * Postclear and postset bits (return the value before the operation, 1692 * by analogy with the n++ postincrement operator.) 1693 */ 1694 1695 /** 1696 * @brief Atomically clear bits in a uint64_t 1697 * 1698 * This function atomic clears the bits indicated. 1699 * 1700 * @param[in,out] var Pointer to the value to modify 1701 * @param[in] bits Bits to clear 1702 * 1703 * @return The value before clearing. 1704 */ 1705 1706 #ifdef GCC_ATOMIC_FUNCTIONS 1707 static inline uint64_t atomic_postclear_uint64_t_bits(uint64_t *var, 1708 uint64_t bits) 1709 { 1710 return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); 1711 } 1712 #elif defined(GCC_SYNC_FUNCTIONS) 1713 static inline uint64_t atomic_postclear_uint64_t_bits(uint64_t *var, 1714 uint64_t bits) 1715 { 1716 return __sync_fetch_and_and(var, ~bits); 1717 } 1718 #endif 1719 1720 /** 1721 * @brief Atomically set bits in a uint64_t 1722 * 1723 * This function atomic clears the bits indicated. 1724 * 1725 * @param[in,out] var Pointer to the value to modify 1726 * @param[in] bits Bits to set 1727 * 1728 * @return The value before setting. 1729 */ 1730 1731 #ifdef GCC_ATOMIC_FUNCTIONS 1732 static inline uint64_t atomic_postset_uint64_t_bits(uint64_t *var, 1733 uint64_t bits) 1734 { 1735 return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); 1736 } 1737 #elif defined(GCC_SYNC_FUNCTIONS) 1738 static inline uint64_t atomic_postset_uint64_t_bits(uint64_t *var, 1739 uint64_t bits) 1740 { 1741 return __sync_fetch_and_or(var, bits); 1742 } 1743 #endif 1744 1745 /** 1746 * @brief Atomically clear bits in a uint32_t 1747 * 1748 * This function atomic clears the bits indicated. 1749 * 1750 * @param[in,out] var Pointer to the value to modify 1751 * @param[in] bits Bits to clear 1752 * 1753 * @return The value before clearing. 1754 */ 1755 1756 #ifdef GCC_ATOMIC_FUNCTIONS 1757 static inline uint32_t atomic_postclear_uint32_t_bits(uint32_t *var, 1758 uint32_t bits) 1759 { 1760 return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); 1761 } 1762 #elif defined(GCC_SYNC_FUNCTIONS) 1763 static inline uint32_t atomic_postclear_uint32_t_bits(uint32_t *var, 1764 uint32_t bits) 1765 { 1766 return __sync_fetch_and_and(var, ~bits); 1767 } 1768 #endif 1769 1770 /** 1771 * @brief Atomically set bits in a uint32_t 1772 * 1773 * This function atomic clears the bits indicated. 1774 * 1775 * @param[in,out] var Pointer to the value to modify 1776 * @param[in] bits Bits to set 1777 * 1778 * @return The value before setting. 1779 */ 1780 1781 #ifdef GCC_ATOMIC_FUNCTIONS 1782 static inline uint32_t atomic_postset_uint32_t_bits(uint32_t *var, 1783 uint32_t bits) 1784 { 1785 return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); 1786 } 1787 #elif defined(GCC_SYNC_FUNCTIONS) 1788 static inline uint32_t atomic_postset_uint32_t_bits(uint32_t *var, 1789 uint32_t bits) 1790 { 1791 return __sync_fetch_and_or(var, bits); 1792 } 1793 #endif 1794 1795 /** 1796 * @brief Atomically clear bits in a uint16_t 1797 * 1798 * This function atomic clears the bits indicated. 1799 * 1800 * @param[in,out] var Pointer to the value to modify 1801 * @param[in] bits Bits to clear 1802 * 1803 * @return The value before clearing. 1804 */ 1805 1806 #ifdef GCC_ATOMIC_FUNCTIONS 1807 static inline uint16_t atomic_postclear_uint16_t_bits(uint16_t *var, 1808 uint16_t bits) 1809 { 1810 return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); 1811 } 1812 #elif defined(GCC_SYNC_FUNCTIONS) 1813 static inline uint16_t atomic_postclear_uint16_t_bits(uint16_t *var, 1814 uint16_t bits) 1815 { 1816 return __sync_fetch_and_and(var, ~bits); 1817 } 1818 #endif 1819 1820 /** 1821 * @brief Atomically set bits in a uint16_t 1822 * 1823 * This function atomic clears the bits indicated. 1824 * 1825 * @param[in,out] var Pointer to the value to modify 1826 * @param[in] bits Bits to set 1827 * 1828 * @return The value before setting. 1829 */ 1830 1831 #ifdef GCC_ATOMIC_FUNCTIONS 1832 static inline uint16_t atomic_postset_uint16_t_bits(uint16_t *var, 1833 uint16_t bits) 1834 { 1835 return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); 1836 } 1837 #elif defined(GCC_SYNC_FUNCTIONS) 1838 static inline uint16_t atomic_postset_uint16_t_bits(uint16_t *var, 1839 uint16_t bits) 1840 { 1841 return __sync_fetch_and_or(var, bits); 1842 } 1843 #endif 1844 1845 /** 1846 * @brief Atomically clear bits in a uint8_t 1847 * 1848 * This function atomic clears the bits indicated. 1849 * 1850 * @param[in,out] var Pointer to the value to modify 1851 * @param[in] bits Bits to clear 1852 * 1853 * @return The value before clearing. 1854 */ 1855 1856 #ifdef GCC_ATOMIC_FUNCTIONS 1857 static inline uint8_t atomic_postclear_uint8_t_bits(uint8_t *var, uint8_t bits) 1858 { 1859 return __atomic_fetch_and(var, ~bits, __ATOMIC_SEQ_CST); 1860 } 1861 #elif defined(GCC_SYNC_FUNCTIONS) 1862 static inline uint8_t atomic_postclear_uint8_t_bits(uint8_t *var, uint8_t bits) 1863 { 1864 return __sync_fetch_and_and(var, ~bits); 1865 } 1866 #endif 1867 1868 /** 1869 * @brief Atomically set bits in a uint8_t 1870 * 1871 * This function atomic clears the bits indicated. 1872 * 1873 * @param[in,out] var Pointer to the value to modify 1874 * @param[in] bits Bits to set 1875 * 1876 * @return The value before setting. 1877 */ 1878 1879 #ifdef GCC_ATOMIC_FUNCTIONS 1880 static inline uint8_t atomic_postset_uint8_t_bits(uint8_t *var, uint8_t bits) 1881 { 1882 return __atomic_fetch_or(var, bits, __ATOMIC_SEQ_CST); 1883 } 1884 #elif defined(GCC_SYNC_FUNCTIONS) 1885 static inline uint8_t atomic_postset_uint8_t_bits(uint8_t *var, uint8_t bits) 1886 { 1887 return __sync_fetch_and_or(var, bits); 1888 } 1889 #endif 1890 1891 /* 1892 * Fetch and store 1893 */ 1894 1895 /** 1896 * @brief Atomically fetch a size_t 1897 * 1898 * This function atomically fetches the value indicated by the 1899 * supplied pointer. 1900 * 1901 * @param[in,out] var Pointer to the variable to fetch 1902 * 1903 * @return the value pointed to by var. 1904 */ 1905 1906 #ifdef GCC_ATOMIC_FUNCTIONS 1907 static inline size_t atomic_fetch_size_t(size_t *var) 1908 { 1909 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 1910 } 1911 #elif defined(GCC_SYNC_FUNCTIONS) 1912 static inline size_t atomic_fetch_size_t(size_t *var) 1913 { 1914 return __sync_fetch_and_add(var, 0); 1915 } 1916 #endif 1917 1918 /** 1919 * @brief Atomically store a size_t 1920 * 1921 * This function atomically fetches the value indicated by the 1922 * supplied pointer. 1923 * 1924 * @param[in,out] var Pointer to the variable to modify 1925 * @param[in] val The value to store 1926 */ 1927 1928 #ifdef GCC_ATOMIC_FUNCTIONS 1929 static inline void atomic_store_size_t(size_t *var, size_t val) 1930 { 1931 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 1932 } 1933 #elif defined(GCC_SYNC_FUNCTIONS) 1934 static inline void atomic_store_size_t(size_t *var, size_t val) 1935 { 1936 (void)__sync_lock_test_and_set(var, val); 1937 } 1938 #endif 1939 1940 /** 1941 * @brief Atomically fetch a ptrdiff_t 1942 * 1943 * This function atomically fetches the value indicated by the 1944 * supplied pointer. 1945 * 1946 * @param[in,out] var Pointer to the variable to fetch 1947 * 1948 * @return the value pointed to by var. 1949 */ 1950 1951 #ifdef GCC_ATOMIC_FUNCTIONS 1952 static inline ptrdiff_t atomic_fetch_ptrdiff_t(ptrdiff_t *var) 1953 { 1954 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 1955 } 1956 #elif defined(GCC_SYNC_FUNCTIONS) 1957 static inline ptrdiff_t atomic_fetch_ptrdiff_t(ptrdiff_t *var) 1958 { 1959 return __sync_fetch_and_add(var, 0); 1960 } 1961 #endif 1962 1963 /** 1964 * @brief Atomically store a ptrdiff_t 1965 * 1966 * This function atomically fetches the value indicated by the 1967 * supplied pointer. 1968 * 1969 * @param[in,out] var Pointer to the variable to modify 1970 * @param[in] val The value to store 1971 */ 1972 1973 #ifdef GCC_ATOMIC_FUNCTIONS 1974 static inline void atomic_store_ptrdiff_t(ptrdiff_t *var, ptrdiff_t val) 1975 { 1976 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 1977 } 1978 #elif defined(GCC_SYNC_FUNCTIONS) 1979 static inline void atomic_store_ptrdiff_t(ptrdiff_t *var, ptrdiff_t val) 1980 { 1981 (void)__sync_lock_test_and_set(var, val); 1982 } 1983 #endif 1984 1985 /** 1986 * @brief Atomically fetch a time_t 1987 * 1988 * This function atomically fetches the value indicated by the 1989 * supplied pointer. 1990 * 1991 * @param[in,out] var Pointer to the variable to fetch 1992 * 1993 * @return the value pointed to by var. 1994 */ 1995 1996 #ifdef GCC_ATOMIC_FUNCTIONS 1997 static inline time_t atomic_fetch_time_t(time_t *var) 1998 { 1999 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2000 } 2001 #elif defined(GCC_SYNC_FUNCTIONS) 2002 static inline time_t atomic_fetch_time_t(time_t *var) 2003 { 2004 return __sync_fetch_and_add(var, 0); 2005 } 2006 #endif 2007 2008 /** 2009 * @brief Atomically store a time_t 2010 * 2011 * This function atomically fetches the value indicated by the 2012 * supplied pointer. 2013 * 2014 * @param[in,out] var Pointer to the variable to modify 2015 * @param[in] val The value to store 2016 */ 2017 2018 #ifdef GCC_ATOMIC_FUNCTIONS 2019 static inline void atomic_store_time_t(time_t *var, time_t val) 2020 { 2021 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2022 } 2023 #elif defined(GCC_SYNC_FUNCTIONS) 2024 static inline void atomic_store_time_t(time_t *var, time_t val) 2025 { 2026 (void)__sync_lock_test_and_set(var, val); 2027 } 2028 #endif 2029 2030 /** 2031 * @brief Atomically fetch a uintptr_t 2032 * 2033 * This function atomically fetches the value indicated by the 2034 * supplied pointer. 2035 * 2036 * @param[in,out] var Pointer to the variable to fetch 2037 * 2038 * @return the value pointed to by var. 2039 */ 2040 2041 #ifdef GCC_ATOMIC_FUNCTIONS 2042 static inline uintptr_t atomic_fetch_uintptr_t(uintptr_t *var) 2043 { 2044 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2045 } 2046 #elif defined(GCC_SYNC_FUNCTIONS) 2047 static inline uintptr_t atomic_fetch_uintptr_t(uintptr_t *var) 2048 { 2049 return __sync_fetch_and_add(var, 0); 2050 } 2051 #endif 2052 2053 /** 2054 * @brief Atomically store a uintptr_t 2055 * 2056 * This function atomically fetches the value indicated by the 2057 * supplied pointer. 2058 * 2059 * @param[in,out] var Pointer to the variable to modify 2060 * @param[in] val The value to store 2061 */ 2062 2063 #ifdef GCC_ATOMIC_FUNCTIONS 2064 static inline void atomic_store_uintptr_t(uintptr_t *var, uintptr_t val) 2065 { 2066 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2067 } 2068 #elif defined(GCC_SYNC_FUNCTIONS) 2069 static inline void atomic_store_uintptr_t(uintptr_t *var, uintptr_t val) 2070 { 2071 (void)__sync_lock_test_and_set(var, 0); 2072 } 2073 #endif 2074 2075 /** 2076 * @brief Atomically fetch a void * 2077 * 2078 * This function atomically fetches the value indicated by the 2079 * supplied pointer. 2080 * 2081 * @param[in,out] var Pointer to the variable to fetch 2082 * 2083 * @return the value pointed to by var. 2084 */ 2085 2086 #ifdef GCC_ATOMIC_FUNCTIONS 2087 static inline void *atomic_fetch_voidptr(void **var) 2088 { 2089 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2090 } 2091 #elif defined(GCC_SYNC_FUNCTIONS) 2092 static inline void *atomic_fetch_voidptr(void **var) 2093 { 2094 return __sync_fetch_and_add(var, 0); 2095 } 2096 #endif 2097 2098 /** 2099 * @brief Atomically store a void * 2100 * 2101 * This function atomically stores the value indicated by the 2102 * supplied pointer. 2103 * 2104 * @param[in,out] var Pointer to the variable to modify 2105 * @param[in] val The value to store 2106 */ 2107 2108 #ifdef GCC_ATOMIC_FUNCTIONS 2109 static inline void atomic_store_voidptr(void **var, void *val) 2110 { 2111 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2112 } 2113 #elif defined(GCC_SYNC_FUNCTIONS) 2114 static inline void atomic_store_voidptr(void **var, void *val) 2115 { 2116 (void)__sync_lock_test_and_set(var, val); 2117 } 2118 #endif 2119 2120 /** 2121 * @brief Atomically fetch an int64_t 2122 * 2123 * This function atomically fetches the value indicated by the 2124 * supplied pointer. 2125 * 2126 * @param[in,out] var Pointer to the variable to fetch 2127 * 2128 * @return the value pointed to by var. 2129 */ 2130 2131 #ifdef GCC_ATOMIC_FUNCTIONS 2132 static inline int64_t atomic_fetch_int64_t(int64_t *var) 2133 { 2134 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2135 } 2136 #elif defined(GCC_SYNC_FUNCTIONS) 2137 static inline int64_t atomic_fetch_int64_t(int64_t *var) 2138 { 2139 return __sync_fetch_and_add(var, 0); 2140 } 2141 #endif 2142 2143 /** 2144 * @brief Atomically store an int64_t 2145 * 2146 * This function atomically fetches the value indicated by the 2147 * supplied pointer. 2148 * 2149 * @param[in,out] var Pointer to the variable to modify 2150 * @param[in] val The value to store 2151 */ 2152 2153 #ifdef GCC_ATOMIC_FUNCTIONS 2154 static inline void atomic_store_int64_t(int64_t *var, int64_t val) 2155 { 2156 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2157 } 2158 #elif defined(GCC_SYNC_FUNCTIONS) 2159 static inline void atomic_store_int64_t(int64_t *var, int64_t val) 2160 { 2161 (void)__sync_lock_test_and_set(var, val); 2162 } 2163 #endif 2164 2165 /** 2166 * @brief Atomically fetch a uint64_t 2167 * 2168 * This function atomically fetches the value indicated by the 2169 * supplied pointer. 2170 * 2171 * @param[in,out] var Pointer to the variable to fetch 2172 * 2173 * @return the value pointed to by var. 2174 */ 2175 2176 #ifdef GCC_ATOMIC_FUNCTIONS 2177 static inline uint64_t atomic_fetch_uint64_t(uint64_t *var) 2178 { 2179 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2180 } 2181 #elif defined(GCC_SYNC_FUNCTIONS) 2182 static inline uint64_t atomic_fetch_uint64_t(uint64_t *var) 2183 { 2184 return __sync_fetch_and_add(var, 0); 2185 } 2186 #endif 2187 2188 /** 2189 * @brief Atomically store a uint64_t 2190 * 2191 * This function atomically fetches the value indicated by the 2192 * supplied pointer. 2193 * 2194 * @param[in,out] var Pointer to the variable to modify 2195 * @param[in] val The value to store 2196 */ 2197 2198 #ifdef GCC_ATOMIC_FUNCTIONS 2199 static inline void atomic_store_uint64_t(uint64_t *var, uint64_t val) 2200 { 2201 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2202 } 2203 #elif defined(GCC_SYNC_FUNCTIONS) 2204 static inline void atomic_store_uint64_t(uint64_t *var, uint64_t val) 2205 { 2206 (void)__sync_lock_test_and_set(var, val); 2207 } 2208 #endif 2209 2210 /** 2211 * @brief Atomically fetch an int32_t 2212 * 2213 * This function atomically fetches the value indicated by the 2214 * supplied pointer. 2215 * 2216 * @param[in,out] var Pointer to the variable to fetch 2217 * 2218 * @return the value pointed to by var. 2219 */ 2220 2221 #ifdef GCC_ATOMIC_FUNCTIONS 2222 static inline int32_t atomic_fetch_int32_t(int32_t *var) 2223 { 2224 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2225 } 2226 #elif defined(GCC_SYNC_FUNCTIONS) 2227 static inline int32_t atomic_fetch_int32_t(int32_t *var) 2228 { 2229 return __sync_fetch_and_add(var, 0); 2230 } 2231 #endif 2232 2233 /** 2234 * @brief Atomically store an int32_t 2235 * 2236 * This function atomically fetches the value indicated by the 2237 * supplied pointer. 2238 * 2239 * @param[in,out] var Pointer to the variable to modify 2240 * @param[in] val The value to store 2241 */ 2242 2243 #ifdef GCC_ATOMIC_FUNCTIONS 2244 static inline void atomic_store_int32_t(int32_t *var, int32_t val) 2245 { 2246 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2247 } 2248 #elif defined(GCC_SYNC_FUNCTIONS) 2249 static inline void atomic_store_int32_t(int32_t *var, int32_t val) 2250 { 2251 (void)__sync_lock_test_and_set(var, val); 2252 } 2253 #endif 2254 2255 /** 2256 * @brief Atomically fetch a uint32_t 2257 * 2258 * This function atomically fetches the value indicated by the 2259 * supplied pointer. 2260 * 2261 * @param[in,out] var Pointer to the variable to fetch 2262 * 2263 * @return the value pointed to by var. 2264 */ 2265 2266 #ifdef GCC_ATOMIC_FUNCTIONS 2267 static inline uint32_t atomic_fetch_uint32_t(uint32_t *var) 2268 { 2269 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2270 } 2271 #elif defined(GCC_SYNC_FUNCTIONS) 2272 static inline uint32_t atomic_fetch_uint32_t(uint32_t *var) 2273 { 2274 return __sync_fetch_and_add(var, 0); 2275 } 2276 #endif 2277 2278 /** 2279 * @brief Atomically store a uint32_t 2280 * 2281 * This function atomically fetches the value indicated by the 2282 * supplied pointer. 2283 * 2284 * @param[in,out] var Pointer to the variable to modify 2285 * @param[in] val The value to store 2286 */ 2287 2288 #ifdef GCC_ATOMIC_FUNCTIONS 2289 static inline void atomic_store_uint32_t(uint32_t *var, uint32_t val) 2290 { 2291 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2292 } 2293 #elif defined(GCC_SYNC_FUNCTIONS) 2294 static inline void atomic_store_uint32_t(uint32_t *var, uint32_t val) 2295 { 2296 (void)__sync_lock_test_and_set(var, val); 2297 } 2298 #endif 2299 2300 /** 2301 * @brief Atomically fetch an int16_t 2302 * 2303 * This function atomically fetches the value indicated by the 2304 * supplied pointer. 2305 * 2306 * @param[in,out] var Pointer to the variable to fetch 2307 * 2308 * @return the value pointed to by var. 2309 */ 2310 2311 #ifdef GCC_ATOMIC_FUNCTIONS 2312 static inline int16_t atomic_fetch_int16_t(int16_t *var) 2313 { 2314 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2315 } 2316 #elif defined(GCC_SYNC_FUNCTIONS) 2317 static inline int16_t atomic_fetch_int16_t(int16_t *var) 2318 { 2319 return __sync_fetch_and_add(var, 0); 2320 } 2321 #endif 2322 2323 /** 2324 * @brief Atomically store an int16_t 2325 * 2326 * This function atomically fetches the value indicated by the 2327 * supplied pointer. 2328 * 2329 * @param[in,out] var Pointer to the variable to modify 2330 * @param[in] val The value to store 2331 */ 2332 2333 #ifdef GCC_ATOMIC_FUNCTIONS 2334 static inline void atomic_store_int16_t(int16_t *var, int16_t val) 2335 { 2336 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2337 } 2338 #elif defined(GCC_SYNC_FUNCTIONS) 2339 static inline void atomic_store_int16_t(int16_t *var, int16_t val) 2340 { 2341 (void)__sync_lock_test_and_set(var, val); 2342 } 2343 #endif 2344 2345 /** 2346 * @brief Atomically fetch a uint16_t 2347 * 2348 * This function atomically fetches the value indicated by the 2349 * supplied pointer. 2350 * 2351 * @param[in,out] var Pointer to the variable to fetch 2352 * 2353 * @return the value pointed to by var. 2354 */ 2355 2356 #ifdef GCC_ATOMIC_FUNCTIONS 2357 static inline uint16_t atomic_fetch_uint16_t(uint16_t *var) 2358 { 2359 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2360 } 2361 #elif defined(GCC_SYNC_FUNCTIONS) 2362 static inline uint16_t atomic_fetch_uint16_t(uint16_t *var) 2363 { 2364 return __sync_fetch_and_add(var, 0); 2365 } 2366 #endif 2367 2368 /** 2369 * @brief Atomically store a uint16_t 2370 * 2371 * This function atomically fetches the value indicated by the 2372 * supplied pointer. 2373 * 2374 * @param[in,out] var Pointer to the variable to modify 2375 * @param[in] val The value to store 2376 */ 2377 2378 #ifdef GCC_ATOMIC_FUNCTIONS 2379 static inline void atomic_store_uint16_t(uint16_t *var, uint16_t val) 2380 { 2381 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2382 } 2383 #elif defined(GCC_SYNC_FUNCTIONS) 2384 static inline void atomic_store_uint16_t(uint16_t *var, uint16_t val) 2385 { 2386 (void)__sync_lock_test_and_set(var, val); 2387 } 2388 #endif 2389 2390 /** 2391 * @brief Atomically fetch a int8_t 2392 * 2393 * This function atomically fetches the value indicated by the 2394 * supplied pointer. 2395 * 2396 * @param[in,out] var Pointer to the variable to fetch 2397 * 2398 * @return the value pointed to by var. 2399 */ 2400 2401 #ifdef GCC_ATOMIC_FUNCTIONS 2402 static inline int8_t atomic_fetch_int8_t(int8_t *var) 2403 { 2404 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2405 } 2406 #elif defined(GCC_SYNC_FUNCTIONS) 2407 static inline int8_t atomic_fetch_int8_t(int8_t *var) 2408 { 2409 return __sync_fetch_and_add(var, 0); 2410 } 2411 #endif 2412 2413 /** 2414 * @brief Atomically store a int8_t 2415 * 2416 * This function atomically fetches the value indicated by the 2417 * supplied pointer. 2418 * 2419 * @param[in,out] var Pointer to the variable to modify 2420 * @param[in] val The value to store 2421 */ 2422 2423 #ifdef GCC_ATOMIC_FUNCTIONS 2424 static inline void atomic_store_int8_t(int8_t *var, int8_t val) 2425 { 2426 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2427 } 2428 #elif defined(GCC_SYNC_FUNCTIONS) 2429 static inline void atomic_store_int8_t(int8_t *var, int8_t val) 2430 { 2431 (void)__sync_lock_test_and_set(var, val); 2432 } 2433 #endif 2434 2435 /** 2436 * @brief Atomically fetch a uint8_t 2437 * 2438 * This function atomically fetches the value indicated by the 2439 * supplied pointer. 2440 * 2441 * @param[in,out] var Pointer to the variable to fetch 2442 * 2443 * @return the value pointed to by var. 2444 */ 2445 2446 #ifdef GCC_ATOMIC_FUNCTIONS 2447 static inline uint8_t atomic_fetch_uint8_t(uint8_t *var) 2448 { 2449 return __atomic_load_n(var, __ATOMIC_SEQ_CST); 2450 } 2451 #elif defined(GCC_SYNC_FUNCTIONS) 2452 static inline uint8_t atomic_fetch_uint8_t(uint8_t *var) 2453 { 2454 return __sync_fetch_and_add(var, 0); 2455 } 2456 #endif 2457 2458 /** 2459 * @brief Atomically store a uint8_t 2460 * 2461 * This function atomically fetches the value indicated by the 2462 * supplied pointer. 2463 * 2464 * @param[in,out] var Pointer to the variable to modify 2465 * @param[in] val The value to store 2466 */ 2467 2468 #ifdef GCC_ATOMIC_FUNCTIONS 2469 static inline void atomic_store_uint8_t(uint8_t *var, uint8_t val) 2470 { 2471 __atomic_store_n(var, val, __ATOMIC_SEQ_CST); 2472 } 2473 #elif defined(GCC_SYNC_FUNCTIONS) 2474 static inline void atomic_store_uint8_t(uint8_t *var, uint8_t val) 2475 { 2476 (void)__sync_lock_test_and_set(var, val); 2477 } 2478 #endif 2479 #endif /* !_ABSTRACT_ATOMIC_H */
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™