ovni/test/emu/nosv/task-pause-from-submit.c
Rodrigo Arias 4b4f1bd218 Don't modify nOS-V subsystem state on task pause
In nOS-V, when a task was paused via the VTp event, two things were
happening: 1) the task state was set to pause and 2) the subsystem state
"Task: Running" was being popped.

This causes a problem when a task calls nosv_submit() in blocking mode,
as it will call nosv_pause() which will emit a VTp event from a
subsystem different than "Task: Running".

To solve this conflict, we handle the subsystems state and the task
state separately with the VTp and VTr events. The subsystem state "Task:
Running" no longer is connected to the state of the task and only shows
if we entered the body of the task or not. It has now been renamed to
"Task: In body".

The new state "Task: In body" represents that the task body has begun
the execution and is still in the stack, but the task may be paused. The
subsystem is not changed by the VTp (pause) or VTr (resume) events.

Fixes: https://pm.bsc.es/gitlab/rarias/ovni/-/issues/128
2023-10-23 11:26:17 +02:00

69 lines
1.9 KiB
C

/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <stdint.h>
#include <stdio.h>
#include "common.h"
#include "emu_prv.h"
#include "instr.h"
#include "instr_nosv.h"
#include "emu/nosv/nosv_priv.h"
int
main(void)
{
/* Tests the case where a task is paused from nosv_submit():
*
* A VTp event causes a pop of the subsystem channel, which is expected
* to be ST_TASK_RUNNING. This is not true in the case of a blocking
* submit (NOSV_SUBMIT_BLOCKING), which calls nosv_pause from inside
* nosv_submit, causing the transition to happen from the unexpected
* ST_API_SUBMIT state.
*/
instr_start(0, 1);
/* Match the PRV line in the trace */
FILE *f = fopen("match.sh", "w");
if (f == NULL)
die("fopen failed:");
uint32_t typeid = 100;
instr_nosv_type_create(typeid);
instr_nosv_task_create(1, typeid);
instr_nosv_task_execute(1);
/* When starting a task, it must cause the subsystems to enter
* the "Task: In body" state */
int prvtype = PRV_NOSV_SUBSYSTEM;
int st = ST_TASK_BODY;
fprintf(f, "grep ':%ld:%d:%d$' ovni/thread.prv\n", get_delta(), prvtype, st);
fprintf(f, "grep ':%ld:%d:%d$' ovni/cpu.prv\n", get_delta(), prvtype, st);
instr_nosv_submit_enter(); /* Blocking submit */
instr_nosv_task_pause(1);
/* Should be left in the submit state, so no state transition in
* subsystems view */
fprintf(f, "! grep ':%ld:%d:[0-9]*$' ovni/thread.prv\n", get_delta(), prvtype);
fprintf(f, "! grep ':%ld:%d:[0-9]*$' ovni/cpu.prv\n", get_delta(), prvtype);
/* But the task state must be set to pause, so the task id
* must be null */
prvtype = PRV_NOSV_TASKID;
fprintf(f, "grep ':%ld:%d:0$' ovni/thread.prv\n", get_delta(), prvtype);
fprintf(f, "grep ':%ld:%d:0$' ovni/cpu.prv\n", get_delta(), prvtype);
instr_nosv_submit_exit();
instr_nosv_task_resume(1);
instr_nosv_task_end(1);
fclose(f);
instr_end();
return 0;
}