lock.hpp 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #pragma once
  2. #include <stdint.h>
  3. inline void spin_lock(uint32_t volatile* lock_addr)
  4. {
  5. asm volatile(
  6. "%=:\n\t\
  7. movl $1, %%eax\n\t\
  8. xchgl %%eax, (%0)\n\t\
  9. test $0, %%eax\n\t\
  10. jne %=b\n\t\
  11. "
  12. :
  13. : "r"(lock_addr)
  14. : "eax", "memory");
  15. }
  16. inline void spin_unlock(uint32_t volatile* lock_addr)
  17. {
  18. asm volatile(
  19. "movl $0, %%eax\n\
  20. xchgl %%eax, (%0)"
  21. :
  22. : "r"(lock_addr)
  23. : "eax", "memory");
  24. }
  25. namespace types {
  26. struct mutex {
  27. using mtx_t = volatile uint32_t;
  28. mtx_t m_lock = 0;
  29. inline void lock(void)
  30. {
  31. spin_lock(&m_lock);
  32. }
  33. inline void unlock(void)
  34. {
  35. spin_unlock(&m_lock);
  36. }
  37. };
  38. class lock_guard {
  39. private:
  40. mutex& m_mtx;
  41. public:
  42. explicit lock_guard(mutex& mtx)
  43. : m_mtx(mtx)
  44. {
  45. mtx.lock();
  46. }
  47. lock_guard(const lock_guard&) = delete;
  48. lock_guard(lock_guard&&) = delete;
  49. ~lock_guard()
  50. {
  51. m_mtx.unlock();
  52. }
  53. };
  54. } // namespace types