arch/arm64/include/asm/atomic_lse.h

Source file repositories/reference/linux-study-clean/arch/arm64/include/asm/atomic_lse.h

File Facts

System
Linux kernel
Corpus path
arch/arm64/include/asm/atomic_lse.h
Extension
.h
Size
8287 bytes
Lines
316
Domain
Architecture Layer
Bucket
arch/arm64
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef __ASM_ATOMIC_LSE_H
#define __ASM_ATOMIC_LSE_H

#define ATOMIC_OP(op, asm_op)						\
static __always_inline void						\
__lse_atomic_##op(int i, atomic_t *v)					\
{									\
	asm volatile(							\
	__LSE_PREAMBLE							\
	"	" #asm_op "	%w[i], %[v]\n"				\
	: [v] "+Q" (v->counter)						\
	: [i] "r" (i));							\
}

ATOMIC_OP(andnot, stclr)
ATOMIC_OP(or, stset)
ATOMIC_OP(xor, steor)
ATOMIC_OP(add, stadd)

static __always_inline void __lse_atomic_sub(int i, atomic_t *v)
{
	__lse_atomic_add(-i, v);
}

#undef ATOMIC_OP

#define ATOMIC_FETCH_OP(name, mb, op, asm_op, cl...)			\
static __always_inline int						\
__lse_atomic_fetch_##op##name(int i, atomic_t *v)			\
{									\
	int old;							\
									\
	asm volatile(							\
	__LSE_PREAMBLE							\
	"	" #asm_op #mb "	%w[i], %w[old], %[v]"			\
	: [v] "+Q" (v->counter),					\
	  [old] "=r" (old)						\
	: [i] "r" (i)							\
	: cl);								\
									\
	return old;							\
}

#define ATOMIC_FETCH_OPS(op, asm_op)					\
	ATOMIC_FETCH_OP(_relaxed,   , op, asm_op)			\
	ATOMIC_FETCH_OP(_acquire,  a, op, asm_op, "memory")		\
	ATOMIC_FETCH_OP(_release,  l, op, asm_op, "memory")		\
	ATOMIC_FETCH_OP(        , al, op, asm_op, "memory")

ATOMIC_FETCH_OPS(andnot, ldclr)
ATOMIC_FETCH_OPS(or, ldset)
ATOMIC_FETCH_OPS(xor, ldeor)
ATOMIC_FETCH_OPS(add, ldadd)

#undef ATOMIC_FETCH_OP
#undef ATOMIC_FETCH_OPS

#define ATOMIC_FETCH_OP_SUB(name)					\
static __always_inline int						\
__lse_atomic_fetch_sub##name(int i, atomic_t *v)			\
{									\
	return __lse_atomic_fetch_add##name(-i, v);			\
}

ATOMIC_FETCH_OP_SUB(_relaxed)
ATOMIC_FETCH_OP_SUB(_acquire)
ATOMIC_FETCH_OP_SUB(_release)
ATOMIC_FETCH_OP_SUB(        )

#undef ATOMIC_FETCH_OP_SUB

#define ATOMIC_OP_ADD_SUB_RETURN(name)					\
static __always_inline int						\
__lse_atomic_add_return##name(int i, atomic_t *v)			\
{									\
	return __lse_atomic_fetch_add##name(i, v) + i;			\
}									\
									\
static __always_inline int						\
__lse_atomic_sub_return##name(int i, atomic_t *v)			\
{									\
	return __lse_atomic_fetch_sub(i, v) - i;			\
}

ATOMIC_OP_ADD_SUB_RETURN(_relaxed)
ATOMIC_OP_ADD_SUB_RETURN(_acquire)
ATOMIC_OP_ADD_SUB_RETURN(_release)
ATOMIC_OP_ADD_SUB_RETURN(        )

#undef ATOMIC_OP_ADD_SUB_RETURN

Annotation

Implementation Notes