#include "pipeline_common.h"
worker_generic(void *arg)
{
    struct worker_data *data = (struct worker_data *)arg;
    uint8_t dev_id = data->dev_id;
    uint8_t port_id = data->port_id;
    size_t sent = 0, received = 0;
    while (!fdata->done) {
        if (fdata->cap.scheduler)
            fdata->cap.scheduler(lcore_id);
        if (!fdata->worker_core[lcore_id]) {
            continue;
        }
                &ev, 1, 0);
        if (nb_rx == 0) {
            continue;
        }
        received++;
        
                        % cdata.num_fids;
        work();
        sent++;
    }
    if (!cdata.quiet)
        printf("  worker %u thread done. RX=%zu TX=%zu\n",
    return 0;
}
static int
worker_generic_burst(void *arg)
{
    struct worker_data *data = (struct worker_data *)arg;
    uint8_t dev_id = data->dev_id;
    uint8_t port_id = data->port_id;
    size_t sent = 0, received = 0;
    while (!fdata->done) {
        uint16_t i;
        if (fdata->cap.scheduler)
            fdata->cap.scheduler(lcore_id);
        if (!fdata->worker_core[lcore_id]) {
            continue;
        }
        if (nb_rx == 0) {
            continue;
        }
        received += nb_rx;
        for (i = 0; i < nb_rx; i++) {
            
            if (events[i].queue_id == cdata.qid[0])
                events[i].flow_id = events[i].mbuf->hash.rss
                            % cdata.num_fids;
            events[i].queue_id = cdata.next_qid[events[i].queue_id];
            events[i].sched_type = cdata.queue_type;
            work();
        }
                events, nb_rx);
        while (nb_tx < nb_rx && !fdata->done)
                            events + nb_tx,
                            nb_rx - nb_tx);
        sent += nb_tx;
    }
    if (!cdata.quiet)
        printf("  worker %u thread done. RX=%zu TX=%zu\n",
    return 0;
}
static int
setup_eventdev_generic(struct worker_data *worker_data)
{
    const uint8_t dev_id = 0;
    
    const uint8_t nb_queues = cdata.num_stages + 1;
    const uint8_t nb_ports = cdata.num_workers;
            .nb_event_ports = nb_ports,
            .nb_events_limit  = 4096,
            .nb_event_queue_flows = 1024,
            .nb_event_port_dequeue_depth = 128,
            .nb_event_port_enqueue_depth = 128,
    };
            .enqueue_depth = 64,
            .new_event_threshold = 4096,
    };
            .nb_atomic_flows = 1024,
        .nb_atomic_order_sequences = 1024,
    };
    };
    struct port_link worker_queues[MAX_NUM_STAGES];
    uint8_t disable_implicit_release;
    unsigned int i;
    if (ndev < 1) {
        printf("%d: No Eventdev Devices Found\n", __LINE__);
        return -1;
    }
    printf("\tEventdev %d: %s\n", dev_id, dev_info.driver_name);
    disable_implicit_release = (dev_info.event_dev_cap &
    if (dev_info.max_event_port_dequeue_depth <
                dev_info.max_event_port_dequeue_depth;
    if (dev_info.max_event_port_enqueue_depth <
                dev_info.max_event_port_enqueue_depth;
    if (ret < 0) {
        printf("%d: Error configuring device\n", __LINE__);
        return -1;
    }
    
    printf("  Stages:\n");
    for (i = 0; i < cdata.num_stages; i++) {
            printf("%d: error creating qid %d\n", __LINE__, i);
            return -1;
        }
        cdata.qid[i] = i;
        cdata.next_qid[i] = i+1;
        worker_queues[i].queue_id = i;
        if (cdata.enable_queue_priorities) {
            
            const uint32_t prio_delta =
            
        }
        const char *type_str = "Atomic";
            type_str = "Ordered";
            break;
            type_str = "Parallel";
            break;
        }
        printf("\tStage %d, Type %s\tPriority = %d\n", i, type_str,
    }
    printf("\n");
    
        printf("%d: error creating qid %d\n", __LINE__, i);
        return -1;
    }
    cdata.tx_queue_id = i;
    
    for (i = 0; i < cdata.num_workers; i++) {
        struct worker_data *w = &worker_data[i];
        w->dev_id = dev_id;
            printf("Error setting up port %d\n", i);
            return -1;
        }
        uint32_t s;
        for (s = 0; s < cdata.num_stages; s++) {
                        &worker_queues[s].queue_id,
                        &worker_queues[s].priority,
                        1) != 1) {
                printf("%d: error creating link for port %d\n",
                        __LINE__, i);
                return -1;
            }
        }
        w->port_id = i;
    }
                &fdata->evdev_service_id);
    if (ret != -ESRCH && ret != 0) {
        printf("Error getting the service ID for sw eventdev\n");
        return -1;
    }
    return dev_id;
}
static void
init_adapters(uint16_t nb_ports)
{
    int i;
    int ret;
    uint8_t tx_port_id = 0;
    uint8_t evdev_id = 0;
        .enqueue_depth = 64,
        .new_event_threshold = 4096,
    };
    if (adptr_p_conf.
dequeue_depth > dev_info.max_event_port_dequeue_depth)
 
            dev_info.max_event_port_dequeue_depth;
    if (adptr_p_conf.
enqueue_depth > dev_info.max_event_port_enqueue_depth)
 
            dev_info.max_event_port_enqueue_depth;
    
            &adptr_p_conf);
    if (ret)
        rte_exit(EXIT_FAILURE, 
"failed to create rx adapter[%d]",
 
                cdata.rx_adapter_id);
            &adptr_p_conf);
    if (ret)
        rte_exit(EXIT_FAILURE, 
"failed to create tx adapter[%d]",
 
                cdata.tx_adapter_id);
    memset(&queue_conf, 0, sizeof(queue_conf));
    queue_conf.ev.sched_type = cdata.queue_type;
    queue_conf.ev.queue_id = cdata.qid[0];
    for (i = 0; i < nb_ports; i++) {
                -1, &queue_conf);
        if (ret)
                    "Failed to add queues to Rx adapter");
                -1);
        if (ret)
                    "Failed to add queues to Tx adapter");
    }
            &tx_port_id);
    if (ret)
                "Failed to get Tx adapter port id");
            NULL, 1);
    if (ret != 1)
                "Unable to link Tx adapter port to Tx queue");
                &fdata->rxadptr_service_id);
    if (ret != -ESRCH && ret != 0) {
            "Error getting the service ID for Rx adapter\n");
    }
                &fdata->txadptr_service_id);
    if (ret != -ESRCH && ret != 0) {
            "Error getting the service ID for Tx adapter\n");
    }
    if (ret)
        rte_exit(EXIT_FAILURE, 
"Rx adapter[%d] start failed",
 
                cdata.rx_adapter_id);
    if (ret)
        rte_exit(EXIT_FAILURE, 
"Tx adapter[%d] start failed",
 
                cdata.tx_adapter_id);
        rte_exit(EXIT_FAILURE, 
"Error starting eventdev");
 
}
static void
generic_opt_check(void)
{
    int i;
    int ret;
    uint32_t cap = 0;
    uint8_t rx_needed = 0;
    uint8_t sched_needed = 0;
    if (cdata.all_type_queues && !(eventdev_info.event_dev_cap &
                "Event dev doesn't support all type queues\n");
    sched_needed = !(eventdev_info.event_dev_cap &
        if (ret)
                "failed to get event rx adapter capabilities");
        rx_needed |=
    }
    if (cdata.worker_lcore_mask == 0 ||
            (rx_needed && cdata.rx_lcore_mask == 0) ||
            (cdata.tx_lcore_mask == 0) ||
            (sched_needed && cdata.sched_lcore_mask == 0)) {
        printf("Core part of pipeline was not assigned any cores. "
            "This will stall the pipeline, please check core masks "
            "(use -h for details on setting core masks):\n"
            "\trx: %"PRIu64"\n\ttx: %"PRIu64"\n\tsched: %"PRIu64
            "\n\tworkers: %"PRIu64"\n",
            cdata.rx_lcore_mask, cdata.tx_lcore_mask,
            cdata.sched_lcore_mask,
            cdata.worker_lcore_mask);
    }
    if (!sched_needed)
        memset(fdata->sched_core, 0,
                sizeof(unsigned int) * MAX_NUM_CORE);
    if (!rx_needed)
        memset(fdata->rx_core, 0,
                sizeof(unsigned int) * MAX_NUM_CORE);
}
void
set_worker_generic_setup_data(struct setup_data *caps, bool burst)
{
    if (burst) {
        caps->worker = worker_generic_burst;
    } else {
        caps->worker = worker_generic;
    }
    caps->adptr_setup = init_adapters;
    caps->scheduler = schedule_devices;
    caps->evdev_setup = setup_eventdev_generic;
    caps->check_opt = generic_opt_check;
}