blob: 4e8b03f28ef9373bbb76cd1b971ebc5954c53307 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <arch/spinlock.h>
#include <arch/arch_ops.h>
void arch_spin_lock(spin_lock_t *lock) TA_NO_THREAD_SAFETY_ANALYSIS {
unsigned long val = arch_curr_cpu_num() + 1;
unsigned long expected = 0;
while(unlikely(!__atomic_compare_exchange_n(&lock->value, &expected, val, false,
__ATOMIC_ACQUIRE, __ATOMIC_RELAXED))) {
expected = 0;
do {
arch_spinloop_pause();
} while (unlikely(__atomic_load_n(&lock->value, __ATOMIC_RELAXED) != 0));
}
}
int arch_spin_trylock(spin_lock_t* lock) TA_NO_THREAD_SAFETY_ANALYSIS {
unsigned long val = arch_curr_cpu_num() + 1;
unsigned long expected = 0;
__atomic_compare_exchange_n(&lock->value, &expected, val, false, __ATOMIC_ACQUIRE,
__ATOMIC_RELAXED);
return static_cast<int>(expected);
}
void arch_spin_unlock(spin_lock_t* lock) TA_NO_THREAD_SAFETY_ANALYSIS {
__atomic_store_n(&lock->value, 0UL, __ATOMIC_RELEASE);
}