lsq_impl.hh revision 3184:8edaf4539e05
14776Sgblack@eecs.umich.edu/* 24776Sgblack@eecs.umich.edu * Copyright (c) 2005-2006 The Regents of The University of Michigan 34776Sgblack@eecs.umich.edu * All rights reserved. 44776Sgblack@eecs.umich.edu * 54776Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64776Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74776Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84776Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94776Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104776Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114776Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124776Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134776Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144776Sgblack@eecs.umich.edu * this software without specific prior written permission. 154776Sgblack@eecs.umich.edu * 164776Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174776Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184776Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194776Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204776Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214776Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224776Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234776Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244776Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254776Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264776Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274776Sgblack@eecs.umich.edu * 284776Sgblack@eecs.umich.edu * Authors: Korey Sewell 294776Sgblack@eecs.umich.edu */ 304776Sgblack@eecs.umich.edu 314776Sgblack@eecs.umich.edu#include <algorithm> 324776Sgblack@eecs.umich.edu#include <list> 334776Sgblack@eecs.umich.edu#include <string> 344776Sgblack@eecs.umich.edu 354776Sgblack@eecs.umich.edu#include "cpu/o3/lsq.hh" 364776Sgblack@eecs.umich.edu 374776Sgblack@eecs.umich.edutemplate <class Impl> 384776Sgblack@eecs.umich.eduTick 394776Sgblack@eecs.umich.eduLSQ<Impl>::DcachePort::recvAtomic(PacketPtr pkt) 404776Sgblack@eecs.umich.edu{ 414776Sgblack@eecs.umich.edu panic("O3CPU model does not work with atomic mode!"); 424776Sgblack@eecs.umich.edu return curTick; 434776Sgblack@eecs.umich.edu} 444776Sgblack@eecs.umich.edu 454776Sgblack@eecs.umich.edutemplate <class Impl> 464776Sgblack@eecs.umich.eduvoid 474776Sgblack@eecs.umich.eduLSQ<Impl>::DcachePort::recvFunctional(PacketPtr pkt) 484776Sgblack@eecs.umich.edu{ 494776Sgblack@eecs.umich.edu warn("O3CPU doesn't update things on a recvFunctional."); 504776Sgblack@eecs.umich.edu} 514776Sgblack@eecs.umich.edu 524776Sgblack@eecs.umich.edutemplate <class Impl> 535038Sgblack@eecs.umich.eduvoid 544776Sgblack@eecs.umich.eduLSQ<Impl>::DcachePort::recvStatusChange(Status status) 554776Sgblack@eecs.umich.edu{ 564776Sgblack@eecs.umich.edu if (status == RangeChange) 574776Sgblack@eecs.umich.edu return; 584776Sgblack@eecs.umich.edu 594776Sgblack@eecs.umich.edu panic("O3CPU doesn't expect recvStatusChange callback!"); 604776Sgblack@eecs.umich.edu} 614776Sgblack@eecs.umich.edu 624776Sgblack@eecs.umich.edutemplate <class Impl> 634830Sgblack@eecs.umich.edubool 644830Sgblack@eecs.umich.eduLSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt) 654776Sgblack@eecs.umich.edu{ 664776Sgblack@eecs.umich.edu lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt); 674776Sgblack@eecs.umich.edu return true; 684830Sgblack@eecs.umich.edu} 694776Sgblack@eecs.umich.edu 704830Sgblack@eecs.umich.edutemplate <class Impl> 714830Sgblack@eecs.umich.eduvoid 724830Sgblack@eecs.umich.eduLSQ<Impl>::DcachePort::recvRetry() 734830Sgblack@eecs.umich.edu{ 744776Sgblack@eecs.umich.edu if (lsq->retryTid == -1) 754776Sgblack@eecs.umich.edu { 764776Sgblack@eecs.umich.edu //Squashed, so drop it 774830Sgblack@eecs.umich.edu return; 784830Sgblack@eecs.umich.edu } 794776Sgblack@eecs.umich.edu lsq->thread[lsq->retryTid].recvRetry(); 804830Sgblack@eecs.umich.edu // Speculatively clear the retry Tid. This will get set again if 814830Sgblack@eecs.umich.edu // the LSQUnit was unable to complete its access. 824830Sgblack@eecs.umich.edu lsq->retryTid = -1; 834830Sgblack@eecs.umich.edu} 844776Sgblack@eecs.umich.edu 854776Sgblack@eecs.umich.edutemplate <class Impl> 864776Sgblack@eecs.umich.eduLSQ<Impl>::LSQ(Params *params) 875049Sgblack@eecs.umich.edu : dcachePort(this), LQEntries(params->LQEntries), 885049Sgblack@eecs.umich.edu SQEntries(params->SQEntries), numThreads(params->numberOfThreads), 895049Sgblack@eecs.umich.edu retryTid(-1) 905049Sgblack@eecs.umich.edu{ 915049Sgblack@eecs.umich.edu DPRINTF(LSQ, "Creating LSQ object.\n"); 925049Sgblack@eecs.umich.edu 935049Sgblack@eecs.umich.edu //**********************************************/ 945049Sgblack@eecs.umich.edu //************ Handle SMT Parameters ***********/ 955049Sgblack@eecs.umich.edu //**********************************************/ 965049Sgblack@eecs.umich.edu std::string policy = params->smtLSQPolicy; 975049Sgblack@eecs.umich.edu 985049Sgblack@eecs.umich.edu //Convert string to lowercase 995049Sgblack@eecs.umich.edu std::transform(policy.begin(), policy.end(), policy.begin(), 1004776Sgblack@eecs.umich.edu (int(*)(int)) tolower); 1014776Sgblack@eecs.umich.edu 1024776Sgblack@eecs.umich.edu //Figure out fetch policy 1034776Sgblack@eecs.umich.edu if (policy == "dynamic") { 1044776Sgblack@eecs.umich.edu lsqPolicy = Dynamic; 1054776Sgblack@eecs.umich.edu 1064830Sgblack@eecs.umich.edu maxLQEntries = LQEntries; 1074830Sgblack@eecs.umich.edu maxSQEntries = SQEntries; 1084830Sgblack@eecs.umich.edu 1094830Sgblack@eecs.umich.edu DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n"); 1104830Sgblack@eecs.umich.edu 1114830Sgblack@eecs.umich.edu } else if (policy == "partitioned") { 1124830Sgblack@eecs.umich.edu lsqPolicy = Partitioned; 1134830Sgblack@eecs.umich.edu 1144830Sgblack@eecs.umich.edu //@todo:make work if part_amt doesnt divide evenly. 1154830Sgblack@eecs.umich.edu maxLQEntries = LQEntries / numThreads; 1164830Sgblack@eecs.umich.edu maxSQEntries = SQEntries / numThreads; 1174776Sgblack@eecs.umich.edu 1184830Sgblack@eecs.umich.edu DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: " 1194830Sgblack@eecs.umich.edu "%i entries per LQ | %i entries per SQ", 1204830Sgblack@eecs.umich.edu maxLQEntries,maxSQEntries); 1214830Sgblack@eecs.umich.edu 1224830Sgblack@eecs.umich.edu } else if (policy == "threshold") { 1234830Sgblack@eecs.umich.edu lsqPolicy = Threshold; 1244830Sgblack@eecs.umich.edu 1254830Sgblack@eecs.umich.edu assert(params->smtLSQThreshold > LQEntries); 1264830Sgblack@eecs.umich.edu assert(params->smtLSQThreshold > SQEntries); 1274830Sgblack@eecs.umich.edu 1284830Sgblack@eecs.umich.edu //Divide up by threshold amount 1294830Sgblack@eecs.umich.edu //@todo: Should threads check the max and the total 1304830Sgblack@eecs.umich.edu //amount of the LSQ 1314830Sgblack@eecs.umich.edu maxLQEntries = params->smtLSQThreshold; 1324830Sgblack@eecs.umich.edu maxSQEntries = params->smtLSQThreshold; 1334830Sgblack@eecs.umich.edu 1344830Sgblack@eecs.umich.edu DPRINTF(LSQ, "LSQ sharing policy set to Threshold: " 1354830Sgblack@eecs.umich.edu "%i entries per LQ | %i entries per SQ", 1364830Sgblack@eecs.umich.edu maxLQEntries,maxSQEntries); 1374830Sgblack@eecs.umich.edu 1384830Sgblack@eecs.umich.edu } else { 1394830Sgblack@eecs.umich.edu assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic," 1404830Sgblack@eecs.umich.edu "Partitioned, Threshold}"); 1414830Sgblack@eecs.umich.edu } 1424830Sgblack@eecs.umich.edu 1435049Sgblack@eecs.umich.edu //Initialize LSQs 1445049Sgblack@eecs.umich.edu for (int tid=0; tid < numThreads; tid++) { 1455049Sgblack@eecs.umich.edu thread[tid].init(params, this, maxLQEntries, maxSQEntries, tid); 1465049Sgblack@eecs.umich.edu thread[tid].setDcachePort(&dcachePort); 1475049Sgblack@eecs.umich.edu } 1485049Sgblack@eecs.umich.edu} 1495049Sgblack@eecs.umich.edu 1505049Sgblack@eecs.umich.edu 1515049Sgblack@eecs.umich.edutemplate<class Impl> 1525049Sgblack@eecs.umich.edustd::string 1535049Sgblack@eecs.umich.eduLSQ<Impl>::name() const 1545049Sgblack@eecs.umich.edu{ 1555049Sgblack@eecs.umich.edu return iewStage->name() + ".lsq"; 1565049Sgblack@eecs.umich.edu} 1575049Sgblack@eecs.umich.edu 1585049Sgblack@eecs.umich.edutemplate<class Impl> 1594776Sgblack@eecs.umich.eduvoid 1604830Sgblack@eecs.umich.eduLSQ<Impl>::regStats() 1614830Sgblack@eecs.umich.edu{ 1624776Sgblack@eecs.umich.edu //Initialize LSQs 1634776Sgblack@eecs.umich.edu for (int tid=0; tid < numThreads; tid++) { 1644776Sgblack@eecs.umich.edu thread[tid].regStats(); 1654776Sgblack@eecs.umich.edu } 1664776Sgblack@eecs.umich.edu} 1674830Sgblack@eecs.umich.edu 1684776Sgblack@eecs.umich.edutemplate<class Impl> 1694776Sgblack@eecs.umich.eduvoid 1704830Sgblack@eecs.umich.eduLSQ<Impl>::setActiveThreads(std::list<unsigned> *at_ptr) 1714776Sgblack@eecs.umich.edu{ 1724830Sgblack@eecs.umich.edu activeThreads = at_ptr; 1734830Sgblack@eecs.umich.edu assert(activeThreads != 0); 1744830Sgblack@eecs.umich.edu} 1754830Sgblack@eecs.umich.edu 1764830Sgblack@eecs.umich.edutemplate<class Impl> 1774830Sgblack@eecs.umich.eduvoid 1784830Sgblack@eecs.umich.eduLSQ<Impl>::setCPU(O3CPU *cpu_ptr) 1794830Sgblack@eecs.umich.edu{ 1804830Sgblack@eecs.umich.edu cpu = cpu_ptr; 1814830Sgblack@eecs.umich.edu 1824830Sgblack@eecs.umich.edu dcachePort.setName(name()); 1834830Sgblack@eecs.umich.edu 1844830Sgblack@eecs.umich.edu for (int tid=0; tid < numThreads; tid++) { 1854830Sgblack@eecs.umich.edu thread[tid].setCPU(cpu_ptr); 1864830Sgblack@eecs.umich.edu } 1874830Sgblack@eecs.umich.edu} 1884830Sgblack@eecs.umich.edu 1894830Sgblack@eecs.umich.edutemplate<class Impl> 1904830Sgblack@eecs.umich.eduvoid 1914830Sgblack@eecs.umich.eduLSQ<Impl>::setIEW(IEW *iew_ptr) 1924830Sgblack@eecs.umich.edu{ 1934830Sgblack@eecs.umich.edu iewStage = iew_ptr; 1944830Sgblack@eecs.umich.edu 1954830Sgblack@eecs.umich.edu for (int tid=0; tid < numThreads; tid++) { 1964830Sgblack@eecs.umich.edu thread[tid].setIEW(iew_ptr); 1974830Sgblack@eecs.umich.edu } 1984830Sgblack@eecs.umich.edu} 1994830Sgblack@eecs.umich.edu 2004830Sgblack@eecs.umich.edutemplate <class Impl> 2014830Sgblack@eecs.umich.eduvoid 2024830Sgblack@eecs.umich.eduLSQ<Impl>::switchOut() 2034830Sgblack@eecs.umich.edu{ 2044830Sgblack@eecs.umich.edu for (int tid = 0; tid < numThreads; tid++) { 2054830Sgblack@eecs.umich.edu thread[tid].switchOut(); 2064830Sgblack@eecs.umich.edu } 2074776Sgblack@eecs.umich.edu} 2084776Sgblack@eecs.umich.edu 2094776Sgblack@eecs.umich.edutemplate <class Impl> 2104776Sgblack@eecs.umich.eduvoid 2114776Sgblack@eecs.umich.eduLSQ<Impl>::takeOverFrom() 2124776Sgblack@eecs.umich.edu{ 2134776Sgblack@eecs.umich.edu for (int tid = 0; tid < numThreads; tid++) { 2144776Sgblack@eecs.umich.edu thread[tid].takeOverFrom(); 2154776Sgblack@eecs.umich.edu } 2164776Sgblack@eecs.umich.edu} 2174776Sgblack@eecs.umich.edu 2184776Sgblack@eecs.umich.edutemplate <class Impl> 2195038Sgblack@eecs.umich.eduint 2204776Sgblack@eecs.umich.eduLSQ<Impl>::entryAmount(int num_threads) 221{ 222 if (lsqPolicy == Partitioned) { 223 return LQEntries / num_threads; 224 } else { 225 return 0; 226 } 227} 228 229template <class Impl> 230void 231LSQ<Impl>::resetEntries() 232{ 233 if (lsqPolicy != Dynamic || numThreads > 1) { 234 int active_threads = (*activeThreads).size(); 235 236 std::list<unsigned>::iterator threads = (*activeThreads).begin(); 237 std::list<unsigned>::iterator list_end = (*activeThreads).end(); 238 239 int maxEntries; 240 241 if (lsqPolicy == Partitioned) { 242 maxEntries = LQEntries / active_threads; 243 } else if (lsqPolicy == Threshold && active_threads == 1) { 244 maxEntries = LQEntries; 245 } else { 246 maxEntries = LQEntries; 247 } 248 249 while (threads != list_end) { 250 resizeEntries(maxEntries,*threads++); 251 } 252 } 253} 254 255template<class Impl> 256void 257LSQ<Impl>::removeEntries(unsigned tid) 258{ 259 thread[tid].clearLQ(); 260 thread[tid].clearSQ(); 261} 262 263template<class Impl> 264void 265LSQ<Impl>::resizeEntries(unsigned size,unsigned tid) 266{ 267 thread[tid].resizeLQ(size); 268 thread[tid].resizeSQ(size); 269} 270 271template<class Impl> 272void 273LSQ<Impl>::tick() 274{ 275 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 276 277 while (active_threads != (*activeThreads).end()) { 278 unsigned tid = *active_threads++; 279 280 thread[tid].tick(); 281 } 282} 283 284template<class Impl> 285void 286LSQ<Impl>::insertLoad(DynInstPtr &load_inst) 287{ 288 unsigned tid = load_inst->threadNumber; 289 290 thread[tid].insertLoad(load_inst); 291} 292 293template<class Impl> 294void 295LSQ<Impl>::insertStore(DynInstPtr &store_inst) 296{ 297 unsigned tid = store_inst->threadNumber; 298 299 thread[tid].insertStore(store_inst); 300} 301 302template<class Impl> 303Fault 304LSQ<Impl>::executeLoad(DynInstPtr &inst) 305{ 306 unsigned tid = inst->threadNumber; 307 308 return thread[tid].executeLoad(inst); 309} 310 311template<class Impl> 312Fault 313LSQ<Impl>::executeStore(DynInstPtr &inst) 314{ 315 unsigned tid = inst->threadNumber; 316 317 return thread[tid].executeStore(inst); 318} 319 320template<class Impl> 321void 322LSQ<Impl>::writebackStores() 323{ 324 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 325 326 while (active_threads != (*activeThreads).end()) { 327 unsigned tid = *active_threads++; 328 329 if (numStoresToWB(tid) > 0) { 330 DPRINTF(Writeback,"[tid:%i] Writing back stores. %i stores " 331 "available for Writeback.\n", tid, numStoresToWB(tid)); 332 } 333 334 thread[tid].writebackStores(); 335 } 336} 337 338template<class Impl> 339bool 340LSQ<Impl>::violation() 341{ 342 /* Answers: Does Anybody Have a Violation?*/ 343 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 344 345 while (active_threads != (*activeThreads).end()) { 346 unsigned tid = *active_threads++; 347 if (thread[tid].violation()) 348 return true; 349 } 350 351 return false; 352} 353 354template<class Impl> 355int 356LSQ<Impl>::getCount() 357{ 358 unsigned total = 0; 359 360 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 361 362 while (active_threads != (*activeThreads).end()) { 363 unsigned tid = *active_threads++; 364 total += getCount(tid); 365 } 366 367 return total; 368} 369 370template<class Impl> 371int 372LSQ<Impl>::numLoads() 373{ 374 unsigned total = 0; 375 376 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 377 378 while (active_threads != (*activeThreads).end()) { 379 unsigned tid = *active_threads++; 380 total += numLoads(tid); 381 } 382 383 return total; 384} 385 386template<class Impl> 387int 388LSQ<Impl>::numStores() 389{ 390 unsigned total = 0; 391 392 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 393 394 while (active_threads != (*activeThreads).end()) { 395 unsigned tid = *active_threads++; 396 total += thread[tid].numStores(); 397 } 398 399 return total; 400} 401 402template<class Impl> 403int 404LSQ<Impl>::numLoadsReady() 405{ 406 unsigned total = 0; 407 408 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 409 410 while (active_threads != (*activeThreads).end()) { 411 unsigned tid = *active_threads++; 412 total += thread[tid].numLoadsReady(); 413 } 414 415 return total; 416} 417 418template<class Impl> 419unsigned 420LSQ<Impl>::numFreeEntries() 421{ 422 unsigned total = 0; 423 424 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 425 426 while (active_threads != (*activeThreads).end()) { 427 unsigned tid = *active_threads++; 428 total += thread[tid].numFreeEntries(); 429 } 430 431 return total; 432} 433 434template<class Impl> 435unsigned 436LSQ<Impl>::numFreeEntries(unsigned tid) 437{ 438 //if( lsqPolicy == Dynamic ) 439 //return numFreeEntries(); 440 //else 441 return thread[tid].numFreeEntries(); 442} 443 444template<class Impl> 445bool 446LSQ<Impl>::isFull() 447{ 448 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 449 450 while (active_threads != (*activeThreads).end()) { 451 unsigned tid = *active_threads++; 452 if (! (thread[tid].lqFull() || thread[tid].sqFull()) ) 453 return false; 454 } 455 456 return true; 457} 458 459template<class Impl> 460bool 461LSQ<Impl>::isFull(unsigned tid) 462{ 463 //@todo: Change to Calculate All Entries for 464 //Dynamic Policy 465 if( lsqPolicy == Dynamic ) 466 return isFull(); 467 else 468 return thread[tid].lqFull() || thread[tid].sqFull(); 469} 470 471template<class Impl> 472bool 473LSQ<Impl>::lqFull() 474{ 475 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 476 477 while (active_threads != (*activeThreads).end()) { 478 unsigned tid = *active_threads++; 479 if (!thread[tid].lqFull()) 480 return false; 481 } 482 483 return true; 484} 485 486template<class Impl> 487bool 488LSQ<Impl>::lqFull(unsigned tid) 489{ 490 //@todo: Change to Calculate All Entries for 491 //Dynamic Policy 492 if( lsqPolicy == Dynamic ) 493 return lqFull(); 494 else 495 return thread[tid].lqFull(); 496} 497 498template<class Impl> 499bool 500LSQ<Impl>::sqFull() 501{ 502 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 503 504 while (active_threads != (*activeThreads).end()) { 505 unsigned tid = *active_threads++; 506 if (!sqFull(tid)) 507 return false; 508 } 509 510 return true; 511} 512 513template<class Impl> 514bool 515LSQ<Impl>::sqFull(unsigned tid) 516{ 517 //@todo: Change to Calculate All Entries for 518 //Dynamic Policy 519 if( lsqPolicy == Dynamic ) 520 return sqFull(); 521 else 522 return thread[tid].sqFull(); 523} 524 525template<class Impl> 526bool 527LSQ<Impl>::isStalled() 528{ 529 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 530 531 while (active_threads != (*activeThreads).end()) { 532 unsigned tid = *active_threads++; 533 if (!thread[tid].isStalled()) 534 return false; 535 } 536 537 return true; 538} 539 540template<class Impl> 541bool 542LSQ<Impl>::isStalled(unsigned tid) 543{ 544 if( lsqPolicy == Dynamic ) 545 return isStalled(); 546 else 547 return thread[tid].isStalled(); 548} 549 550template<class Impl> 551bool 552LSQ<Impl>::hasStoresToWB() 553{ 554 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 555 556 if ((*activeThreads).empty()) 557 return false; 558 559 while (active_threads != (*activeThreads).end()) { 560 unsigned tid = *active_threads++; 561 if (!hasStoresToWB(tid)) 562 return false; 563 } 564 565 return true; 566} 567 568template<class Impl> 569bool 570LSQ<Impl>::willWB() 571{ 572 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 573 574 while (active_threads != (*activeThreads).end()) { 575 unsigned tid = *active_threads++; 576 if (!willWB(tid)) 577 return false; 578 } 579 580 return true; 581} 582 583template<class Impl> 584void 585LSQ<Impl>::dumpInsts() 586{ 587 std::list<unsigned>::iterator active_threads = (*activeThreads).begin(); 588 589 while (active_threads != (*activeThreads).end()) { 590 unsigned tid = *active_threads++; 591 thread[tid].dumpInsts(); 592 } 593} 594