Differentiate preemption from yielding.
Yielding is voluntary and indicates something else should be given the
chance to run. Preemption is involuntary and indicates the vCPU still
wants to run.
Change-Id: I9ba2445c3d67ea140bf33005a08084b29457e42f
diff --git a/src/api.c b/src/api.c
index 004122f..8ff3b60 100644
--- a/src/api.c
+++ b/src/api.c
@@ -76,8 +76,21 @@
}
/**
- * Returns to the primary vm leaving the current vcpu ready to be scheduled
- * again.
+ * Returns to the primary vm and signals that the vcpu still has work to do so.
+ */
+struct vcpu *api_preempt(struct vcpu *current)
+{
+ struct hf_vcpu_run_return ret = {
+ .code = HF_VCPU_RUN_PREEMPTED,
+ };
+
+ return api_switch_to_primary(current, ret, vcpu_state_ready);
+}
+
+/**
+ * Returns to the primary vm to allow this cpu to be used for other tasks as the
+ * vcpu does not have work to do at this moment. The current vcpu is marked as
+ * ready to be scheduled again.
*/
struct vcpu *api_yield(struct vcpu *current)
{
@@ -240,10 +253,16 @@
goto out;
}
+ /* Switch to the vcpu. */
*next = vcpu;
- ret.code = HF_VCPU_RUN_YIELD;
- /* Update return value if one was injected. */
+ /*
+ * Set a placeholder return code to the scheduler. This will be
+ * overwritten when the switch back to the primary occurs.
+ */
+ ret.code = HF_VCPU_RUN_PREEMPTED;
+
+ /* Update return value for the next vcpu if one was injected. */
if (vcpu_retval.force) {
arch_regs_set_retval(&vcpu->regs, vcpu_retval.value);
}