1/*	$OpenBSD: _atomic_lock.c,v 1.2 2022/12/27 17:10:06 jmc Exp $	*/
2/*
3 * Copyright (c) 2020	Mars Li <mengshi.li.mars@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*
19 * Atomic lock for riscv64
20 */
21
22#include <sys/types.h>
23#include <machine/spinlock.h>
24
25/*
26 * Spinlock does not have Acquire/Release semantics, so amoswap.w.aq
27 * should not used here.
28 */
29int
30_atomic_lock(volatile _atomic_lock_t *lock)
31{
32	_atomic_lock_t old;
33
34	/*
35	 * Use the amoswap instruction to swap the lock value with
36	 * a local variable containing the locked state.
37	 */
38	__asm__("amoswap.w %0, %1, (%2)"
39		: "=r" (old)
40		: "r" (_ATOMIC_LOCK_LOCKED), "r"  (lock) : "memory");
41
42	return (old != _ATOMIC_LOCK_UNLOCKED);
43}
44