Ignore:
Timestamp:
Sep 18, 2013, 1:44:37 PM (11 years ago)
Author:
cfuguet
Message:

Bugfix in vci_mem_cache and generic_llsc_global_table:

  • The Store Conditional commmand was not performed atomically in some special cases. To solve this, a new operation has been introduced in the LL/SC table (check operation) which allows

to check if a SC operation is atomic or not without erasing the

reservation on the LL/SC table.

The reservation on the LL/SC table will be erased once the SC
command is completely treated:

  • A GET request has been inserted on the TRT when MISS.
  • An UPDATE request has been inserted on the UPT when MULTI

UPDATE needed.

  • An INVAL request has been inserted on the IVT when BROADCAST INVALIDATE needed.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/generic_llsc_global_table/include/generic_llsc_global_table.h

    r524 r527  
    2828#define SOCLIB_GENERIC_LLSC_GLOBAL_TABLE_H
    2929
    30 #include <systemc>
    31 #include <arithmetics.h>
    3230#include <cassert>
    3331#include <cstring>
     
    3533#include <iostream>
    3634#include <iomanip>
     35#include <stdint.h>
    3736
    3837namespace soclib
     
    7069
    7170    uint32_t                    r_next_key        ; // value of the next key
    72     sc_dt::sc_uint<nb_slots>    r_block_mask      ; // mask for the slots blocks
    73     sc_dt::sc_uint<nb_slots>    r_last_counter    ; // mask for the slots blocks
     71    uint64_t                    r_block_mask      ; // mask for the slots blocks
     72    uint64_t                    r_last_counter    ; // mask for the slots blocks
    7473    size_t                      r_write_ptr       ; // index of next slot to replace
    7574    size_t                      r_last_empty      ; // index of last empty slot used
    7675
    77     uint32_t                    m_cpt_evic        ; // number of eviction in the table
    78     uint32_t                    m_cpt_ll          ; // number of ll accesses to the table
    79     uint32_t                    m_cpt_ll_update   ; // number of ll accesses to the table that trigger an update TODO check that
    80     uint32_t                    m_cpt_sc          ; // number of sc accesses to the table
    81     uint32_t                    m_cpt_sc_success  ; // number of sc accesses to the table that are successful
    82     uint32_t                    m_cpt_sw          ; // number of sw accesses to the table
     76    mutable uint32_t            m_cpt_evic        ; // number of eviction in the table
     77    mutable uint32_t            m_cpt_ll          ; // number of ll accesses to the table
     78    mutable uint32_t            m_cpt_ll_update   ; // number of ll accesses to the table that trigger an update TODO check that
     79    mutable uint32_t            m_cpt_sc          ; // number of sc accesses to the table
     80    mutable uint32_t            m_cpt_sc_success  ; // number of sc accesses to the table that are successful
     81    mutable uint32_t            m_cpt_check       ; // number of check accesses to the table
     82    mutable uint32_t            m_cpt_sw          ; // number of sw accesses to the table
    8383
    8484    ////////////////////////////////////////////////////////////////////////////
     
    121121    //  This is done by updating the value of r_write_ptr
    122122    {
    123         sc_dt::sc_uint<nb_slots> new_counter;
    124         sc_dt::sc_uint<nb_slots> xor_counter;
     123        uint64_t new_counter;
     124        uint64_t xor_counter;
    125125
    126126        new_counter = newCounter(r_block_mask, r_last_counter);
     
    129129        for (size_t i = nb_slots - 1; i >= 0; --i)
    130130        {
    131             if(xor_counter[i])
     131            if(xor_counter & (1 << i))
    132132            {
    133133                r_write_ptr = i;
     
    140140
    141141    ////////////////////////////////////////////////////////////////////////////
    142     inline sc_dt::sc_uint<nb_slots> newCounter(const sc_dt::sc_uint<nb_slots>& mask,
    143                                                const sc_dt::sc_uint<nb_slots>& counter)
     142    inline uint64_t newCounter(const uint64_t& mask,
     143                               const uint64_t& counter) const
    144144    // This function generates the new counter //TODO comment more
    145145    {
    146         //
    147146        return ((((~counter) & (counter << 1)) & mask) | (counter + 1));
    148147    }
     
    164163        {
    165164            case 12:
    166             r_block_mask = sc_dt::sc_uint<nb_slots>("0x000");
     165            r_block_mask = (uint64_t)0x000ULL;
    167166            break;
    168167            case 16 :
    169             r_block_mask = sc_dt::sc_uint<nb_slots>("0xA800");
     168            r_block_mask = (uint64_t)0xA800ULL;
    170169            break;
    171170            case 20 :
    172             r_block_mask = sc_dt::sc_uint<nb_slots>("0xD5500");
     171            r_block_mask = (uint64_t)0xD5500ULL;
    173172            break;
    174173            case 24 :
    175             r_block_mask = sc_dt::sc_uint<nb_slots>("0xDB5540");
     174            r_block_mask = (uint64_t)0xDB5540ULL;
    176175            break;
    177176            case 28 :
    178             r_block_mask = sc_dt::sc_uint<nb_slots>("0xEEDAAA0");
     177            r_block_mask = (uint64_t)0xEEDAAA0ULL;
    179178            break;
    180179            case 32 :
    181             r_block_mask = sc_dt::sc_uint<nb_slots>("0xF776D550");
     180            r_block_mask = (uint64_t)0xF776D550ULL;
    182181            break;
    183182            case 36 :
    184             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFBDDDB550");
     183            r_block_mask = (uint64_t)0xFBDDDB550ULL;
    185184            break;
    186185            case 40 :
    187             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFDF7BB6D50");
     186            r_block_mask = (uint64_t)0xFDF7BB6D50ULL;
    188187            break;
    189188            case 44 :
    190             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFEFBDEEDAA8");
     189            r_block_mask = (uint64_t)0xFEFBDEEDAA8ULL;
    191190            break;
    192191            case 48 :
    193             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFF7EFBDDDAA8");
     192            r_block_mask = (uint64_t)0xFF7EFBDDDAA8ULL;
    194193            break;
    195194            case 52 :
    196             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFBFBF7BBB6A8");
     195            r_block_mask = (uint64_t)0xFFBFBF7BBB6A8ULL;
    197196            break;
    198197            case 56 :
    199             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFDFEFDF7BB6A8");
     198            r_block_mask = (uint64_t)0xFFDFEFDF7BB6A8ULL;
    200199            break;
    201200            case 60 :
    202             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFF7FDFDF7BB6A8");
     201            r_block_mask = (uint64_t)0xFFF7FDFDF7BB6A8ULL;
    203202            break;
    204203            case 64 :
    205             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFFBFF7FBF7BB6A8");
     204            r_block_mask = (uint64_t)0xFFFBFF7FBF7BB6A8ULL;
    206205            break;
    207206            default:
     
    211210
    212211    ////////////////////////////////////////////////////////////////////////////
    213     inline int nextEmptySlot()
     212    inline int nextEmptySlot() const
    214213    //  This function returns :
    215214    //  - the position of the first next empty slot in the table
     
    218217    //  - -1 if the table is full
    219218    {
    220         size_t i = r_last_empty;
    221         do
    222         {
    223             // checking if current slot is empty
    224             if(!r_val[i])
    225             {
    226                 // updating last empty slot and returning its position
    227                 r_last_empty = i;
    228                 return i;
    229             }
    230             // selecting next slot
    231             i = (i+1) % nb_slots;
    232         }
    233         // stop if all slots have been tested
    234         while(i != r_last_empty);
    235 
    236         // the table is full
     219        uint64_t i;
     220        for(i = 0; i < nb_slots; i++)
     221        {
     222            if (!r_val[i]) return i;
     223        }
     224
    237225        return -1;
    238226    }
    239227
    240228    ////////////////////////////////////////////////////////////////////////////
    241     inline int hitAddr(const addr_t ad)
     229    inline int hitAddr(const addr_t ad) const
    242230    //  HIT on the address only
    243231    //  This function takes an addr_t ad
     
    259247
    260248    ////////////////////////////////////////////////////////////////////////////
    261     inline int hitAddrKey(const addr_t ad, const uint32_t key)
     249    inline int hitAddrKey(const addr_t ad, const uint32_t key) const
    262250    //  HIT on the address AND the on the signature
    263251    //  This function takes an addr_t ad and a uint32_t key
     
    291279        m_cpt_sc            = 0;
    292280        m_cpt_sc_success    = 0;
     281        m_cpt_check         = 0;
    293282        m_cpt_sw            = 0;
    294283    }
     
    301290    :   name(n)
    302291    {
    303         #define L2 soclib::common::uint32_log2
    304292        assert(nb_procs > 1);
    305         assert((int)nb_slots >= L2(nb_procs));
    306         #undef L2
    307293        init();
    308294        init_block_mask();
     
    362348        if (pos >= 0)
    363349        {
    364             if(r_key[pos] - r_next_key > life_span)
    365                 return r_key[pos];
     350            uint32_t absdiff = ( r_key[pos] > r_next_key) ?
     351                                 r_key[pos] - r_next_key  :
     352                                 r_next_key - r_key[pos];
     353
     354            if(absdiff < life_span) return r_key[pos];
     355
    366356            r_key[pos] = r_next_key;
    367357            upNextKey();
    368358            m_cpt_ll_update++;
     359
    369360            return r_key[pos];
    370361        }
     
    377368        if (pos == -1)
    378369        {
     370            //  update the victim slot for the next eviction
     371            updateVictimSlot();
     372
    379373            //  get the position of the evicted registration
    380374            pos = r_write_ptr;
    381             //  update the victim slot for the next eviction
    382             updateVictimSlot();
     375
    383376            // increment the eviction counter (for stats)
    384377            m_cpt_evic++;
     
    434427
    435428    ////////////////////////////////////////////////////////////////////////////
     429    inline bool check(const addr_t ad, const uint32_t key) const
     430    //  This method checks if there is a valid registration for the SC (ad &&
     431    //  key)
     432    //  The return value can be used to tell if the SC is atomic
     433    {
     434        // increment the check access counter (for stats)
     435        m_cpt_check++;
     436
     437        return (hitAddrKey(ad, key) >= 0);
     438    }
     439
     440    ////////////////////////////////////////////////////////////////////////////
    436441    /*
    437442    inline void sw(const addr_t ad)
     
    489494    inline void print_trace(std::ostream& out = std::cout)
    490495    {
    491         out <<  " ___________________________________" << std::endl
    492             <<  "| " << std::setw(33) << "generic_llsc_global_table" << " |" << std::endl
    493             <<  "| " << std::setw(33) << name << " |" << std::endl
    494             <<  " ===================================" << std::endl
    495             <<  "| "
    496             <<  std::setw(11) << "addr"   << " | "
    497             <<  std::setw(11) << "key"    << " | "
    498             <<  std::setw(5)  << "val"
    499             << " |" << std::endl
    500             <<  " -----------------------------------" << std::endl;
    501496        for ( size_t i = 0; i < nb_slots ; i++ )
    502497        {
    503             out << "| "
    504                 << std::showbase
    505                 << std::setw(11) << std::setfill('0')   << std::hex       << r_addr[i]    << " | "
     498            out << std::setw(3)   << std::setfill(' ') << std::dec << i
    506499                << std::noshowbase
    507                 << std::setw(11) << std::setfill('0')   << std::dec       << r_key[i]     << " | "
    508                 << std::setw(5)  << std::setfill(' ')   << std::boolalpha << r_val[i]     << " |" << std::endl ;
    509         }
    510         out <<  " -----------------------------------" << std::endl
    511             << std::noshowbase << std::dec << std::endl ;
     500                << " VLD_RX = "   << r_val[i]
     501                << std::uppercase
     502                << " ADR_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << (r_addr[i] >> 2)
     503                << " SGN_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << r_key[i]
     504                << std::endl;
     505        }
     506        out << "NEXT_SGN_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << r_next_key     << std::endl
     507            << "CNT_RX = 0x"      << std::setw(8) << std::setfill('0') << std::hex << r_last_counter << std::endl;
    512508    }
    513509
Note: See TracChangeset for help on using the changeset viewer.