kernel: Improve spinlock implementation
atomic_or() and atomic_and() are not supported by x86 are need to be emulated using CAS. Use atomic_get_and_set() and atomic_set() instead.
This commit is contained in:
@@ -76,7 +76,7 @@ int smp_intercpu_int_handler(int32 cpu);
|
|||||||
static inline bool
|
static inline bool
|
||||||
try_acquire_spinlock_inline(spinlock* lock)
|
try_acquire_spinlock_inline(spinlock* lock)
|
||||||
{
|
{
|
||||||
return atomic_or((int32*)lock, 1) == 0;
|
return atomic_get_and_set((int32*)lock, 1) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ acquire_spinlock_inline(spinlock* lock)
|
|||||||
static inline void
|
static inline void
|
||||||
release_spinlock_inline(spinlock* lock)
|
release_spinlock_inline(spinlock* lock)
|
||||||
{
|
{
|
||||||
atomic_and((int32*)lock, 0);
|
atomic_set((int32*)lock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+12
-10
@@ -313,7 +313,7 @@ try_acquire_spinlock(spinlock* lock)
|
|||||||
if (atomic_add(&lock->lock, 1) != 0)
|
if (atomic_add(&lock->lock, 1) != 0)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
if (atomic_or((int32*)lock, 1) != 0)
|
if (atomic_get_and_set((int32*)lock, 1) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
# if DEBUG_SPINLOCKS
|
# if DEBUG_SPINLOCKS
|
||||||
@@ -353,7 +353,7 @@ acquire_spinlock(spinlock* lock)
|
|||||||
process_all_pending_ici(currentCPU);
|
process_all_pending_ici(currentCPU);
|
||||||
PAUSE();
|
PAUSE();
|
||||||
}
|
}
|
||||||
if (atomic_or((int32*)lock, 1) == 0)
|
if (atomic_get_and_set((int32*)lock, 1) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ acquire_spinlock(spinlock* lock)
|
|||||||
} else {
|
} else {
|
||||||
#if DEBUG_SPINLOCKS
|
#if DEBUG_SPINLOCKS
|
||||||
int32 oldValue;
|
int32 oldValue;
|
||||||
oldValue = atomic_or((int32*)lock, 1);
|
oldValue = atomic_get_and_set((int32*)lock, 1);
|
||||||
if (oldValue != 0) {
|
if (oldValue != 0) {
|
||||||
panic("acquire_spinlock: attempt to acquire lock %p twice on "
|
panic("acquire_spinlock: attempt to acquire lock %p twice on "
|
||||||
"non-SMP system (last caller: %p, value %" B_PRId32 ")", lock,
|
"non-SMP system (last caller: %p, value %" B_PRId32 ")", lock,
|
||||||
@@ -407,13 +407,13 @@ acquire_spinlock_nocheck(spinlock *lock)
|
|||||||
PAUSE();
|
PAUSE();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_or((int32*)lock, 1) == 0)
|
if (atomic_get_and_set((int32*)lock, 1) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if DEBUG_SPINLOCKS
|
#if DEBUG_SPINLOCKS
|
||||||
if (atomic_or((int32*)lock, 1) != 0) {
|
if (atomic_get_and_set((int32*)lock, 1) != 0) {
|
||||||
panic("acquire_spinlock_nocheck: attempt to acquire lock %p twice "
|
panic("acquire_spinlock_nocheck: attempt to acquire lock %p twice "
|
||||||
"on non-SMP system\n", lock);
|
"on non-SMP system\n", lock);
|
||||||
}
|
}
|
||||||
@@ -450,7 +450,7 @@ acquire_spinlock_cpu(int32 currentCPU, spinlock *lock)
|
|||||||
process_all_pending_ici(currentCPU);
|
process_all_pending_ici(currentCPU);
|
||||||
PAUSE();
|
PAUSE();
|
||||||
}
|
}
|
||||||
if (atomic_or((int32*)lock, 1) == 0)
|
if (atomic_get_and_set((int32*)lock, 1) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +461,7 @@ acquire_spinlock_cpu(int32 currentCPU, spinlock *lock)
|
|||||||
} else {
|
} else {
|
||||||
#if DEBUG_SPINLOCKS
|
#if DEBUG_SPINLOCKS
|
||||||
int32 oldValue;
|
int32 oldValue;
|
||||||
oldValue = atomic_or((int32*)lock, 1);
|
oldValue = atomic_get_and_set((int32*)lock, 1);
|
||||||
if (oldValue != 0) {
|
if (oldValue != 0) {
|
||||||
panic("acquire_spinlock_cpu(): attempt to acquire lock %p twice on "
|
panic("acquire_spinlock_cpu(): attempt to acquire lock %p twice on "
|
||||||
"non-SMP system (last caller: %p, value %" B_PRId32 ")", lock,
|
"non-SMP system (last caller: %p, value %" B_PRId32 ")", lock,
|
||||||
@@ -498,9 +498,11 @@ release_spinlock(spinlock *lock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#elif DEBUG_SPINLOCKS
|
||||||
if (atomic_and((int32*)lock, 0) != 1)
|
if (atomic_get_and_set((int32*)lock, 0) != 1)
|
||||||
panic("release_spinlock: lock %p was already released\n", lock);
|
panic("release_spinlock: lock %p was already released\n", lock);
|
||||||
|
#else
|
||||||
|
atomic_set((int32*)lock, 0);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if DEBUG_SPINLOCKS
|
#if DEBUG_SPINLOCKS
|
||||||
@@ -508,7 +510,7 @@ release_spinlock(spinlock *lock)
|
|||||||
panic("release_spinlock: attempt to release lock %p with "
|
panic("release_spinlock: attempt to release lock %p with "
|
||||||
"interrupts enabled\n", lock);
|
"interrupts enabled\n", lock);
|
||||||
}
|
}
|
||||||
if (atomic_and((int32*)lock, 0) != 1)
|
if (atomic_get_and_set((int32*)lock, 0) != 1)
|
||||||
panic("release_spinlock: lock %p was already released\n", lock);
|
panic("release_spinlock: lock %p was already released\n", lock);
|
||||||
#endif
|
#endif
|
||||||
#if DEBUG_SPINLOCK_LATENCIES
|
#if DEBUG_SPINLOCK_LATENCIES
|
||||||
|
|||||||
Reference in New Issue
Block a user