LCOV - code coverage report
Current view: top level - felix-star/src - completion_table.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 60 67 89.6 %
Date: 2025-06-10 03:23:28 Functions: 8 9 88.9 %

          Line data    Source code
       1             : #include <map>
       2             : 
       3             : extern "C" {
       4             :   #include "log.h"
       5             :   #include "completion_table.h"
       6             : }
       7             : 
       8             : /**
       9             :  * The completion table is the data structure that 
      10             :  * allows to advance the DMA buffer read pointer as
      11             :  * completion objects from send operations are returned
      12             :  * The table is implemented using a pair of std::map used
      13             :  * in tandem to deal with address wrap-around.
      14             :  */
      15             : 
      16             : 
      17             : typedef uint32_t address_t;
      18             : typedef uint32_t counter_t;
      19             : 
      20             : 
      21          23 : struct completion_table
      22             : {
      23             :   address_t rd;
      24             :   address_t last_pushed_addr;
      25             :   address_t last_provided_addr;
      26             :   std::map<address_t, counter_t> table_a;
      27             :   std::map<address_t, counter_t> table_b;
      28             :   std::map<address_t, counter_t>* current_table;
      29             :   std::map<address_t, counter_t>* wrap_table;
      30             : };
      31             : 
      32             : 
      33          23 : void completion_table_init(completion_table** t)
      34             : {
      35          23 :   (*t) = new completion_table;
      36          23 :   (*t)->rd = UINT32_MAX;
      37          23 :   (*t)->current_table = &(*t)->table_a;
      38          23 :   (*t)->wrap_table = &(*t)->table_b;
      39          23 :   (*t)->last_pushed_addr = 0x0;
      40          23 :   (*t)->last_provided_addr = 0x0;
      41          23 : }
      42             : 
      43             : 
      44           6 : void completion_table_close(completion_table** t)
      45             : {
      46           6 :   delete (*t);
      47           6 :   (*t) = NULL;
      48           6 : }
      49             : 
      50             : 
      51             : // When a chunk has been decoded
      52    86744382 : void completion_table_push(completion_table* t, uint32_t addr)
      53             : {
      54    86744382 :   if (addr >= t->rd || t->rd == UINT32_MAX){
      55    84804699 :     (*t->current_table)[addr]++;
      56             :   } else {
      57     1939683 :     (*t->wrap_table)[addr]++;
      58             :   }
      59    86744382 :   t->last_pushed_addr = addr;
      60             :   //swap tables if current is empty
      61    86744382 :   if (t->current_table->empty() && !t->wrap_table->empty()) {
      62        1137 :     t->rd = t->wrap_table->begin()->first;
      63        1137 :     std::swap(t->current_table, t->wrap_table);
      64             :   }
      65    86744382 : }
      66             : 
      67             : // When a completion object is read
      68    86744382 : int completion_table_update(completion_table* t, uint32_t addr)
      69             : {
      70    86744382 :   if (t->current_table->empty() && t->wrap_table->empty()){
      71             :     return CT_EMPTY;
      72             :   }
      73    86744382 :   t->last_provided_addr = t->rd;
      74             : 
      75    86744382 :   if (t->rd <= addr || t->rd == UINT32_MAX){
      76             : 
      77    84897772 :     auto it = t->current_table->find(addr);
      78    84897772 :     if (it == t->current_table->end()){
      79           1 :       LOG_WARN("Completion object provided block addr 0x%x not in current table", addr);
      80           1 :       return CT_ERR;
      81             :     }
      82             : 
      83    84897771 :     --(it->second);
      84    84897771 :     if (it->second == 0){
      85    83825089 :       if(it == t->current_table->begin()){
      86   105914251 :         t->rd = t->current_table->size() > 1 ? std::next(it, 1)->first : it->first;
      87             :       }
      88    83825089 :       t->current_table->erase(it);
      89             :     }
      90             : 
      91             :   } else {
      92             : 
      93     1846610 :     auto it = t->wrap_table->find(addr);
      94     1846610 :     if (it == t->wrap_table->end()){
      95           1 :       return CT_ERR;
      96             :     }
      97     1846610 :     --(it->second);
      98     1846610 :     if (it->second == 0){
      99     1838908 :       t->wrap_table->erase(it);
     100             :     }
     101             : 
     102             :   }
     103             : 
     104             :   return CT_OK;
     105             : }
     106             : 
     107             : 
     108           8 : uint32_t completion_table_get_count(completion_table* t, uint32_t addr)
     109             : {
     110           8 :   uint32_t count = 0;
     111           8 :   if (t->rd <= addr || t->rd == UINT32_MAX) {
     112           8 :     if(t->current_table->count(addr) == 1){
     113           8 :       count = t->current_table->at(addr);
     114             :     }
     115             :   } else {
     116           0 :     if(t->wrap_table->count(addr) == 1){
     117           0 :       count = t->wrap_table->at(addr);
     118             :     }
     119             :   }
     120           8 :   return count;
     121             : }
     122             : 
     123             : 
     124     2667852 : uint32_t completion_table_get_rd(completion_table* t)
     125             : {
     126     2667852 :   return t->rd;
     127             : }
     128             : 
     129             : 
     130           6 : size_t completion_table_get_entries(completion_table* t)
     131             : {
     132           6 :   return (t->current_table->size() + t->wrap_table->size());
     133             : }
     134             : 
     135             : 
     136          10 : void completion_table_inspect(completion_table* t)
     137             : {
     138          10 :   LOG_INFO("Completion table contains %lu entries", (t->current_table->size()+t->wrap_table->size()) );
     139          10 :   int printed{0}, max_printout{100};
     140          12 :   for (auto & c : *t->current_table){
     141           2 :     LOG_INFO("CT Block 0x%08x count  %u", c.first, c.second);
     142           2 :     ++printed;
     143           2 :     if(printed == max_printout){break;}
     144             :   }
     145          10 :   for (auto & w : *t->wrap_table){
     146           0 :     LOG_INFO("WT Block 0x%08x count %u", w.first, w.second);
     147           0 :     ++printed;
     148           0 :     if(printed == max_printout){break;}
     149             :   }
     150          10 : }
     151             : 
     152             : 
     153           0 : uint32_t get_previous_rd(completion_table* t)
     154             : {
     155           0 :   return t->last_provided_addr;
     156             : }

Generated by: LCOV version 1.0