recursive_spin_lock.h 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #pragma once
  2. #include "public.h"
  3. #include "spin_lock_base.h"
  4. #include "spin_lock_count.h"
  5. #include <library/cpp/yt/system/thread_id.h>
  6. #include <util/system/types.h>
  7. #include <atomic>
  8. namespace NYT::NThreading {
  9. ////////////////////////////////////////////////////////////////////////////////
  10. //! A counterpart of #TSpinLock that can be acquired from a single thread multiple times.
  11. class TRecursiveSpinLock
  12. : public TSpinLockBase
  13. {
  14. public:
  15. using TSpinLockBase::TSpinLockBase;
  16. void Acquire() noexcept;
  17. bool TryAcquire() noexcept;
  18. void Release() noexcept;
  19. bool IsLocked() const noexcept;
  20. bool IsLockedByCurrentThread() const noexcept;
  21. private:
  22. // Bits 0..31: recursion depth; if zero then the lock is not taken,
  23. // thread id can be arbitrary
  24. // Bits 32..63: id of the thread owning the lock
  25. using TValue = ui64;
  26. std::atomic<TValue> Value_ = 0;
  27. static constexpr int ThreadIdShift = 32;
  28. static constexpr TValue RecursionDepthMask = (1ULL << ThreadIdShift) - 1;
  29. static_assert(sizeof(TSequentialThreadId) == 4);
  30. bool TryAndTryAcquire() noexcept;
  31. void AcquireSlow() noexcept;
  32. };
  33. REGISTER_TRACKED_SPIN_LOCK_CLASS(TRecursiveSpinLock)
  34. ////////////////////////////////////////////////////////////////////////////////
  35. } // namespace NYT::NThreading
  36. #define RECURSIVE_SPIN_LOCK_INL_H_
  37. #include "recursive_spin_lock-inl.h"
  38. #undef RECURSIVE_SPIN_LOCK_INL_H_