/** @brief private structure for N3 */
typedef struct {
- n4_opmode cur_opmode;
+ n4_opmode input_opmode;
output_ready n2_cb;
+ model *model;
+ list running_ops;
} scheduler_priv;
/** @brief N3 internal private data */
* @param[in] op npu_input_opmode
* @return n4_opmode
*/
-static n4_opmode
+static n4_opmode
opmode_npu_to_n4 (npu_input_opmode op)
{
switch (op) {
}
/**
- * @brief request configure() for all submodels to N4
+ * @brief request stop() for all submodels to N4
+ * @param[in] op n4_opmode
+ * @param[in] stop_cond stopping condition for n4x
+ * @return 0 if ok, otherwise a negative errrno
+ */
+static int
+stop_all_services (model *model, stop_condition stop_cond)
+{
+ submodel *smodel;
+ int err = 0;
+ n4_opmode op;
+
+ assert (model);
+
+ list_for_each_entry (smodel, model->submodels, list) {
+ op = (n4_opmode) smodel->meta->type;
+ if ((err = n4_stop (op, stop_cond)) < 0) {
+ logerr (TAG, "Error stopping the model with op %d\n", op);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief request start() for all submodels to N4
* @param[in] op n4_opmode
+ * @return 0 if ok, otherwise a negative errrno
+ */
+static int
+start_all_services (model *model)
+{
+ submodel *smodel;
+ int err;
+ n4_opmode op;
+
+ assert (model);
+
+ list_for_each_entry (smodel, model->submodels, list) {
+ op = (n4_opmode) smodel->meta->type;
+ if ((err = n4_start (op)) < 0) {
+ stop_all_services (model, STOP_PREEMPT);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief request configure() for all submodels to N4
+ * @param[in] input_op input service op
* @param[in] model model
* @param[in] cb output ready callback
* @param[in] cb_data callback data
* @return 0 if ok, otherwise a negative errrno
*/
static int
-config_all_submodels (n4_opmode op, model *model, output_ready cb, void *cb_data)
+config_all_services (model *model, output_ready cb, void *cb_data)
{
submodel *smodel;
int err;
+ n4_opmode op;
assert (model);
list_for_each_entry (smodel, model->submodels, list) {
+ op = (n4_opmode) smodel->meta->type;
if ((err = n4_configure (op, smodel, cb, cb_data)) < 0)
return err;
}
int n3_setOpMode(npu_input_opmode op, int force, model *model,
output_ready cb, void *cb_data)
{
- n4_opmode n4_op;
+ n4_opmode n4_input_op;
int err;
+ stop_condition stop_cond;
if (!model) {
logerr (TAG, "A valid model was not provided\n");
return -EINVAL;
}
+ stop_cond = force ? STOP_PREEMPT : STOP_TRY;
if (op == NPUINPUT_STOP) {
- if (spriv.cur_opmode == N4_OPS_END) {
+ if (spriv.input_opmode == N4_OPS_END) {
logerr (TAG, "No input service was working\n");
return -EINVAL;
}
- if ((err = n4_stop (spriv.cur_opmode, force ? STOP_PREEMPT : STOP_TRY)) == 0)
- spriv.cur_opmode = N4_OPS_END;
+ if ((err = stop_all_services (spriv.model, stop_cond)) != 0) {
+ logerr (TAG, "Error stopping the model\n");
+ }
+ spriv.input_opmode = N4_OPS_END;
+ spriv.model = NULL;
return err;
}
/* start */
- n4_op = opmode_npu_to_n4 (op);
- if (n4_op == N4_OPS_END) {
+ n4_input_op = opmode_npu_to_n4 (op);
+ if (n4_input_op == N4_OPS_END) {
logerr (TAG, "Unknown npu input opmode (%d)\n", op);
return -EINVAL;
}
- if (spriv.cur_opmode != N4_OPS_END) {
+ if (spriv.input_opmode != N4_OPS_END) {
/* wait or preempt the previous one */
- if ((err = n4_stop (spriv.cur_opmode, force ? STOP_PREEMPT : STOP_WAIT)) != 0)
+ if ((err = stop_all_services (spriv.model, stop_cond)) != 0) {
+ logerr (TAG, "Error stopping the model\n");
return err;
+ }
}
spriv.n2_cb = cb;
- if ((err = config_all_submodels (n4_op, model, n3_cb, cb_data)) < 0)
+ if ((err = config_all_services (model, n3_cb, cb_data)) < 0) {
+ logerr (TAG, "Error configuring the submodels\n");
return err;
+ }
- if ((err = n4_start (n4_op)) < 0)
+ if ((err = start_all_services (model)) < 0) {
+ logerr (TAG, "Error starting the submodels\n");
return err;
+ }
- spriv.cur_opmode = n4_op;
+ spriv.input_opmode = n4_input_op;
+ spriv.model = model;
return 0;
}
*/
int n3_dataReady(void)
{
- if (spriv.cur_opmode == N4_OPS_END) {
+ if (spriv.input_opmode == N4_OPS_END) {
logerr (TAG, "No input service yet\n");
return -EINVAL;
}
+ if (spriv.input_opmode != N4_OPS_HOST_INPUT) {
+ logerr (TAG, "Operation only permitted for host input mode\n");
+ return -EPERM;
+ }
+
return n4_dataReady ();
}
*/
void init_ne_scheduler (void)
{
- spriv.cur_opmode = N4_OPS_END;
+ spriv.input_opmode = N4_OPS_END;
spriv.n2_cb = NULL;
+ spriv.model = NULL;
}