1 | /* |
2 | * Copyright (c) 2015-2016, Intel Corporation |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions are met: |
6 | * |
7 | * * Redistributions of source code must retain the above copyright notice, |
8 | * this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of Intel Corporation nor the names of its contributors |
13 | * may be used to endorse or promote products derived from this software |
14 | * without specific prior written permission. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
28 | |
29 | #ifndef MPV_INTERNAL_H |
30 | #define MPV_INTERNAL_H |
31 | |
32 | #include "ue2common.h" |
33 | |
34 | #define MPV_DOT 0 |
35 | #define MPV_VERM 1 |
36 | #define MPV_SHUFTI 2 |
37 | #define MPV_TRUFFLE 3 |
38 | #define MPV_NVERM 4 |
39 | |
40 | struct mpv_puffette { |
41 | u32 repeats; |
42 | char unbounded; |
43 | |
44 | /** |
45 | * \brief Report is simple-exhaustible. |
46 | * |
47 | * If this is true, we do best-effort suppression of runs of reports, only |
48 | * delivering the first one. |
49 | */ |
50 | char simple_exhaust; |
51 | |
52 | ReportID report; |
53 | }; |
54 | |
55 | struct mpv_kilopuff { |
56 | u32 counter_offset; /**< offset (in full stream state) to the counter that |
57 | * this kilopuff refers to */ |
58 | u32 count; /**< number of real (non sentinel mpv puffettes) */ |
59 | u32 puffette_offset; /**< relative to base of mpv, points past the 1st |
60 | * sent */ |
61 | u64a dead_point; |
62 | u8 auto_restart; |
63 | u8 type; /* MPV_DOT, MPV_VERM, etc */ |
64 | union { |
65 | struct { |
66 | char c; |
67 | } verm; |
68 | struct { |
69 | m128 mask_lo; |
70 | m128 mask_hi; |
71 | } shuf; |
72 | struct { |
73 | m128 mask1; |
74 | m128 mask2; |
75 | } truffle; |
76 | } u; |
77 | }; |
78 | |
79 | struct mpv_counter_info { |
80 | u64a max_counter; /**< maximum value this counter needs to track */ |
81 | u32 counter_size; /**< number of bytes to represent the counter in stream |
82 | * state */ |
83 | u32 counter_offset; /**< offset that this counter is stored at in the |
84 | * full stream state */ |
85 | u32 kilo_begin; /**< first kilo to turn on when the counter is started */ |
86 | u32 kilo_end; /**< 1 + last kilo to turn on when the counter is started */ |
87 | }; |
88 | |
89 | struct ALIGN_AVX_DIRECTIVE mpv { |
90 | u32 kilo_count; /**< number of kilopuffs following */ |
91 | u32 counter_count; /**< number of counters managed by the mpv */ |
92 | u32 puffette_count; /**< total number of puffettes under all the kilos */ |
93 | u32 pq_offset; /**< offset to the priority queue in the decompressed |
94 | * state */ |
95 | u32 reporter_offset; /**< offset to the reporter mmbit in the decompressed |
96 | * state */ |
97 | u32 report_list_offset; /**< offset to the report list scratch space in the |
98 | * decompressed state */ |
99 | u32 active_offset; /**< offset to the active kp mmbit in the compressed |
100 | * state */ |
101 | u32 top_kilo_begin; /**< first kilo to switch on when top arrives */ |
102 | u32 top_kilo_end; /**< one past the last kilo to switch on when top |
103 | * arrives */ |
104 | }; |
105 | |
106 | struct mpv_decomp_kilo { |
107 | u64a limit; |
108 | const struct mpv_puffette *curr; |
109 | }; |
110 | |
111 | /* note: size varies on different platforms */ |
112 | struct mpv_decomp_state { |
113 | u32 pq_size; |
114 | char filled; |
115 | u64a counter_adj; /**< progress not yet written to the real counters */ |
116 | struct mpv_decomp_kilo active[]; |
117 | }; |
118 | |
119 | /* --- |
120 | * | | mpv |
121 | * --- |
122 | * | | |
123 | * | | kilo_count * mpv_kilopuffs |
124 | * | | |
125 | * ... |
126 | * | | |
127 | * --- |
128 | * | | |
129 | * | | counter_count * mpv_counter_infos |
130 | * | | |
131 | * ... |
132 | * | | |
133 | * --- |
134 | * | | sentinel mpv_puffette |
135 | * --- |
136 | * | | mpv_puffettes for 1st kilopuff |
137 | * | | (mpv_puffettes are ordered by minimum number of repeats) |
138 | * | | |
139 | * --- |
140 | * | | sentinel mpv_puffette |
141 | * --- |
142 | * | | mpv_puffettes for 2nd kilopuff |
143 | * ... |
144 | * | | |
145 | * --- |
146 | * | | sentinel mpv_puffette |
147 | * --- |
148 | */ |
149 | |
150 | /* |
151 | * Stream State |
152 | * [Compressed Counter 0] |
153 | * [Compressed Counter 1] |
154 | * ... |
155 | * [Compressed Counter N] |
156 | * [mmbit of active kilopuffs] |
157 | * |
158 | * Decompressed State |
159 | * [header (limit pq_size)] |
160 | * [ |
161 | * [kilo 1 current reports] |
162 | * ... |
163 | * [kilo N current reports] |
164 | * ] |
165 | * [ |
166 | * [Full Counter 0] |
167 | * [Full Counter 1] |
168 | * ... |
169 | * [Full Counter N] |
170 | * ] |
171 | * [pq of kilo changes] |
172 | * [scratch space for current report lists (total number of puffettes)] |
173 | * [mmbit of kilopuffs with active reports] |
174 | */ |
175 | |
176 | struct mpv_pq_item { |
177 | u64a trigger_loc; |
178 | u32 kilo; |
179 | }; |
180 | |
181 | /* returns pointer to first non sentinel mpv_puff */ |
182 | static really_inline |
183 | const struct mpv_puffette *get_puff_array(const struct mpv *m, |
184 | const struct mpv_kilopuff *kp) { |
185 | return (const struct mpv_puffette *)((const char *)m + kp->puffette_offset); |
186 | } |
187 | |
188 | static really_inline |
189 | const struct mpv_counter_info *get_counter_info(const struct mpv *m) { |
190 | return (const struct mpv_counter_info *)((const char *)(m + 1) |
191 | + m->kilo_count * sizeof(struct mpv_kilopuff)); |
192 | } |
193 | |
194 | #define MPV_DEAD_VALUE (~0ULL) |
195 | #define INVALID_REPORT (~0U) |
196 | |
197 | #endif |
198 | |