include/asm-generic/atomic.h

Source file repositories/reference/linux-study-clean/include/asm-generic/atomic.h

File Facts

System
Linux kernel
Corpus path
include/asm-generic/atomic.h
Extension
.h
Size
3413 bytes
Lines
134
Domain
Repository Root And Misc
Bucket
include
Inferred role
Repository Root And Misc: implementation source
Status
source implementation candidate

Why This File Exists

Top-level or miscellaneous repository surface. Use this as map coverage unless a later manual pass promotes the file into a deeper subsystem dossier.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef __ASM_GENERIC_ATOMIC_H
#define __ASM_GENERIC_ATOMIC_H

#include <asm/cmpxchg.h>
#include <asm/barrier.h>

#ifdef CONFIG_SMP

/* we can build all atomic primitives from cmpxchg */

#define ATOMIC_OP(op, c_op)						\
static inline void generic_atomic_##op(int i, atomic_t *v)		\
{									\
	int c, old;							\
									\
	c = v->counter;							\
	while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c)	\
		c = old;						\
}

#define ATOMIC_OP_RETURN(op, c_op)					\
static inline int generic_atomic_##op##_return(int i, atomic_t *v)	\
{									\
	int c, old;							\
									\
	c = v->counter;							\
	while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c)	\
		c = old;						\
									\
	return c c_op i;						\
}

#define ATOMIC_FETCH_OP(op, c_op)					\
static inline int generic_atomic_fetch_##op(int i, atomic_t *v)		\
{									\
	int c, old;							\
									\
	c = v->counter;							\
	while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c)	\
		c = old;						\
									\
	return c;							\
}

#else

#include <linux/irqflags.h>

#define ATOMIC_OP(op, c_op)						\
static inline void generic_atomic_##op(int i, atomic_t *v)		\
{									\
	unsigned long flags;						\
									\
	raw_local_irq_save(flags);					\
	v->counter = v->counter c_op i;					\
	raw_local_irq_restore(flags);					\
}

#define ATOMIC_OP_RETURN(op, c_op)					\
static inline int generic_atomic_##op##_return(int i, atomic_t *v)	\
{									\
	unsigned long flags;						\
	int ret;							\
									\
	raw_local_irq_save(flags);					\
	ret = (v->counter = v->counter c_op i);				\
	raw_local_irq_restore(flags);					\
									\
	return ret;							\
}

#define ATOMIC_FETCH_OP(op, c_op)					\
static inline int generic_atomic_fetch_##op(int i, atomic_t *v)		\
{									\
	unsigned long flags;						\
	int ret;							\
									\
	raw_local_irq_save(flags);					\
	ret = v->counter;						\
	v->counter = v->counter c_op i;					\
	raw_local_irq_restore(flags);					\
									\
	return ret;							\
}

#endif /* CONFIG_SMP */

ATOMIC_OP_RETURN(add, +)
ATOMIC_OP_RETURN(sub, -)

Annotation

Implementation Notes