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