No public description PiperOrigin-RevId: 819273859 Change-Id: Ia3707c1db285a8807c64e377bf4a5aaf00570bfc
diff --git a/riscv/riscv_top.cc b/riscv/riscv_top.cc index 8472281..b0ae232 100644 --- a/riscv/riscv_top.cc +++ b/riscv/riscv_top.cc
@@ -279,6 +279,7 @@ run_status_ = RunStatus::kSingleStep; int count = 0; halted_ = false; + paused_ = false; halt_reason_ = *HaltReason::kNone; // First check to see if the previous halt was due to a breakpoint. If so, // need to step over the breakpoint. @@ -289,6 +290,7 @@ run_status_ = RunStatus::kHalted; return status; } + paused_ |= halted_; count++; } @@ -303,7 +305,7 @@ // be executed. uint64_t next_pc = pc_operand->AsUint64(0); pc = next_pc; - while (!halted_ && (count < num)) { + while (!paused_ && (count < num)) { SetPc(pc); auto* inst = rv_decode_cache_->GetDecodedInstruction(pc); // Set the next_pc to the next sequential instruction. @@ -323,6 +325,7 @@ state_->TakeAvailableInterrupt(epc); // Will set state_->branch(). } } while (!executed); + paused_ |= halted_; count++; // Update counters. counter_opcode_[inst->opcode()].Increment(1); @@ -334,7 +337,7 @@ AddToBranchTrace(pc, pc_val); next_pc = pc_val; } - if (!halted_) { + if (!paused_) { pc = next_pc; continue; } @@ -343,10 +346,11 @@ auto status = StepPastBreakpoint(); if (!status.ok()) { run_status_ = RunStatus::kHalted; + halted_ = true; return status; } // Reset the halt reason and continue; - halted_ = false; + paused_ = halted_; halt_reason_ = *HaltReason::kNone; need_to_step_over_ = false; continue; @@ -391,6 +395,7 @@ std::thread([this]() { run_status_ = RunStatus::kRunning; halted_ = false; + paused_ = false; halt_reason_ = *HaltReason::kNone; run_started_->Notify(); auto pc_operand = state_->pc_operand(); @@ -401,7 +406,7 @@ // This holds the value of the current pc, and post-loop, the address of // the most recently executed instruction. uint64_t pc = next_pc; - while (!halted_) { + while (!paused_) { auto* inst = rv_decode_cache_->GetDecodedInstruction(pc); SetPc(pc); next_pc = pc + inst->size(); @@ -423,6 +428,7 @@ state_->TakeAvailableInterrupt(epc); // Will set state_->branch(). } } while (!executed); + paused_ |= halted_; // Update counters. counter_opcode_[inst->opcode()].Increment(1); counter_num_instructions_.Increment(1); @@ -433,7 +439,7 @@ AddToBranchTrace(pc, pc_val); next_pc = pc_val; } - if (!halted_) { + if (!paused_) { pc = next_pc; continue; } @@ -447,7 +453,7 @@ break; }; // Reset the halt reason and continue; - halted_ = false; + paused_ = halted_; halt_reason_ = *HaltReason::kNone; need_to_step_over_ = false; continue; @@ -814,7 +820,16 @@ const Instruction* inst) { // First set the halt_reason_, then the halt flag. halt_reason_ = halt_reason; - halted_ = true; + // Action point halts are always called from the thread that is executing the + // instructions. In this case we set paused_ to true, and not halted_, since + // we want to keep running after the action point by resetting paused_. If we + // use halted_ there would be a race condition between clearing halted_ and + // an asynchronous halt request from a different thread. + if (halt_reason == *HaltReason::kActionPoint) { + paused_ = true; + } else { + halted_ = true; + } // If the halt reason is either sw breakpoint or action point, set // need_to_step_over to true. if ((halt_reason_ == *HaltReason::kSoftwareBreakpoint) ||
diff --git a/riscv/riscv_top.h b/riscv/riscv_top.h index 171ef9c..22ca7f9 100644 --- a/riscv/riscv_top.h +++ b/riscv/riscv_top.h
@@ -179,6 +179,9 @@ HaltReasonValueType halt_reason_ = *HaltReason::kNone; // Halting flag. This is set to true when execution must halt. bool halted_ = false; + // Paused flag. This is set to true when execution must pause due to an action + // point or breakpoint. + bool paused_ = false; // Set to true if the next instruction requires a step-over. bool need_to_step_over_ = false; absl::Notification* run_halted_ = nullptr;