limiter: un-inline code

This commit is contained in:
Thomas Schoebel-Theuer 2012-09-24 11:17:00 +02:00 committed by Thomas Schoebel-Theuer
parent 37c4e34f76
commit 84ca56f6b1
3 changed files with 46 additions and 35 deletions

View File

@ -9,6 +9,7 @@ mars-objs := \
mars_generic.o \
lib_log.o \
lib_rank.o \
lib_limiter.o \
mars_net.o \
mars_server.o \
mars_client.o \

42
lib_limiter.c Normal file
View File

@ -0,0 +1,42 @@
// (c) 2012 Thomas Schoebel-Theuer / 1&1 Internet AG
#include "lib_limiter.h"
#include <linux/kernel.h>
#include <linux/module.h>
int mars_limit(struct mars_limiter *lim, int amount)
{
int res = 0;
unsigned long long now;
now = cpu_clock(raw_smp_processor_id());
if (lim->lim_max_rate > 0 && likely(lim->lim_stamp)) {
long long elapsed = now - lim->lim_stamp;
long long rate;
/* Races are possible, but taken into account.
* There is no real harm from rarely lost updates.
*/
lim->lim_accu += amount;
rate = (long long)lim->lim_accu * LIMITER_TIME_RESOLUTION / elapsed;
if (rate > lim->lim_max_rate) {
res = 1001 - lim->lim_max_rate * 1000 / rate;
}
elapsed -= LIMITER_TIME_RESOLUTION * 2;
if (elapsed > LIMITER_TIME_RESOLUTION) {
lim->lim_stamp += elapsed;
if (lim->lim_accu > 0)
lim->lim_accu -= (long long)lim->lim_max_rate * elapsed / LIMITER_TIME_RESOLUTION;
}
} else {
lim->lim_accu = amount;
lim->lim_stamp = now;
}
return res;
}
EXPORT_SYMBOL_GPL(mars_limit);

View File

@ -2,6 +2,8 @@
#ifndef MARS_LIB_LIMITER_H
#define MARS_LIB_LIMITER_H
#include "brick.h"
#include <linux/utsname.h>
#define LIMITER_TIME_RESOLUTION NSEC_PER_SEC
@ -14,41 +16,7 @@ struct mars_limiter {
unsigned long long lim_stamp;
};
extern inline
int mars_limit(struct mars_limiter *lim, int amount)
{
int res = 0;
unsigned long long now;
now = cpu_clock(raw_smp_processor_id());
if (lim->lim_max_rate > 0 && likely(lim->lim_stamp)) {
long long elapsed = now - lim->lim_stamp;
long long rate;
/* Races are possible, but taken into account.
* There is no real harm from rarely lost updates.
*/
lim->lim_accu += amount;
rate = (long long)lim->lim_accu * LIMITER_TIME_RESOLUTION / elapsed;
if (rate > lim->lim_max_rate) {
res = 1001 - lim->lim_max_rate * 1000 / rate;
}
elapsed -= LIMITER_TIME_RESOLUTION * 2;
if (elapsed > LIMITER_TIME_RESOLUTION) {
lim->lim_stamp += elapsed;
if (lim->lim_accu > 0)
lim->lim_accu -= (long long)lim->lim_max_rate * elapsed / LIMITER_TIME_RESOLUTION;
}
} else {
lim->lim_accu = amount;
lim->lim_stamp = now;
}
return res;
}
extern int mars_limit(struct mars_limiter *lim, int amount);
extern inline
void mars_limit_sleep(struct mars_limiter *lim, int amount)