spin_lock_count.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #pragma once
  2. #define SPIN_LOCK_COUNT_INL_H_
  3. #include "spin_lock_count-inl.h"
  4. #undef SPIN_LOCK_COUNT_INL_H_
  5. namespace NYT::NThreading {
  6. // Tracks the number of spinlocks currently held by the thread.
  7. // Generally useful to ensure that we are not holding a spinlock
  8. // in a given context.
  9. // Tracking is only active in debug builds.
  10. ////////////////////////////////////////////////////////////////////////////////
  11. namespace NDetail {
  12. // In order to properly support tracking in your spinlock you have to do two steps:
  13. // 1) Insert RecordSpinlockAcquired and RecordSpinlockReleased inside your
  14. // (Try)Acquire and Release calls.
  15. // 2) (Optional) Write REGISTER_TRACKED_SPIN_LOCK_CLASS(TSpinLock) for your spinlock
  16. // so that you can use algorithms aware of spinlock tracking.
  17. using NPrivate::RecordSpinLockAcquired;
  18. using NPrivate::RecordSpinLockReleased;
  19. template <class TSpinLock>
  20. struct TIsTrackedSpinLock
  21. : public std::false_type
  22. { };
  23. #define REGISTER_TRACKED_SPIN_LOCK_CLASS(Name) \
  24. namespace NDetail { \
  25. \
  26. template <> \
  27. struct TIsTrackedSpinLock<Name> \
  28. : public std::true_type \
  29. { }; \
  30. \
  31. } \
  32. } // namespace NDetail
  33. ////////////////////////////////////////////////////////////////////////////////
  34. template <class T>
  35. concept CTrackedSpinLock = NDetail::TIsTrackedSpinLock<T>::value;
  36. //! Semantic requirements:
  37. //! 1) T must have a method successful call to which begins critical section (e.g. Acquire).
  38. //! 2) T must have a method successful call to which ends critical section (e.g. Release).
  39. //! In (1) and (2) "successful" is expected to have a definition given by T's author.
  40. //! 3) Beggining of a critical section CS must be sequenced before RecordSpinlockAcquired(true) call.
  41. //! 4) RecordSpinlockAcquired(true) call must be sequenced before RecordSpinlockReleased() call.
  42. //! 5) RecordSpinlockReleased() must be sequenced before the ending of the CS.
  43. ////////////////////////////////////////////////////////////////////////////////
  44. using NPrivate::VerifyNoSpinLockAffinity;
  45. ////////////////////////////////////////////////////////////////////////////////
  46. } // namespace NYT::NThreading