mirror of
				https://git.haproxy.org/git/haproxy.git/
				synced 2025-10-31 00:21:00 +01:00 
			
		
		
		
	Some freq counters will have to work on periods different from 1 second. The original freq counters rely on the period to be exactly one second. The new ones (freq_ctr_period) let the user define the period in ticks, and all computations are operated over that period. When reading a value, it indicates the amount of events over that period too.
		
			
				
	
	
		
			126 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|   include/proto/freq_ctr.h
 | |
|   This file contains macros and inline functions for frequency counters.
 | |
| 
 | |
|   Copyright (C) 2000-2009 Willy Tarreau - w@1wt.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>
 | |
| #include <common/time.h>
 | |
| #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 */
 | |
| }
 | |
| 
 | |
| /* 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 */
 | |
| }
 | |
| 
 | |
| /* Read a frequency counter taking history into account for missing time in
 | |
|  * current period.
 | |
|  */
 | |
| unsigned int read_freq_ctr(struct freq_ctr *ctr);
 | |
| 
 | |
| /* 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 1ms for better accuracy, with a minimum
 | |
|  * of one ms.
 | |
|  */
 | |
| unsigned int next_event_delay(struct freq_ctr *ctr, unsigned int freq, unsigned int pend);
 | |
| 
 | |
| /* 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);
 | |
| 
 | |
| #endif /* _PROTO_FREQ_CTR_H */
 | |
| 
 | |
| /*
 | |
|  * Local variables:
 | |
|  *  c-indent-level: 8
 | |
|  *  c-basic-offset: 8
 | |
|  * End:
 | |
|   */
 |