inline void MESI_protocol::do_cache_M (Mreq *request) { switch (request->msg) { /* The M state means we have the data and we can modify it. Therefore any request * from the processor (read or write) can be immediately satisfied. */ case LOAD: case STORE: /* This is how you send data back to the processor to finish the request * Note: There was no need to send anything on the bus on a hit. */ send_DATA_to_proc(request->addr); break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: M state shouldn't see this message\n"); } }
inline void MESI_protocol::do_snoop_SM (Mreq *request) { switch (request->msg) { case GETS: set_shared_line(true); // Set line to shared because others are getting the data break; case GETM: break; case DATA: // Send the data up, set shared=false since we have the data send_DATA_to_proc(request->addr); state = MESI_CACHE_M; set_shared_line(false); break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client SnoopSM state shouldn't see this message\n"); } }
inline void MESI_protocol::do_cache_S (Mreq *request) { switch(request->msg) { case LOAD: // already have it, send it send_DATA_to_proc(request->addr); break; case STORE: // move to the intermediate state, another miss send_GETM(request->addr); state = MESI_CACHE_SM; Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: CacheS state shouldn't see this message\n"); } }
inline void MOSI_protocol::do_snoop_SM (Mreq *request){ switch (request->msg) { case GETS: set_shared_line(); break; case GETM: state = MOSI_CACHE_IM; Sim->cache_misses++; break; case DATA: send_DATA_to_proc(request->addr); state = MOSI_CACHE_M; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: SM state shouldn't see this message\n"); } }
inline void MOESI_protocol::do_snoop_SM (Mreq *request) { switch (request->msg) { case GETS: set_shared_line(); if(-1!=Owner_nodeID) { //give data send_DATA_on_bus(request->addr,request->src_mid); } break; case GETM: if( (-1!=Owner_nodeID) && (false==get_shared_line()) ) { //give data set_shared_line(); send_DATA_on_bus(request->addr,request->src_mid); } if (request->src_mid.nodeID != Owner_nodeID) { //Change state state = MOESI_CACHE_IM; Owner_nodeID = -1; } break; case DATA: Owner_nodeID = -1; //Get data send_DATA_to_proc(request->addr); //Change to modify state state = MOESI_CACHE_M; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: State shouldn't see this message\n"); } }
inline void MOESI_protocol::do_snoop_SM_Intermediate (Mreq *request) { switch (request->msg) { case GETS: set_shared_line(); case GETM: if (request->src_mid != my_table->moduleID){ state = MOESI_CACHE_IM_Intermediate; } break; case DATA: send_DATA_to_proc(request->addr); state = MOESI_CACHE_M; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: I state shouldn't see this message\n"); } }
inline void MOESI_protocol::do_cache_O (Mreq *request) { switch (request->msg) { case LOAD: //data is clean and can be sent to the processor send_DATA_to_proc(request->addr); break; case STORE: //put the request on the bus for block with the intent to modify //this will lead to a cache miss send_GETM(request->addr); state = MOESI_CACHE_OM_Intermediate; Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: I state shouldn't see this message\n"); } }
inline void MOESIF_protocol::do_cache_S (Mreq *request) { /* In S we provide data when LOAD requested and transition to M when STORE requested */ switch (request->msg) { case LOAD: send_DATA_to_proc(request->addr); break; case STORE: send_GETM(request->addr); state = MOESIF_CACHE_SM; Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: S state shouldn't see this message\n"); } }
inline void MSI_protocol::do_snoop_IS (Mreq *request) { switch (request->msg) { case GETS: case GETM: break; case DATA: send_DATA_to_proc(request->addr); state = MSI_CACHE_S; if (get_shared_line()) { } break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: IS state shouldn't see this message\n"); } }
inline void MOESIF_protocol::do_cache_F (Mreq *request) { /* In forwarder mode, we act the same as S when a LOAD is requested and similar to S when M is requested, but go to the FM state instead */ switch (request->msg) { case LOAD: send_DATA_to_proc(request->addr); break; case STORE: send_GETM(request->addr); state = MOESIF_CACHE_FM; Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: S state shouldn't see this message\n"); } }
inline void MOESIF_protocol::do_snoop_FM (Mreq *request) { switch (request->msg) { case GETS: set_shared_line(); // Set shared line to prevent other nodes going to E send_DATA_on_bus(request->addr,request->src_mid); break; case GETM: set_shared_line(); // Set shared line to prevent other nodes going to E send_DATA_on_bus(request->addr,request->src_mid); break; case DATA: send_DATA_to_proc(request->addr); state = MOESIF_CACHE_M; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: IM state shouldn't see this message\n"); } }
inline void MOESIF_protocol::do_snoop_OM (Mreq *request) { switch (request->msg) { case GETS: case GETM: set_shared_line(); send_DATA_on_bus(request->addr,request->src_mid); break; case DATA: send_DATA_to_proc(request->addr); state = MOESIF_CACHE_M; if (get_shared_line()) { } break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: OM state shouldn't see this message\n"); } }
inline void TYPE(_protocol)::do_cache_O (Mreq *request) { switch (request->msg) { /* Like F but now its dirty */ case LOAD://we can haz data, so yay! send_DATA_to_proc(request->addr); break; case STORE://we can haz dataz, But cant use the dataz we can haz send_GETM(request->addr); state = TYPE(_CACHE_FM); /* This is a cache miss */ Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: O state shouldn't see this message\n"); } }
inline void TYPE(_protocol)::do_snoop_IM (Mreq *request) { switch (request->msg) { /* See cache function with same state for description of this state */ case GETS: case GETM: break; case DATA://finaly can haz datas, and now we can //change it, so noone eles can haz them send_DATA_to_proc(request->addr); state = TYPE(_CACHE_M); break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: IM state shouldn't see this message\n"); } }
inline void MESI_protocol::do_snoop_IS (Mreq *request) { switch (request->msg) { case GETS: case GETM: break; case DATA: // Send the data up send_DATA_to_proc(request->addr); // Check if there are other copies in other processors. If so // then we go to the shared state, otherwise go to exclusive if (get_shared_line()) state = MESI_CACHE_S; else { state = MESI_CACHE_E; set_shared_line(false); } break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client SnoopIS state shouldn't see this message\n"); } }
inline void TYPE(_protocol)::do_snoop_IE (Mreq *request) { switch (request->msg) { /* See cache function with same state for description of this state */ case GETS: case GETM: break; case DATA://we finaly can has dataz // if anyone else says they haz the data then we go to S // otherwize they are jerks, an so we /deserve/ exclusive // access send_DATA_to_proc(request->addr); state = TYPE(_CACHE_S); break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: IE state shouldn't see this message\n"); } }
inline void MOESI_protocol::do_cache_S (Mreq *request) { switch (request->msg) { case LOAD: //Data is already there in cache line send_DATA_to_proc(request->addr); break; case STORE: /* Line up the GETM in the Bus' queue */ send_GETM(request->addr); /* Move to M-state*/ state = MOESI_CACHE_SM; // We will still get data from memory as we have placed GetM on memory Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: I state shouldn't see this message\n"); } }
inline void TYPE(_protocol)::do_snoop_FM (Mreq *request) { switch (request->msg) { /* See cache function with same state for description of this state */ case GETM: // if someone writes to the dataz, then invalidate state = TYPE(_CACHE_IM); case GETS://technically in F , so give the dataz to the other guy send_DATA_on_bus(request->addr,request->src_mid); set_shared_line(); break; case DATA: // can haz dataz send_DATA_to_proc(request->addr); state = TYPE(_CACHE_M); break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: FM state shouldn't see this message\n"); } }
inline void MSI_protocol::do_snoop_IM (Mreq *request) { switch (request->msg) { case GETS: case GETM: /** While in IM we will see our own GETS or GETM on the bus, there is no practical * way, in this project, to detect that the request is our own. We may also see other * caches make GETS or GETM requests. Since we came from I, we can ignore these * requests and wait for DATA to show up. In other protocols with other intermediate * states, the cache will have come from a different state, and then * it might need to respond and possibly transition while waiting to receive data. */ break; case DATA: /** IM state meant that the block had sent the GET and was waiting on DATA. * Now that Data is received we can send the DATA to the processor and finish * the transition to M. */ /** * Note we use get_shared_line() here to demonstrate its use. * (Hint) The shared line indicates when another cache has a copy and is useful * for knowing when to go to the E/S state. * Since we only have I and M state in the MI protocol, what the shared line * means here is whether a cache sent the data or the memory controller. */ send_DATA_to_proc(request->addr); state = MSI_CACHE_M; if (get_shared_line()) { // Nothing to do for MI protocol } break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: IM state shouldn't see this message\n"); } }
inline void MOESI_protocol::do_cache_O (Mreq *request) { switch (request->msg) { case LOAD: //Data is already there in cache line send_DATA_to_proc(request->addr); break; case STORE: Owner_nodeID = request->src_mid.nodeID; /* Line up the GETM in the Bus' queue */ send_GETM(request->addr); /* Move to M-state*/ state = MOESI_CACHE_SM; // Owner has the data. Still it is treated as coherence miss. Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: I state shouldn't see this message\n"); } }
inline void MOESIF_protocol::do_snoop_IS (Mreq *request) { switch (request->msg) { case GETS: break; case GETM: break; case DATA: send_DATA_to_proc(request->addr); /* Once we receive the data in IS, we check the shared line to see if any other nodes currently have this data; if they don't we go to E, otherwise we go to S. */ if (get_shared_line()) { state = MOESIF_CACHE_S; } else { state = MOESIF_CACHE_E; } break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: IS state shouldn't see this message\n"); } }
inline void TYPE(_protocol)::do_cache_S (Mreq *request) { switch (request->msg) { /* This is like F but not allowed to send datas */ case LOAD: //can haz datas, so no problemz send_DATA_to_proc(request->addr); break; case STORE: //same as F, we can haz dataz, but have to //pretend that we not can haz datas. send_GETM(request->addr); state = TYPE(_CACHE_SM); /* This is a cache miss */ Sim->cache_misses++; break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: S state shouldn't see this message\n"); } }
inline void TYPE(_protocol)::do_snoop_SM (Mreq *request) { switch (request->msg) { /* See cache function with same state for description of this state */ case GETM://if we see someones GETM we invalidate our dataz, // so it is like we were in invalid before the CPU // asked for the memories state = TYPE(_CACHE_IM); case GETS://those jerks are reading whil im trying to write set_shared_line(); break; case DATA://YAY! we can finaly haz dataz send_DATA_to_proc(request->addr); state = TYPE(_CACHE_M); break; default: request->print_msg (my_table->moduleID, "ERROR"); fatal_error ("Client: SM state shouldn't see this message\n"); } }