2009-03-05 18:43:00 +01:00
/*
include / proto / freq_ctr . h
This file contains macros and inline functions for frequency counters .
Copyright ( C ) 2000 - 2009 Willy Tarreau - w @ 1 wt . eu
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation , version 2.1
exclusively .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
# ifndef _PROTO_FREQ_CTR_H
# define _PROTO_FREQ_CTR_H
# include <common/config.h>
2009-10-01 11:05:26 +02:00
# include <common/time.h>
2009-03-05 18:43:00 +01:00
# include <types/freq_ctr.h>
/* Rotate a frequency counter when current period is over. Must not be called
* during a valid period . It is important that it correctly initializes a null
* area .
*/
static inline void rotate_freq_ctr ( struct freq_ctr * ctr )
{
ctr - > prev_ctr = ctr - > curr_ctr ;
if ( likely ( now . tv_sec - ctr - > curr_sec ! = 1 ) ) {
/* we missed more than one second */
ctr - > prev_ctr = 0 ;
}
ctr - > curr_sec = now . tv_sec ;
ctr - > curr_ctr = 0 ; /* leave it at the end to help gcc optimize it away */
}
/* Update a frequency counter by <inc> incremental units. It is automatically
* rotated if the period is over . It is important that it correctly initializes
* a null area .
*/
static inline void update_freq_ctr ( struct freq_ctr * ctr , unsigned int inc )
{
if ( likely ( ctr - > curr_sec = = now . tv_sec ) ) {
ctr - > curr_ctr + = inc ;
return ;
}
rotate_freq_ctr ( ctr ) ;
ctr - > curr_ctr = inc ;
/* Note: later we may want to propagate the update to other counters */
}
2010-06-20 07:15:43 +02:00
/* Rotate a frequency counter when current period is over. Must not be called
* during a valid period . It is important that it correctly initializes a null
* area . This one works on frequency counters which have a period different
* from one second .
*/
static inline void rotate_freq_ctr_period ( struct freq_ctr_period * ctr ,
unsigned int period )
{
ctr - > prev_ctr = ctr - > curr_ctr ;
ctr - > curr_tick + = period ;
if ( likely ( now_ms - ctr - > curr_tick > = period ) ) {
/* we missed at least two periods */
ctr - > prev_ctr = 0 ;
ctr - > curr_tick = now_ms ;
}
ctr - > curr_ctr = 0 ; /* leave it at the end to help gcc optimize it away */
}
/* Update a frequency counter by <inc> incremental units. It is automatically
* rotated if the period is over . It is important that it correctly initializes
* a null area . This one works on frequency counters which have a period
* different from one second .
*/
static inline void update_freq_ctr_period ( struct freq_ctr_period * ctr ,
unsigned int period , unsigned int inc )
{
if ( likely ( now_ms - ctr - > curr_tick < period ) ) {
ctr - > curr_ctr + = inc ;
return ;
}
rotate_freq_ctr_period ( ctr , period ) ;
ctr - > curr_ctr = inc ;
/* Note: later we may want to propagate the update to other counters */
}
2009-03-05 18:43:00 +01:00
/* Read a frequency counter taking history into account for missing time in
* current period .
*/
unsigned int read_freq_ctr ( struct freq_ctr * ctr ) ;
2009-03-06 09:18:27 +01:00
/* returns the number of remaining events that can occur on this freq counter
* while respecting < freq > and taking into account that < pend > events are
* already known to be pending . Returns 0 if limit was reached .
*/
unsigned int freq_ctr_remain ( struct freq_ctr * ctr , unsigned int freq , unsigned int pend ) ;
/* return the expected wait time in ms before the next event may occur,
* respecting frequency < freq > , and assuming there may already be some pending
* events . It returns zero if we can proceed immediately , otherwise the wait
* time , which will be rounded down 1 ms for better accuracy , with a minimum
* of one ms .
*/
unsigned int next_event_delay ( struct freq_ctr * ctr , unsigned int freq , unsigned int pend ) ;
2010-06-20 07:15:43 +02:00
/* process freq counters over configurable periods */
unsigned int read_freq_ctr_period ( struct freq_ctr_period * ctr , unsigned int period ) ;
unsigned int freq_ctr_remain_period ( struct freq_ctr_period * ctr , unsigned int period ,
unsigned int freq , unsigned int pend ) ;
2009-03-05 18:43:00 +01:00
# endif /* _PROTO_FREQ_CTR_H */
/*
* Local variables :
* c - indent - level : 8
* c - basic - offset : 8
* End :
*/