xref: /f-stack/freebsd/sys/tim_filter.h (revision 22ce4aff)
1*22ce4affSfengbojiang #ifndef __tim_filter_h__
2*22ce4affSfengbojiang #define __tim_filter_h__
3*22ce4affSfengbojiang /*-
4*22ce4affSfengbojiang  * Copyright (c) 2016-9 Netflix, Inc.
5*22ce4affSfengbojiang  * All rights reserved.
6*22ce4affSfengbojiang  *
7*22ce4affSfengbojiang  * Redistribution and use in source and binary forms, with or without
8*22ce4affSfengbojiang  * modification, are permitted provided that the following conditions
9*22ce4affSfengbojiang  * are met:
10*22ce4affSfengbojiang  * 1. Redistributions of source code must retain the above copyright
11*22ce4affSfengbojiang  *    notice, this list of conditions and the following disclaimer.
12*22ce4affSfengbojiang  * 2. Redistributions in binary form must reproduce the above copyright
13*22ce4affSfengbojiang  *    notice, this list of conditions and the following disclaimer in the
14*22ce4affSfengbojiang  *    documentation and/or other materials provided with the distribution.
15*22ce4affSfengbojiang  *
16*22ce4affSfengbojiang  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*22ce4affSfengbojiang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*22ce4affSfengbojiang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*22ce4affSfengbojiang  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*22ce4affSfengbojiang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*22ce4affSfengbojiang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*22ce4affSfengbojiang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*22ce4affSfengbojiang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*22ce4affSfengbojiang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*22ce4affSfengbojiang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*22ce4affSfengbojiang  * SUCH DAMAGE.
27*22ce4affSfengbojiang  *
28*22ce4affSfengbojiang  * $FreeBSD$
29*22ce4affSfengbojiang  */
30*22ce4affSfengbojiang /*
31*22ce4affSfengbojiang  * Author: Randall Stewart <[email protected]>
32*22ce4affSfengbojiang  */
33*22ce4affSfengbojiang 
34*22ce4affSfengbojiang #include <sys/types.h>
35*22ce4affSfengbojiang #include <machine/param.h>
36*22ce4affSfengbojiang /*
37*22ce4affSfengbojiang  * Do not change the size unless you know what you are
38*22ce4affSfengbojiang  * doing, the current size of 5 is designed around
39*22ce4affSfengbojiang  * the cache-line size for an amd64 processor. Other processors
40*22ce4affSfengbojiang  * may need other sizes.
41*22ce4affSfengbojiang  */
42*22ce4affSfengbojiang #define NUM_FILTER_ENTRIES 3
43*22ce4affSfengbojiang 
44*22ce4affSfengbojiang struct filter_entry {
45*22ce4affSfengbojiang 	uint64_t value;		/* Value */
46*22ce4affSfengbojiang 	uint32_t time_up;	/* Time updated */
47*22ce4affSfengbojiang } __packed ;
48*22ce4affSfengbojiang 
49*22ce4affSfengbojiang struct filter_entry_small {
50*22ce4affSfengbojiang 	uint32_t value;		/* Value */
51*22ce4affSfengbojiang 	uint32_t time_up;	/* Time updated */
52*22ce4affSfengbojiang };
53*22ce4affSfengbojiang 
54*22ce4affSfengbojiang struct time_filter {
55*22ce4affSfengbojiang 	uint32_t cur_time_limit;
56*22ce4affSfengbojiang 	struct filter_entry entries[NUM_FILTER_ENTRIES];
57*22ce4affSfengbojiang #ifdef _KERNEL
58*22ce4affSfengbojiang } __aligned(CACHE_LINE_SIZE);
59*22ce4affSfengbojiang #else
60*22ce4affSfengbojiang };
61*22ce4affSfengbojiang #endif
62*22ce4affSfengbojiang struct time_filter_small {
63*22ce4affSfengbojiang 	uint32_t cur_time_limit;
64*22ce4affSfengbojiang 	struct filter_entry_small entries[NUM_FILTER_ENTRIES];
65*22ce4affSfengbojiang };
66*22ce4affSfengbojiang 
67*22ce4affSfengbojiang /*
68*22ce4affSfengbojiang  * To conserve on space there is a code duplication here (this
69*22ce4affSfengbojiang  * is where polymophism would be nice in the kernel). Everything
70*22ce4affSfengbojiang  * is duplicated to have a filter with a value of uint32_t instead
71*22ce4affSfengbojiang  * of a uint64_t. This saves 20 bytes and the structure size
72*22ce4affSfengbojiang  * drops to 44 from 64. The bad part about this is you end
73*22ce4affSfengbojiang  * up with two sets of functions. The xxx_small() access
74*22ce4affSfengbojiang  * the uint32_t value's where the xxx() the uint64_t values.
75*22ce4affSfengbojiang  * This forces the user to keep straight which type of structure
76*22ce4affSfengbojiang  * they allocated and which call they need to make. crossing
77*22ce4affSfengbojiang  * over calls will create either invalid memory references or
78*22ce4affSfengbojiang  * very bad results :)
79*22ce4affSfengbojiang  */
80*22ce4affSfengbojiang 
81*22ce4affSfengbojiang #define FILTER_TYPE_MIN 1
82*22ce4affSfengbojiang #define FILTER_TYPE_MAX 2
83*22ce4affSfengbojiang 
84*22ce4affSfengbojiang #ifdef _KERNEL
85*22ce4affSfengbojiang int setup_time_filter(struct time_filter *tf, int fil_type, uint32_t time_len);
86*22ce4affSfengbojiang void reset_time(struct time_filter *tf, uint32_t time_len);
87*22ce4affSfengbojiang void forward_filter_clock(struct time_filter *tf, uint32_t ticks_forward);
88*22ce4affSfengbojiang void tick_filter_clock(struct time_filter *tf, uint32_t now);
89*22ce4affSfengbojiang uint32_t apply_filter_min(struct time_filter *tf, uint64_t value, uint32_t now);
90*22ce4affSfengbojiang uint32_t apply_filter_max(struct time_filter *tf, uint64_t value, uint32_t now);
91*22ce4affSfengbojiang void filter_reduce_by(struct time_filter *tf, uint64_t reduce_by, uint32_t now);
92*22ce4affSfengbojiang void filter_increase_by(struct time_filter *tf, uint64_t incr_by, uint32_t now);
93*22ce4affSfengbojiang static uint64_t inline
get_filter_value(struct time_filter * tf)94*22ce4affSfengbojiang get_filter_value(struct time_filter *tf)
95*22ce4affSfengbojiang {
96*22ce4affSfengbojiang 	return(tf->entries[0].value);
97*22ce4affSfengbojiang }
98*22ce4affSfengbojiang 
99*22ce4affSfengbojiang static uint32_t inline
get_cur_timelim(struct time_filter * tf)100*22ce4affSfengbojiang get_cur_timelim(struct time_filter *tf)
101*22ce4affSfengbojiang {
102*22ce4affSfengbojiang 	return(tf->cur_time_limit);
103*22ce4affSfengbojiang }
104*22ce4affSfengbojiang 
105*22ce4affSfengbojiang int setup_time_filter_small(struct time_filter_small *tf,
106*22ce4affSfengbojiang 			    int fil_type, uint32_t time_len);
107*22ce4affSfengbojiang void reset_time_small(struct time_filter_small *tf, uint32_t time_len);
108*22ce4affSfengbojiang void forward_filter_clock_small(struct time_filter_small *tf,
109*22ce4affSfengbojiang 				uint32_t ticks_forward);
110*22ce4affSfengbojiang void tick_filter_clock_small(struct time_filter_small *tf, uint32_t now);
111*22ce4affSfengbojiang uint32_t apply_filter_min_small(struct time_filter_small *tf,
112*22ce4affSfengbojiang 				uint32_t value, uint32_t now);
113*22ce4affSfengbojiang uint32_t apply_filter_max_small(struct time_filter_small *tf,
114*22ce4affSfengbojiang 				uint32_t value, uint32_t now);
115*22ce4affSfengbojiang void filter_reduce_by_small(struct time_filter_small *tf,
116*22ce4affSfengbojiang 			    uint32_t reduce_by, uint32_t now);
117*22ce4affSfengbojiang void filter_increase_by_small(struct time_filter_small *tf,
118*22ce4affSfengbojiang 			      uint32_t incr_by, uint32_t now);
119*22ce4affSfengbojiang static uint64_t inline
get_filter_value_small(struct time_filter_small * tf)120*22ce4affSfengbojiang get_filter_value_small(struct time_filter_small *tf)
121*22ce4affSfengbojiang {
122*22ce4affSfengbojiang 	return(tf->entries[0].value);
123*22ce4affSfengbojiang }
124*22ce4affSfengbojiang 
125*22ce4affSfengbojiang static uint32_t inline
get_cur_timelim_small(struct time_filter_small * tf)126*22ce4affSfengbojiang get_cur_timelim_small(struct time_filter_small *tf)
127*22ce4affSfengbojiang {
128*22ce4affSfengbojiang 	return(tf->cur_time_limit);
129*22ce4affSfengbojiang }
130*22ce4affSfengbojiang 
131*22ce4affSfengbojiang #endif
132*22ce4affSfengbojiang #endif
133