diff options
| author | Steve French <sfrench@us.ibm.com> | 2008-05-06 13:55:32 -0400 |
|---|---|---|
| committer | Steve French <sfrench@us.ibm.com> | 2008-05-06 13:55:32 -0400 |
| commit | a815752ac0ffdb910e92958d41d28f4fb28e5296 (patch) | |
| tree | a3aa16a282354da0debe8e3a3a7ed8aac6e54001 /lib/proportions.c | |
| parent | 5ade9deaaa3e1f7291467d97b238648e43eae15e (diff) | |
| parent | a15306365a16380f3bafee9e181ba01231d4acd7 (diff) | |
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'lib/proportions.c')
| -rw-r--r-- | lib/proportions.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/lib/proportions.c b/lib/proportions.c index 9508d9a7af3e..4f387a643d72 100644 --- a/lib/proportions.c +++ b/lib/proportions.c | |||
| @@ -73,12 +73,6 @@ | |||
| 73 | #include <linux/proportions.h> | 73 | #include <linux/proportions.h> |
| 74 | #include <linux/rcupdate.h> | 74 | #include <linux/rcupdate.h> |
| 75 | 75 | ||
| 76 | /* | ||
| 77 | * Limit the time part in order to ensure there are some bits left for the | ||
| 78 | * cycle counter. | ||
| 79 | */ | ||
| 80 | #define PROP_MAX_SHIFT (3*BITS_PER_LONG/4) | ||
| 81 | |||
| 82 | int prop_descriptor_init(struct prop_descriptor *pd, int shift) | 76 | int prop_descriptor_init(struct prop_descriptor *pd, int shift) |
| 83 | { | 77 | { |
| 84 | int err; | 78 | int err; |
| @@ -268,6 +262,38 @@ void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl) | |||
| 268 | } | 262 | } |
| 269 | 263 | ||
| 270 | /* | 264 | /* |
| 265 | * identical to __prop_inc_percpu, except that it limits this pl's fraction to | ||
| 266 | * @frac/PROP_FRAC_BASE by ignoring events when this limit has been exceeded. | ||
| 267 | */ | ||
| 268 | void __prop_inc_percpu_max(struct prop_descriptor *pd, | ||
| 269 | struct prop_local_percpu *pl, long frac) | ||
| 270 | { | ||
| 271 | struct prop_global *pg = prop_get_global(pd); | ||
| 272 | |||
| 273 | prop_norm_percpu(pg, pl); | ||
| 274 | |||
| 275 | if (unlikely(frac != PROP_FRAC_BASE)) { | ||
| 276 | unsigned long period_2 = 1UL << (pg->shift - 1); | ||
| 277 | unsigned long counter_mask = period_2 - 1; | ||
| 278 | unsigned long global_count; | ||
| 279 | long numerator, denominator; | ||
| 280 | |||
| 281 | numerator = percpu_counter_read_positive(&pl->events); | ||
| 282 | global_count = percpu_counter_read(&pg->events); | ||
| 283 | denominator = period_2 + (global_count & counter_mask); | ||
| 284 | |||
| 285 | if (numerator > ((denominator * frac) >> PROP_FRAC_SHIFT)) | ||
| 286 | goto out_put; | ||
| 287 | } | ||
| 288 | |||
| 289 | percpu_counter_add(&pl->events, 1); | ||
| 290 | percpu_counter_add(&pg->events, 1); | ||
| 291 | |||
| 292 | out_put: | ||
| 293 | prop_put_global(pd, pg); | ||
| 294 | } | ||
| 295 | |||
| 296 | /* | ||
| 271 | * Obtain a fraction of this proportion | 297 | * Obtain a fraction of this proportion |
| 272 | * | 298 | * |
| 273 | * p_{j} = x_{j} / (period/2 + t % period/2) | 299 | * p_{j} = x_{j} / (period/2 + t % period/2) |
