brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · 22142c7 Raw
134 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * Generic C implementation of atomic counter operations. Do not include in4 * machine independent code.5 *6 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.7 * Written by David Howells (dhowells@redhat.com)8 */9#ifndef __ASM_GENERIC_ATOMIC_H10#define __ASM_GENERIC_ATOMIC_H11 12#include <asm/cmpxchg.h>13#include <asm/barrier.h>14 15#ifdef CONFIG_SMP16 17/* we can build all atomic primitives from cmpxchg */18 19#define ATOMIC_OP(op, c_op)						\20static inline void generic_atomic_##op(int i, atomic_t *v)		\21{									\22	int c, old;							\23									\24	c = v->counter;							\25	while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c)	\26		c = old;						\27}28 29#define ATOMIC_OP_RETURN(op, c_op)					\30static inline int generic_atomic_##op##_return(int i, atomic_t *v)	\31{									\32	int c, old;							\33									\34	c = v->counter;							\35	while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c)	\36		c = old;						\37									\38	return c c_op i;						\39}40 41#define ATOMIC_FETCH_OP(op, c_op)					\42static inline int generic_atomic_fetch_##op(int i, atomic_t *v)		\43{									\44	int c, old;							\45									\46	c = v->counter;							\47	while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c)	\48		c = old;						\49									\50	return c;							\51}52 53#else54 55#include <linux/irqflags.h>56 57#define ATOMIC_OP(op, c_op)						\58static inline void generic_atomic_##op(int i, atomic_t *v)		\59{									\60	unsigned long flags;						\61									\62	raw_local_irq_save(flags);					\63	v->counter = v->counter c_op i;					\64	raw_local_irq_restore(flags);					\65}66 67#define ATOMIC_OP_RETURN(op, c_op)					\68static inline int generic_atomic_##op##_return(int i, atomic_t *v)	\69{									\70	unsigned long flags;						\71	int ret;							\72									\73	raw_local_irq_save(flags);					\74	ret = (v->counter = v->counter c_op i);				\75	raw_local_irq_restore(flags);					\76									\77	return ret;							\78}79 80#define ATOMIC_FETCH_OP(op, c_op)					\81static inline int generic_atomic_fetch_##op(int i, atomic_t *v)		\82{									\83	unsigned long flags;						\84	int ret;							\85									\86	raw_local_irq_save(flags);					\87	ret = v->counter;						\88	v->counter = v->counter c_op i;					\89	raw_local_irq_restore(flags);					\90									\91	return ret;							\92}93 94#endif /* CONFIG_SMP */95 96ATOMIC_OP_RETURN(add, +)97ATOMIC_OP_RETURN(sub, -)98 99ATOMIC_FETCH_OP(add, +)100ATOMIC_FETCH_OP(sub, -)101ATOMIC_FETCH_OP(and, &)102ATOMIC_FETCH_OP(or, |)103ATOMIC_FETCH_OP(xor, ^)104 105ATOMIC_OP(add, +)106ATOMIC_OP(sub, -)107ATOMIC_OP(and, &)108ATOMIC_OP(or, |)109ATOMIC_OP(xor, ^)110 111#undef ATOMIC_FETCH_OP112#undef ATOMIC_OP_RETURN113#undef ATOMIC_OP114 115#define arch_atomic_add_return			generic_atomic_add_return116#define arch_atomic_sub_return			generic_atomic_sub_return117 118#define arch_atomic_fetch_add			generic_atomic_fetch_add119#define arch_atomic_fetch_sub			generic_atomic_fetch_sub120#define arch_atomic_fetch_and			generic_atomic_fetch_and121#define arch_atomic_fetch_or			generic_atomic_fetch_or122#define arch_atomic_fetch_xor			generic_atomic_fetch_xor123 124#define arch_atomic_add				generic_atomic_add125#define arch_atomic_sub				generic_atomic_sub126#define arch_atomic_and				generic_atomic_and127#define arch_atomic_or				generic_atomic_or128#define arch_atomic_xor				generic_atomic_xor129 130#define arch_atomic_read(v)			READ_ONCE((v)->counter)131#define arch_atomic_set(v, i)			WRITE_ONCE(((v)->counter), (i))132 133#endif /* __ASM_GENERIC_ATOMIC_H */134