12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- #pragma once
- #include <common/glib.h>
- #include <process/preempt.h>
- typedef struct
- {
- __volatile__ char lock;
- } spinlock_t;
- void spin_init(spinlock_t *lock)
- {
- lock->lock = 1;
- }
- void spin_lock(spinlock_t *lock)
- {
- preempt_disable();
- __asm__ __volatile__("1: \n\t"
- "lock decq %0 \n\t"
- "jns 3f \n\t"
- "2: \n\t"
- "pause \n\t"
- "cmpq $0, %0 \n\t"
- "jle 2b \n\t"
- "jmp 1b \n\t"
- "3:"
- : "=m"(lock->lock)::"memory");
- }
- void spin_unlock(spinlock_t *lock)
- {
- __asm__ __volatile__("movq $1, %0 \n\t"
- : "=m"(lock->lock)::"memory");
- preempt_enable();
- }
- long spin_trylock(spinlock_t *lock)
- {
- uint64_t tmp_val = 0;
- preempt_disable();
-
- asm volatile("lock xchgq %0, %1 \n\t"
- : "=q"(tmp_val), "=m"(lock->lock)
- : "0"(0)
- : "memory");
- if (!tmp_val)
- preempt_enable();
- return tmp_val;
- }
|