int pktin_deq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int num) { int nbr; nbr = queue_deq_multi(qentry, buf_hdr, num); if (nbr < num) { odp_packet_t pkt_tbl[QUEUE_MULTI_MAX]; odp_buffer_hdr_t *tmp_hdr_tbl[QUEUE_MULTI_MAX]; odp_buffer_t buf; int pkts, i; pkts = odp_pktio_recv(qentry->s.pktin, pkt_tbl, QUEUE_MULTI_MAX); if (pkts > 0) { for (i = 0; i < pkts; ++i) { buf = odp_buffer_from_packet(pkt_tbl[i]); tmp_hdr_tbl[i] = odp_buf_to_hdr(buf); } queue_enq_multi(qentry, tmp_hdr_tbl, pkts); } } return nbr; }
int odp_schedule_term_global(void) { int ret = 0; int rc = 0; int i, j; for (i = 0; i < ODP_CONFIG_SCHED_PRIOS; i++) { for (j = 0; j < QUEUES_PER_PRIO; j++) { odp_queue_t pri_q; odp_event_t ev; pri_q = sched->pri_queue[i][j]; while ((ev = odp_queue_deq(pri_q)) != ODP_EVENT_INVALID) { odp_buffer_t buf; sched_cmd_t *sched_cmd; buf = odp_buffer_from_event(ev); sched_cmd = odp_buffer_addr(buf); if (sched_cmd->cmd == SCHED_CMD_DEQUEUE) { queue_entry_t *qe; odp_buffer_hdr_t *buf_hdr[1]; int num; qe = sched_cmd->qe; num = queue_deq_multi(qe, buf_hdr, 1); if (num < 0) queue_destroy_finalize(qe); if (num > 0) ODP_ERR("Queue not empty\n"); } else odp_buffer_free(buf); } if (odp_queue_destroy(pri_q)) { ODP_ERR("Pri queue destroy fail.\n"); rc = -1; } } } if (odp_pool_destroy(sched->pool) != 0) { ODP_ERR("Pool destroy fail.\n"); rc = -1; } ret = odp_shm_free(sched->shm); if (ret < 0) { ODP_ERR("Shm free failed for odp_scheduler"); rc = -1; } return rc; }
int pktin_deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num) { int i; num = queue_deq_multi(queue, buf_hdr, num); for (i = 0; i < num; i++) update_in_packet(buf_hdr[i], queue->s.pktin); return num; }
static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[], unsigned len) { int nbr, i; odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX]; queue_entry_t *qentry; qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq); nbr = queue_deq_multi(qentry, hdr_tbl, len); for (i = 0; i < nbr; ++i) { pkts[i] = _odp_packet_from_buffer(odp_hdr_to_buf(hdr_tbl[i])); _odp_packet_reset_parse(pkts[i]); } return nbr; }
static int loopback_recv(pktio_entry_t *pktio_entry, odp_packet_t pkts[], unsigned len) { int nbr, i, j; odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX]; queue_entry_t *qentry; odp_packet_hdr_t *pkt_hdr; odp_packet_t pkt; nbr = 0; qentry = queue_to_qentry(pktio_entry->s.pkt_loop.loopq); nbr = queue_deq_multi(qentry, hdr_tbl, len); if (pktio_cls_enabled(pktio_entry)) { for (i = 0, j = 0; i < nbr; i++) { pkt = _odp_packet_from_buffer(odp_hdr_to_buf (hdr_tbl[i])); pkt_hdr = odp_packet_hdr(pkt); packet_parse_reset(pkt_hdr); packet_parse_l2(pkt_hdr); if (0 > _odp_packet_classifier(pktio_entry, pkt)) pkts[j++] = pkt; } nbr = j; } else { for (i = 0; i < nbr; ++i) { pkts[i] = _odp_packet_from_buffer(odp_hdr_to_buf (hdr_tbl[i])); pkt_hdr = odp_packet_hdr(pkts[i]); packet_parse_reset(pkt_hdr); packet_parse_l2(pkt_hdr); } } return nbr; }
/* * Schedule queues * * TODO: SYNC_ORDERED not implemented yet */ static int schedule(odp_queue_t *out_queue, odp_event_t out_ev[], unsigned int max_num, unsigned int max_deq) { int i, j; int thr; int ret; if (sched_local.num) { ret = copy_events(out_ev, max_num); if (out_queue) *out_queue = queue_handle(sched_local.qe); return ret; } odp_schedule_release_atomic(); if (odp_unlikely(sched_local.pause)) return 0; thr = odp_thread_id(); for (i = 0; i < ODP_CONFIG_SCHED_PRIOS; i++) { int id; if (sched->pri_mask[i] == 0) continue; id = thr & (QUEUES_PER_PRIO-1); for (j = 0; j < QUEUES_PER_PRIO; j++, id++) { odp_queue_t pri_q; odp_event_t ev; odp_buffer_t buf; sched_cmd_t *sched_cmd; queue_entry_t *qe; int num; if (id >= QUEUES_PER_PRIO) id = 0; if (odp_unlikely((sched->pri_mask[i] & (1 << id)) == 0)) continue; pri_q = sched->pri_queue[i][id]; ev = odp_queue_deq(pri_q); buf = odp_buffer_from_event(ev); if (buf == ODP_BUFFER_INVALID) continue; sched_cmd = odp_buffer_addr(buf); if (sched_cmd->cmd == SCHED_CMD_POLL_PKTIN) { /* Poll packet input */ if (pktin_poll(sched_cmd->pe)) { /* Stop scheduling the pktio */ pri_clr_pktio(sched_cmd->pktio, sched_cmd->prio); odp_buffer_free(buf); } else { /* Continue scheduling the pktio */ if (odp_queue_enq(pri_q, ev)) ODP_ABORT("schedule failed\n"); } continue; } qe = sched_cmd->qe; num = queue_deq_multi(qe, sched_local.buf_hdr, max_deq); if (num < 0) { /* Destroyed queue */ queue_destroy_finalize(qe); continue; } if (num == 0) { /* Remove empty queue from scheduling */ continue; } sched_local.num = num; sched_local.index = 0; sched_local.qe = qe; ret = copy_events(out_ev, max_num); if (queue_is_atomic(qe)) { /* Hold queue during atomic access */ sched_local.pri_queue = pri_q; sched_local.cmd_ev = ev; } else { /* Continue scheduling the queue */ if (odp_queue_enq(pri_q, ev)) ODP_ABORT("schedule failed\n"); } /* Output the source queue handle */ if (out_queue) *out_queue = queue_handle(qe); return ret; } } return 0; }