starpu_spinlock.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. *
  5. * StarPU is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * StarPU is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #ifndef __STARPU_SPINLOCK_H__
  17. #define __STARPU_SPINLOCK_H__
  18. /** @file */
  19. #include <errno.h>
  20. #include <stdint.h>
  21. #include <common/config.h>
  22. #include <common/fxt.h>
  23. #include <common/thread.h>
  24. #include <starpu.h>
  25. #ifdef STARPU_SPINLOCK_CHECK
  26. /* We don't care about performance */
  27. struct _starpu_spinlock
  28. {
  29. starpu_pthread_mutex_t errcheck_lock;
  30. const char *last_taker;
  31. };
  32. int _starpu_spin_init(struct _starpu_spinlock *lock);
  33. int _starpu_spin_destroy(struct _starpu_spinlock *lock);
  34. static inline int __starpu_spin_lock(struct _starpu_spinlock *lock, const char *file STARPU_ATTRIBUTE_UNUSED, int line STARPU_ATTRIBUTE_UNUSED, const char *func STARPU_ATTRIBUTE_UNUSED)
  35. {
  36. _STARPU_TRACE_LOCKING_SPINLOCK(file, line);
  37. int ret = starpu_pthread_mutex_lock(&lock->errcheck_lock);
  38. STARPU_ASSERT(!ret);
  39. lock->last_taker = func;
  40. _STARPU_TRACE_SPINLOCK_LOCKED(file, line);
  41. return ret;
  42. }
  43. static inline void _starpu_spin_checklocked(struct _starpu_spinlock *lock STARPU_ATTRIBUTE_UNUSED)
  44. {
  45. STARPU_ASSERT(starpu_pthread_mutex_trylock(&lock->errcheck_lock) != 0);
  46. }
  47. static inline int __starpu_spin_trylock(struct _starpu_spinlock *lock, const char *file STARPU_ATTRIBUTE_UNUSED, int line STARPU_ATTRIBUTE_UNUSED, const char *func STARPU_ATTRIBUTE_UNUSED)
  48. {
  49. _STARPU_TRACE_TRYLOCK_SPINLOCK(file, line);
  50. int ret = starpu_pthread_mutex_trylock(&lock->errcheck_lock);
  51. STARPU_ASSERT(!ret || (ret == EBUSY));
  52. if (STARPU_LIKELY(!ret))
  53. {
  54. lock->last_taker = func;
  55. _STARPU_TRACE_SPINLOCK_LOCKED(file, line);
  56. }
  57. return ret;
  58. }
  59. static inline int __starpu_spin_unlock(struct _starpu_spinlock *lock, const char *file STARPU_ATTRIBUTE_UNUSED, int line STARPU_ATTRIBUTE_UNUSED, const char *func STARPU_ATTRIBUTE_UNUSED)
  60. {
  61. _STARPU_TRACE_UNLOCKING_SPINLOCK(file, line);
  62. int ret = starpu_pthread_mutex_unlock(&lock->errcheck_lock);
  63. STARPU_ASSERT(!ret);
  64. _STARPU_TRACE_SPINLOCK_UNLOCKED(file, line);
  65. return ret;
  66. }
  67. #else
  68. /* We do care about performance, inline as much as possible */
  69. struct _starpu_spinlock
  70. {
  71. starpu_pthread_spinlock_t lock;
  72. };
  73. static inline int _starpu_spin_init(struct _starpu_spinlock *lock)
  74. {
  75. int ret = starpu_pthread_spin_init(&lock->lock, 0);
  76. STARPU_ASSERT(!ret);
  77. return ret;
  78. }
  79. #define _starpu_spin_destroy(_lock) starpu_pthread_spin_destroy(&(_lock)->lock)
  80. static inline int __starpu_spin_lock(struct _starpu_spinlock *lock, const char *file STARPU_ATTRIBUTE_UNUSED, int line STARPU_ATTRIBUTE_UNUSED, const char *func STARPU_ATTRIBUTE_UNUSED)
  81. {
  82. _STARPU_TRACE_LOCKING_SPINLOCK(file, line);
  83. int ret = starpu_pthread_spin_lock(&lock->lock);
  84. STARPU_ASSERT(!ret);
  85. _STARPU_TRACE_SPINLOCK_LOCKED(file, line);
  86. return ret;
  87. }
  88. #define _starpu_spin_checklocked(_lock) _starpu_pthread_spin_checklocked(&(_lock)->lock)
  89. static inline int __starpu_spin_trylock(struct _starpu_spinlock *lock, const char *file STARPU_ATTRIBUTE_UNUSED, int line STARPU_ATTRIBUTE_UNUSED, const char *func STARPU_ATTRIBUTE_UNUSED)
  90. {
  91. _STARPU_TRACE_TRYLOCK_SPINLOCK(file, line);
  92. int ret = starpu_pthread_spin_trylock(&lock->lock);
  93. STARPU_ASSERT(!ret || (ret == EBUSY));
  94. if (STARPU_LIKELY(!ret))
  95. _STARPU_TRACE_SPINLOCK_LOCKED(file, line);
  96. return ret;
  97. }
  98. static inline int __starpu_spin_unlock(struct _starpu_spinlock *lock, const char *file STARPU_ATTRIBUTE_UNUSED, int line STARPU_ATTRIBUTE_UNUSED, const char *func STARPU_ATTRIBUTE_UNUSED)
  99. {
  100. _STARPU_TRACE_UNLOCKING_SPINLOCK(file, line);
  101. int ret = starpu_pthread_spin_unlock(&lock->lock);
  102. STARPU_ASSERT(!ret);
  103. _STARPU_TRACE_SPINLOCK_UNLOCKED(file, line);
  104. return ret;
  105. }
  106. #endif
  107. #define _starpu_spin_lock(lock) \
  108. __starpu_spin_lock(lock, __FILE__, __LINE__, __starpu_func__)
  109. #define _starpu_spin_trylock(lock) \
  110. __starpu_spin_trylock(lock, __FILE__, __LINE__, __starpu_func__)
  111. #define _starpu_spin_unlock(lock) \
  112. __starpu_spin_unlock(lock, __FILE__, __LINE__, __starpu_func__)
  113. #define STARPU_SPIN_MAXTRY 10
  114. #endif // __STARPU_SPINLOCK_H__