Line data Source code
1 : 2 : #include "completion_table.hpp" 3 : #include "log.hpp" 4 : #include <algorithm> 5 : 6 : typedef enum 7 : { 8 : CT_OK, 9 : CT_EMPTY, 10 : CT_ERR, 11 : } ct_return; 12 : 13 : 14 18 : CompletionTable::CompletionTable() : m_rd(UINT32_MAX), 15 18 : m_last_pushed_addr(0x0), 16 18 : m_last_provided_addr(0x0), 17 18 : m_current_table(&m_table_a), 18 18 : m_wrap_table(&m_table_b) 19 18 : {} 20 : 21 : 22 : // When a chunk has been decoded 23 205203936 : void CompletionTable::push(uint32_t addr) 24 : { 25 205203936 : if (addr >= m_rd || m_rd == UINT32_MAX) 26 : { 27 205193903 : (*m_current_table)[addr]++; 28 : } 29 : else 30 : { 31 10033 : (*m_wrap_table)[addr]++; 32 : } 33 205203936 : m_last_pushed_addr = addr; 34 : // swap tables if current is empty 35 205203936 : if (m_current_table->empty() && !m_wrap_table->empty()) 36 : { 37 3438 : m_rd = m_wrap_table->begin()->first; 38 3438 : std::swap(m_current_table, m_wrap_table); 39 : } 40 205203936 : } 41 : 42 : 43 : // When a completion object is read 44 205203936 : int CompletionTable::update(uint32_t addr) 45 : { 46 205203936 : if (m_current_table->empty() && m_wrap_table->empty()) 47 : { 48 : return CT_EMPTY; 49 : } 50 205203936 : m_last_provided_addr = m_rd; 51 : 52 205203936 : if (m_rd <= addr || m_rd == UINT32_MAX) 53 : { 54 : 55 205203880 : auto it = m_current_table->find(addr); 56 205203880 : if (it == m_current_table->end()) 57 : { 58 0 : LOG_WARN("Completion object provided block addr 0x%x not in current table", addr); 59 0 : return CT_ERR; 60 : } 61 : 62 205203880 : --(it->second); 63 205203880 : if (it->second == 0) 64 : { 65 199463841 : if (it == m_current_table->begin()) 66 : { 67 204467330 : m_rd = m_current_table->size() > 1 ? std::next(it, 1)->first : it->first; 68 : } 69 199463841 : m_current_table->erase(it); 70 : } 71 : } 72 : else 73 : { 74 56 : auto it = m_wrap_table->find(addr); 75 56 : if (it == m_wrap_table->end()) 76 : { 77 205203936 : return CT_ERR; 78 : } 79 56 : --(it->second); 80 56 : if (it->second == 0) 81 : { 82 56 : m_wrap_table->erase(it); 83 : } 84 : } 85 : 86 : return CT_OK; 87 : } 88 : 89 : 90 4 : uint32_t CompletionTable::get_count(uint32_t addr) const 91 : { 92 4 : uint32_t count = 0; 93 4 : if (m_rd <= addr || m_rd == UINT32_MAX) 94 : { 95 4 : if (m_current_table->count(addr) == 1) 96 : { 97 4 : count = m_current_table->at(addr); 98 : } 99 : } 100 : else 101 : { 102 0 : if (m_wrap_table->count(addr) == 1) 103 : { 104 0 : count = m_wrap_table->at(addr); 105 : } 106 : } 107 4 : return count; 108 : } 109 : 110 : 111 6420930 : uint32_t CompletionTable::get_rd() const 112 : { 113 6420930 : return m_rd; 114 : } 115 : 116 : 117 3 : size_t CompletionTable::get_entries() const 118 : { 119 3 : return (m_current_table->size() + m_wrap_table->size()); 120 : } 121 : 122 : 123 6457573 : bool CompletionTable::is_empty() const 124 : { 125 6457573 : return (m_current_table->empty() and m_wrap_table->empty()); 126 : } 127 : 128 : 129 8 : void CompletionTable::inspect() const 130 : { 131 8 : LOG_INFO("Completion table contains %lu entries", (m_current_table->size() + m_wrap_table->size())); 132 8 : int printed{0}, max_printout{100}; 133 10 : for (auto &c : *m_current_table) 134 : { 135 2 : LOG_INFO("CT Block 0x%08x count %u", c.first, c.second); 136 2 : ++printed; 137 2 : if (printed == max_printout) 138 : { 139 : break; 140 : } 141 : } 142 8 : for (auto &w : *m_wrap_table) 143 : { 144 0 : LOG_INFO("WT Block 0x%08x count %u", w.first, w.second); 145 0 : ++printed; 146 0 : if (printed == max_printout) 147 : { 148 : break; 149 : } 150 : } 151 8 : } 152 : 153 : 154 0 : uint32_t CompletionTable::get_previous_rd() const 155 : { 156 0 : return m_last_provided_addr; 157 : }