aboutsummaryrefslogtreecommitdiff
path: root/sys/gnu/fs/xfs/FreeBSD/support/atomic.h
blob: f8b6c9171ddcdc5f31affed0fca94af8f2bcf255 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef __XFS_SUPPORT_ATOMIC_H__

#include <sys/types.h>
#include <machine/atomic.h>

typedef struct {
	volatile unsigned int	val;
} atomic_t;

#define	atomic_read(v)			((v)->val)
#define atomic_set(v, i)		((v)->val = (i))

#define	atomic_add(i, v)		atomic_add_int(&(v)->val, (i))
#define	atomic_inc(v)			atomic_add_int(&(v)->val, 1)
#define	atomic_dec(v)			atomic_subtract_int(&(v)->val, 1)
#define	atomic_sub(i, v)		atomic_subtract_int(&(v)->val, (i))
#define	atomic_sub_and_test(i, v)	(atomic_fetchadd_int(&(v)->val, (-i) == i)
#define	atomic_dec_and_test(v)		(atomic_fetchadd_int(&(v)->val, -1) == 1)

/*
 * This is used for two variables in XFS, one of which is a debug trace
 * buffer index.
 */

static __inline__ int atomicIncWithWrap(volatile unsigned int *ip, int val)
{
	unsigned int oldval, newval;

	do {
		oldval = *ip;
		newval = (oldval + 1 >= val) ? 0 : oldval + 1;
        } while (atomic_cmpset_rel_int(ip, oldval, newval) == 0);

	return oldval;
}

#endif /* __XFS_SUPPORT_ATOMIC_H__ */