* This function releases a burst (cache line) to a worker. * It is called from the process function when a cacheline is * full to make room for more packets for that worker, or when * all packets have been assigned to bursts and need to be flushed * to the workers. * It also needs to wait for any outstanding packets from the worker * before sending out new packets. */
| 394 | * before sending out new packets. |
| 395 | */ |
| 396 | static unsigned int |
| 397 | release(struct rte_distributor *d, unsigned int wkr) |
| 398 | { |
| 399 | struct rte_distributor_buffer *buf = &(d->bufs[wkr]); |
| 400 | unsigned int i; |
| 401 | |
| 402 | handle_returns(d, wkr); |
| 403 | if (unlikely(!d->active[wkr])) |
| 404 | return 0; |
| 405 | |
| 406 | /* Sync with worker on GET_BUF flag */ |
| 407 | while (!(rte_atomic_load_explicit(&(d->bufs[wkr].bufptr64[0]), rte_memory_order_acquire) |
| 408 | & RTE_DISTRIB_GET_BUF)) { |
| 409 | handle_returns(d, wkr); |
| 410 | if (unlikely(!d->active[wkr])) |
| 411 | return 0; |
| 412 | rte_pause(); |
| 413 | } |
| 414 | |
| 415 | buf->count = 0; |
| 416 | |
| 417 | for (i = 0; i < d->backlog[wkr].count; i++) { |
| 418 | d->bufs[wkr].bufptr64[i] = d->backlog[wkr].pkts[i] | |
| 419 | RTE_DISTRIB_GET_BUF | RTE_DISTRIB_VALID_BUF; |
| 420 | d->in_flight_tags[wkr][i] = d->backlog[wkr].tags[i]; |
| 421 | } |
| 422 | buf->count = i; |
| 423 | for ( ; i < RTE_DIST_BURST_SIZE ; i++) { |
| 424 | buf->bufptr64[i] = RTE_DISTRIB_GET_BUF; |
| 425 | d->in_flight_tags[wkr][i] = 0; |
| 426 | } |
| 427 | |
| 428 | d->backlog[wkr].count = 0; |
| 429 | |
| 430 | /* Clear the GET bit. |
| 431 | * Sync with worker on GET_BUF flag. Release bufptrs. |
| 432 | */ |
| 433 | rte_atomic_store_explicit(&(buf->bufptr64[0]), |
| 434 | buf->bufptr64[0] & ~RTE_DISTRIB_GET_BUF, rte_memory_order_release); |
| 435 | return buf->count; |
| 436 | |
| 437 | } |
| 438 | |
| 439 | |
| 440 | /* process a set of packets to distribute them to workers */ |
no test coverage detected