| 560 | // to be as optimized as possible. This is the heart of avida. |
| 561 | |
| 562 | bool cHardwareExperimental::SingleProcess(cAvidaContext& ctx, bool speculative) |
| 563 | { |
| 564 | assert(!speculative || (speculative && !m_thread_slicing_parallel)); |
| 565 | |
| 566 | // Mark this organism as running... |
| 567 | m_organism->SetRunning(true); |
| 568 | |
| 569 | if (!speculative && m_spec_die) { |
| 570 | m_organism->Die(ctx); |
| 571 | m_organism->SetRunning(false); |
| 572 | return false; |
| 573 | } |
| 574 | |
| 575 | cPhenotype& phenotype = m_organism->GetPhenotype(); |
| 576 | |
| 577 | // First instruction - check whether we should be starting at a promoter, when enabled. |
| 578 | if (phenotype.GetCPUCyclesUsed() == 0 && m_promoters_enabled) PromoterTerminate(ctx); |
| 579 | |
| 580 | m_cycle_count++; |
| 581 | phenotype.IncCPUCyclesUsed(); |
| 582 | if (!m_no_cpu_cycle_time) phenotype.IncTimeUsed(); |
| 583 | |
| 584 | // If we have threads turned on and we executed each thread in a single |
| 585 | // timestep, adjust the number of instructions executed accordingly. |
| 586 | const int num_inst_exec = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1) ? m_threads.GetSize() : 1; |
| 587 | |
| 588 | int num_active = 0; |
| 589 | for (int i = 0; i < m_threads.GetSize(); i++) { |
| 590 | if (m_threads[i].active) num_active++; |
| 591 | } |
| 592 | assert(num_active == (m_threads.GetSize() - m_waiting_threads)); |
| 593 | |
| 594 | for (int i = 0; i < num_inst_exec; i++) { |
| 595 | // Setup the hardware for the next instruction to be executed. |
| 596 | int last_thread = m_cur_thread++; |
| 597 | if (m_cur_thread >= m_threads.GetSize()) m_cur_thread = 0; |
| 598 | |
| 599 | // If the currently selected thread is inactive, proceed to the next thread |
| 600 | if (!m_threads[m_cur_thread].active) { |
| 601 | if (num_inst_exec == 1) i--; // When running in non-parallel mode, adjust i so that we will continue to loop |
| 602 | continue; |
| 603 | } |
| 604 | |
| 605 | m_advance_ip = true; |
| 606 | cHeadCPU& ip = m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; |
| 607 | ip.Adjust(); |
| 608 | |
| 609 | /* if (m_organism->GetID() == 0 && m_world->GetStats().GetUpdate() >= 0) cout << " org: " << m_organism->GetID() |
| 610 | << " thread: " << m_cur_thread << " ip_position: " << ip.GetPosition() << " inst: " |
| 611 | << m_inst_set->GetInstLib()->Get(m_inst_set->GetLibFunctionIndex(ip.GetInst())).GetName() |
| 612 | << " write head: " << m_threads[m_cur_thread].heads[nHardware::HEAD_WRITE].GetPosition() |
| 613 | << " flow head: " << m_threads[m_cur_thread].heads[nHardware::HEAD_WRITE].GetPosition() |
| 614 | << " cell: " << m_organism->GetOrgInterface().GetAVCellID() << endl; */ |
| 615 | |
| 616 | // Print the status of this CPU at each step... |
| 617 | if (m_tracer) m_tracer->TraceHardware(ctx, *this); |
| 618 | |
| 619 | // Find the instruction to be executed |
nothing calls this directly
no test coverage detected