12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- #pragma once
- #include <stdint.h>
- inline void spin_lock(uint32_t volatile* lock_addr)
- {
- asm volatile(
- "%=:\n\t\
- movl $1, %%eax\n\t\
- xchgl %%eax, (%0)\n\t\
- test $0, %%eax\n\t\
- jne %=b\n\t\
- "
- :
- : "r"(lock_addr)
- : "eax", "memory");
- }
- inline void spin_unlock(uint32_t volatile* lock_addr)
- {
- asm volatile(
- "movl $0, %%eax\n\
- xchgl %%eax, (%0)"
- :
- : "r"(lock_addr)
- : "eax", "memory");
- }
- namespace types {
- struct mutex {
- using mtx_t = volatile uint32_t;
- mtx_t m_lock = 0;
- inline void lock(void)
- {
- spin_lock(&m_lock);
- }
- inline void unlock(void)
- {
- spin_unlock(&m_lock);
- }
- };
- class lock_guard {
- private:
- mutex& m_mtx;
- public:
- explicit lock_guard(mutex& mtx)
- : m_mtx(mtx)
- {
- mtx.lock();
- }
- lock_guard(const lock_guard&) = delete;
- lock_guard(lock_guard&&) = delete;
- ~lock_guard()
- {
- m_mtx.unlock();
- }
- };
- } // namespace types
|