| 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 | |