]>
Commit | Line | Data |
---|---|---|
145ca25e PZ |
1 | /* |
2 | * FLoating proportions | |
3 | * | |
4 | * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> | |
5 | * | |
6 | * This file contains the public data structure and API definitions. | |
7 | */ | |
8 | ||
9 | #ifndef _LINUX_PROPORTIONS_H | |
10 | #define _LINUX_PROPORTIONS_H | |
11 | ||
12 | #include <linux/percpu_counter.h> | |
13 | #include <linux/spinlock.h> | |
14 | #include <linux/mutex.h> | |
20ae0079 | 15 | #include <linux/gfp.h> |
145ca25e PZ |
16 | |
17 | struct prop_global { | |
18 | /* | |
19 | * The period over which we differentiate | |
20 | * | |
21 | * period = 2^shift | |
22 | */ | |
23 | int shift; | |
24 | /* | |
25 | * The total event counter aka 'time'. | |
26 | * | |
27 | * Treated as an unsigned long; the lower 'shift - 1' bits are the | |
28 | * counter bits, the remaining upper bits the period counter. | |
29 | */ | |
30 | struct percpu_counter events; | |
31 | }; | |
32 | ||
33 | /* | |
34 | * global proportion descriptor | |
35 | * | |
36 | * this is needed to consitently flip prop_global structures. | |
37 | */ | |
38 | struct prop_descriptor { | |
39 | int index; | |
40 | struct prop_global pg[2]; | |
41 | struct mutex mutex; /* serialize the prop_global switch */ | |
42 | }; | |
43 | ||
20ae0079 | 44 | int prop_descriptor_init(struct prop_descriptor *pd, int shift, gfp_t gfp); |
145ca25e PZ |
45 | void prop_change_shift(struct prop_descriptor *pd, int new_shift); |
46 | ||
47 | /* | |
48 | * ----- PERCPU ------ | |
49 | */ | |
50 | ||
51 | struct prop_local_percpu { | |
52 | /* | |
53 | * the local events counter | |
54 | */ | |
55 | struct percpu_counter events; | |
56 | ||
57 | /* | |
58 | * snapshot of the last seen global state | |
59 | */ | |
60 | int shift; | |
61 | unsigned long period; | |
740969f9 | 62 | raw_spinlock_t lock; /* protect the snapshot state */ |
145ca25e PZ |
63 | }; |
64 | ||
20ae0079 | 65 | int prop_local_init_percpu(struct prop_local_percpu *pl, gfp_t gfp); |
145ca25e PZ |
66 | void prop_local_destroy_percpu(struct prop_local_percpu *pl); |
67 | void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl); | |
68 | void prop_fraction_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl, | |
69 | long *numerator, long *denominator); | |
70 | ||
71 | static inline | |
72 | void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl) | |
73 | { | |
74 | unsigned long flags; | |
75 | ||
76 | local_irq_save(flags); | |
77 | __prop_inc_percpu(pd, pl); | |
78 | local_irq_restore(flags); | |
79 | } | |
80 | ||
a42dde04 PZ |
81 | /* |
82 | * Limit the time part in order to ensure there are some bits left for the | |
83 | * cycle counter and fraction multiply. | |
84 | */ | |
3310225d | 85 | #if BITS_PER_LONG == 32 |
a42dde04 | 86 | #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4) |
3310225d WF |
87 | #else |
88 | #define PROP_MAX_SHIFT (BITS_PER_LONG/2) | |
89 | #endif | |
a42dde04 PZ |
90 | |
91 | #define PROP_FRAC_SHIFT (BITS_PER_LONG - PROP_MAX_SHIFT - 1) | |
92 | #define PROP_FRAC_BASE (1UL << PROP_FRAC_SHIFT) | |
93 | ||
94 | void __prop_inc_percpu_max(struct prop_descriptor *pd, | |
95 | struct prop_local_percpu *pl, long frac); | |
96 | ||
97 | ||
145ca25e PZ |
98 | /* |
99 | * ----- SINGLE ------ | |
100 | */ | |
101 | ||
102 | struct prop_local_single { | |
103 | /* | |
104 | * the local events counter | |
105 | */ | |
106 | unsigned long events; | |
107 | ||
108 | /* | |
109 | * snapshot of the last seen global state | |
110 | * and a lock protecting this state | |
111 | */ | |
145ca25e | 112 | unsigned long period; |
3fb669dd | 113 | int shift; |
740969f9 | 114 | raw_spinlock_t lock; /* protect the snapshot state */ |
145ca25e PZ |
115 | }; |
116 | ||
117 | #define INIT_PROP_LOCAL_SINGLE(name) \ | |
740969f9 | 118 | { .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ |
145ca25e PZ |
119 | } |
120 | ||
121 | int prop_local_init_single(struct prop_local_single *pl); | |
122 | void prop_local_destroy_single(struct prop_local_single *pl); | |
123 | void __prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl); | |
124 | void prop_fraction_single(struct prop_descriptor *pd, struct prop_local_single *pl, | |
125 | long *numerator, long *denominator); | |
126 | ||
127 | static inline | |
128 | void prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl) | |
129 | { | |
130 | unsigned long flags; | |
131 | ||
132 | local_irq_save(flags); | |
133 | __prop_inc_single(pd, pl); | |
134 | local_irq_restore(flags); | |
135 | } | |
136 | ||
137 | #endif /* _LINUX_PROPORTIONS_H */ |