Blame view

include/linux/percpu_counter.h 3.83 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
  
  #ifdef CONFIG_SMP
  
  struct percpu_counter {
f032a4508   Thomas Gleixner   locking, percpu_c...
18
  	raw_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
  		return ret;
c84598bbf   Shaohua Li   percpu_counter: c...
73
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  }
7f93cff90   Theodore Ts'o   ext4: fix kernel ...
75
76
77
78
  static inline int percpu_counter_initialized(struct percpu_counter *fbc)
  {
  	return (fbc->counters != NULL);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
  #else
  
  struct percpu_counter {
0216bfcff   Mingming Cao   [PATCH] percpu co...
82
  	s64 count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
  };
833f4077b   Peter Zijlstra   lib: percpu_count...
84
  static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  {
0216bfcff   Mingming Cao   [PATCH] percpu co...
86
  	fbc->count = amount;
833f4077b   Peter Zijlstra   lib: percpu_count...
87
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
  }
  
  static inline void percpu_counter_destroy(struct percpu_counter *fbc)
  {
  }
3a587f47b   Peter Zijlstra   lib: percpu_count...
93
94
95
96
  static inline void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
  {
  	fbc->count = amount;
  }
27f5e0f69   Tim Chen   tmpfs: add accura...
97
98
99
100
101
102
103
104
105
  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
106
  static inline void
20e897670   Peter Zijlstra   lib: make percpu_...
107
  percpu_counter_add(struct percpu_counter *fbc, s64 amount)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
112
  {
  	preempt_disable();
  	fbc->count += amount;
  	preempt_enable();
  }
0c9cf2efd   Anton Blanchard   percpu_counter: M...
113
114
115
116
117
  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...
118
  static inline s64 percpu_counter_read(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
  {
  	return fbc->count;
  }
c84598bbf   Shaohua Li   percpu_counter: c...
122
123
124
125
  /*
   * percpu_counter is intended to track positive numbers. In the UP case the
   * number should never be negative.
   */
0216bfcff   Mingming Cao   [PATCH] percpu co...
126
  static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
  {
  	return fbc->count;
  }
52d9f3b40   Peter Zijlstra   lib: percpu_count...
130
  static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
e2bab3d92   Andrew Morton   [PATCH] percpu_co...
131
132
133
  {
  	return percpu_counter_read_positive(fbc);
  }
bf1d89c81   Peter Zijlstra   lib: percpu_count...
134
135
136
137
  static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
  {
  	return percpu_counter_read(fbc);
  }
7f93cff90   Theodore Ts'o   ext4: fix kernel ...
138
139
140
141
  static inline int percpu_counter_initialized(struct percpu_counter *fbc)
  {
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
  #endif	/* CONFIG_SMP */
  
  static inline void percpu_counter_inc(struct percpu_counter *fbc)
  {
aa0dff2d0   Peter Zijlstra   lib: percpu_count...
146
  	percpu_counter_add(fbc, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
150
  }
  
  static inline void percpu_counter_dec(struct percpu_counter *fbc)
  {
aa0dff2d0   Peter Zijlstra   lib: percpu_count...
151
  	percpu_counter_add(fbc, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  }
3cb4f9fa0   Peter Zijlstra   lib: percpu_count...
153
154
155
156
  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
157
  #endif /* _LINUX_PERCPU_COUNTER_H */