/contrib/bind9/lib/isc/ia64/include/isc/atomic.h

https://bitbucket.org/freebsd/freebsd-head/ · C Header · 100 lines · 57 code · 12 blank · 31 comment · 3 complexity · 1c787fef15eca0cf25e3024a7a095fb4 MD5 · raw file

  1. /*
  2. * Copyright (C) 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /* $Id: atomic.h,v 1.7 2009/06/24 02:22:50 marka Exp $ */
  17. #ifndef ISC_ATOMIC_H
  18. #define ISC_ATOMIC_H 1
  19. #include <isc/platform.h>
  20. #include <isc/types.h>
  21. #ifdef ISC_PLATFORM_USEGCCASM
  22. /*
  23. * This routine atomically increments the value stored in 'p' by 'val', and
  24. * returns the previous value.
  25. *
  26. * Open issue: can 'fetchadd' make the code faster for some particular values
  27. * (e.g., 1 and -1)?
  28. */
  29. static inline isc_int32_t
  30. #ifdef __GNUC__
  31. __attribute__ ((unused))
  32. #endif
  33. isc_atomic_xadd(isc_int32_t *p, isc_int32_t val)
  34. {
  35. isc_int32_t prev, swapped;
  36. for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
  37. swapped = prev + val;
  38. __asm__ volatile(
  39. "mov ar.ccv=%2;;"
  40. "cmpxchg4.acq %0=%4,%3,ar.ccv"
  41. : "=r" (swapped), "=m" (*p)
  42. : "r" (prev), "r" (swapped), "m" (*p)
  43. : "memory");
  44. if (swapped == prev)
  45. break;
  46. }
  47. return (prev);
  48. }
  49. /*
  50. * This routine atomically stores the value 'val' in 'p'.
  51. */
  52. static inline void
  53. #ifdef __GNUC__
  54. __attribute__ ((unused))
  55. #endif
  56. isc_atomic_store(isc_int32_t *p, isc_int32_t val)
  57. {
  58. __asm__ volatile(
  59. "st4.rel %0=%1"
  60. : "=m" (*p)
  61. : "r" (val)
  62. : "memory"
  63. );
  64. }
  65. /*
  66. * This routine atomically replaces the value in 'p' with 'val', if the
  67. * original value is equal to 'cmpval'. The original value is returned in any
  68. * case.
  69. */
  70. static inline isc_int32_t
  71. #ifdef __GNUC__
  72. __attribute__ ((unused))
  73. #endif
  74. isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val)
  75. {
  76. isc_int32_t ret;
  77. __asm__ volatile(
  78. "mov ar.ccv=%2;;"
  79. "cmpxchg4.acq %0=%4,%3,ar.ccv"
  80. : "=r" (ret), "=m" (*p)
  81. : "r" (cmpval), "r" (val), "m" (*p)
  82. : "memory");
  83. return (ret);
  84. }
  85. #else /* !ISC_PLATFORM_USEGCCASM */
  86. #error "unsupported compiler. disable atomic ops by --disable-atomic"
  87. #endif
  88. #endif /* ISC_ATOMIC_H */