ocf/src/utils/utils_pipeline.c
Robert Baldyga 8a82be339f Introduce asynchronous cache lock
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
2019-05-28 11:20:48 +02:00

132 lines
2.8 KiB
C

/*
* Copyright(c) 2019 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include "ocf/ocf.h"
#include "../engine/cache_engine.h"
#include "../engine/engine_common.h"
#include "../ocf_request.h"
#include "utils_pipeline.h"
struct ocf_pipeline {
struct ocf_pipeline_properties *properties;
struct ocf_request *req;
int next_step;
int next_arg;
bool finish;
int error;
void *priv;
};
static int _ocf_pipeline_run_step(struct ocf_request *req)
{
ocf_pipeline_t pipeline = req->priv;
struct ocf_pipeline_step *step;
ocf_pipeline_arg_t arg;
if (pipeline->finish) {
pipeline->properties->finish(pipeline, pipeline->priv,
pipeline->error);
return 0;
}
while (true) {
step = &pipeline->properties->steps[pipeline->next_step];
switch (step->type) {
case ocf_pipeline_step_single:
pipeline->next_step++;
step->hndl(pipeline, pipeline->priv, &step->arg);
return 0;
case ocf_pipeline_step_foreach:
arg = &step->args[pipeline->next_arg++];
if (arg->type == ocf_pipeline_arg_terminator) {
pipeline->next_arg = 0;
pipeline->next_step++;
continue;
}
step->hndl(pipeline, pipeline->priv, arg);
return 0;
case ocf_pipeline_step_terminator:
pipeline->properties->finish(pipeline, pipeline->priv,
pipeline->error);
return 0;
default:
ENV_BUG();
}
}
return 0;
}
static const struct ocf_io_if _io_if_pipeline = {
.read = _ocf_pipeline_run_step,
.write = _ocf_pipeline_run_step,
};
int ocf_pipeline_create(ocf_pipeline_t *pipeline, ocf_cache_t cache,
struct ocf_pipeline_properties *properties)
{
ocf_pipeline_t tmp_pipeline;
struct ocf_request *req;
tmp_pipeline = env_vzalloc(sizeof(*tmp_pipeline) +
properties->priv_size);
if (!tmp_pipeline)
return -OCF_ERR_NO_MEM;
if (properties->priv_size > 0) {
tmp_pipeline->priv = (void *)tmp_pipeline +
sizeof(*tmp_pipeline);
}
req = ocf_req_new(cache->mngt_queue, NULL, 0, 0, 0);
if (!req) {
env_vfree(tmp_pipeline);
return -OCF_ERR_NO_MEM;
}
tmp_pipeline->properties = properties;
tmp_pipeline->req = req;
tmp_pipeline->next_step = 0;
tmp_pipeline->finish = false;
tmp_pipeline->error = 0;
req->info.internal = true;
req->io_if = &_io_if_pipeline;
req->priv = tmp_pipeline;
*pipeline = tmp_pipeline;
return 0;
}
void ocf_pipeline_destroy(ocf_pipeline_t pipeline)
{
ocf_req_put(pipeline->req);
env_vfree(pipeline);
}
void ocf_pipeline_set_priv(ocf_pipeline_t pipeline, void *priv)
{
pipeline->priv = priv;
}
void *ocf_pipeline_get_priv(ocf_pipeline_t pipeline)
{
return pipeline->priv;
}
void ocf_pipeline_next(ocf_pipeline_t pipeline)
{
ocf_engine_push_req_front(pipeline->req, true);
}
void ocf_pipeline_finish(ocf_pipeline_t pipeline, int error)
{
pipeline->finish = true;
pipeline->error = error;
ocf_engine_push_req_front(pipeline->req, true);
}