Blame view

include/linux/percpu_counter.h 3.52 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
  #ifndef _LINUX_PERCPU_COUNTER_H
  #define _LINUX_PERCPU_COUNTER_H
  /*
   * A simple "approximate counter" for use in ext2 and ext3 superblocks.
   *
   * WARNING: these things are HUGE.  4 kbytes per counter on 32-way P4.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
  #include <linux/spinlock.h>
  #include <linux/smp.h>
c67ad917c   Andrew Morton   percpu_counters()...
10
  #include <linux/list.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
  #include <linux/threads.h>
  #include <linux/percpu.h>
0216bfcff   Mingming Cao   [PATCH] percpu co...
13
  #include <linux/types.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
  
  #ifdef CONFIG_SMP
  
  struct percpu_counter {
  	spinlock_t lock;
0216bfcff   Mingming Cao   [PATCH] percpu co...
19
  	s64 count;
c67ad917c   Andrew Morton   percpu_counters()...
20
21
22
  #ifdef CONFIG_HOTPLUG_CPU
  	struct list_head list;	/* All percpu_counters are on a list */
  #endif
43cf38eb5   Tejun Heo   percpu: add __per...
23
  	s32 __percpu *counters;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  };
179f7ebff   Eric Dumazet   percpu_counter: F...
25
  extern int percpu_counter_batch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26

ea319518b   Peter Zijlstra   locking, percpu c...
27
28
29
30
31
32
33
34
35
  int __percpu_counter_init(struct percpu_counter *fbc, s64 amount,
  			  struct lock_class_key *key);
  
  #define percpu_counter_init(fbc, value)					\
  	({								\
  		static struct lock_class_key __key;			\
  									\
  		__percpu_counter_init(fbc, value, &__key);		\
  	})
c67ad917c   Andrew Morton   percpu_counters()...
36
  void percpu_counter_destroy(struct percpu_counter *fbc);
3a587f47b   Peter Zijlstra   lib: percpu_count...
37
  void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
20e897670   Peter Zijlstra   lib: make percpu_...
38
  void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
02d211688   Andrew Morton   revert "percpu_co...
39
  s64 __percpu_counter_sum(struct percpu_counter *fbc);
27f5e0f69   Tim Chen   tmpfs: add accura...
40
  int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

20e897670   Peter Zijlstra   lib: make percpu_...
42
  static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
252e0ba6b   Peter Zijlstra   lib: percpu_count...
43
  {
179f7ebff   Eric Dumazet   percpu_counter: F...
44
  	__percpu_counter_add(fbc, amount, percpu_counter_batch);
252e0ba6b   Peter Zijlstra   lib: percpu_count...
45
  }
bf1d89c81   Peter Zijlstra   lib: percpu_count...
46
47
  static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
  {
02d211688   Andrew Morton   revert "percpu_co...
48
  	s64 ret = __percpu_counter_sum(fbc);
bf1d89c81   Peter Zijlstra   lib: percpu_count...
49
50
51
52
53
  	return ret < 0 ? 0 : ret;
  }
  
  static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
  {
02d211688   Andrew Morton   revert "percpu_co...
54
  	return __percpu_counter_sum(fbc);
bf1d89c81   Peter Zijlstra   lib: percpu_count...
55
  }
0216bfcff   Mingming Cao   [PATCH] percpu co...
56
  static inline s64 percpu_counter_read(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
63
  {
  	return fbc->count;
  }
  
  /*
   * It is possible for the percpu_counter_read() to return a small negative
   * number for some counter which should never be negative.
0216bfcff   Mingming Cao   [PATCH] percpu co...
64
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
   */
0216bfcff   Mingming Cao   [PATCH] percpu co...
66
  static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  {
0216bfcff   Mingming Cao   [PATCH] percpu co...
68
  	s64 ret = fbc->count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
  
  	barrier();		/* Prevent reloads of fbc->count */
0216bfcff   Mingming Cao   [PATCH] percpu co...
71
  	if (ret >= 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
76
77
78
  		return ret;
  	return 1;
  }
  
  #else
  
  struct percpu_counter {
0216bfcff   Mingming Cao   [PATCH] percpu co...
79
  	s64 count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
  };
833f4077b   Peter Zijlstra   lib: percpu_count...
81
  static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  {
0216bfcff   Mingming Cao   [PATCH] percpu co...
83
  	fbc->count = amount;
833f4077b   Peter Zijlstra   lib: percpu_count...
84
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
87
88
89
  }
  
  static inline void percpu_counter_destroy(struct percpu_counter *fbc)
  {
  }
3a587f47b   Peter Zijlstra   lib: percpu_count...
90
91
92
93
  static inline void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
  {
  	fbc->count = amount;
  }
27f5e0f69   Tim Chen   tmpfs: add accura...
94
95
96
97
98
99
100
101
102
  static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs)
  {
  	if (fbc->count > rhs)
  		return 1;
  	else if (fbc->count < rhs)
  		return -1;
  	else
  		return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  static inline void
20e897670   Peter Zijlstra   lib: make percpu_...
104
  percpu_counter_add(struct percpu_counter *fbc, s64 amount)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
108
109
  {
  	preempt_disable();
  	fbc->count += amount;
  	preempt_enable();
  }
0c9cf2efd   Anton Blanchard   percpu_counter: M...
110
111
112
113
114
  static inline void
  __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
  {
  	percpu_counter_add(fbc, amount);
  }
0216bfcff   Mingming Cao   [PATCH] percpu co...
115
  static inline s64 percpu_counter_read(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
  {
  	return fbc->count;
  }
0216bfcff   Mingming Cao   [PATCH] percpu co...
119
  static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
  {
  	return fbc->count;
  }
52d9f3b40   Peter Zijlstra   lib: percpu_count...
123
  static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
e2bab3d92   Andrew Morton   [PATCH] percpu_co...
124
125
126
  {
  	return percpu_counter_read_positive(fbc);
  }
bf1d89c81   Peter Zijlstra   lib: percpu_count...
127
128
129
130
  static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
  {
  	return percpu_counter_read(fbc);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
132
133
134
  #endif	/* CONFIG_SMP */
  
  static inline void percpu_counter_inc(struct percpu_counter *fbc)
  {
aa0dff2d0   Peter Zijlstra   lib: percpu_count...
135
  	percpu_counter_add(fbc, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
138
139
  }
  
  static inline void percpu_counter_dec(struct percpu_counter *fbc)
  {
aa0dff2d0   Peter Zijlstra   lib: percpu_count...
140
  	percpu_counter_add(fbc, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  }
3cb4f9fa0   Peter Zijlstra   lib: percpu_count...
142
143
144
145
  static inline void percpu_counter_sub(struct percpu_counter *fbc, s64 amount)
  {
  	percpu_counter_add(fbc, -amount);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  #endif /* _LINUX_PERCPU_COUNTER_H */