-.. code-block:: c
-
- static
- __rte_noreturn int main_loop(__rte_unused void *dummy)
- {
- // ...
-
- while (1) {
- // ...
-
- /**
- * Read packet from RX queues
- */
-
- lcore_scaleup_hint = FREQ_CURRENT;
- lcore_rx_idle_count = 0;
-
- for (i = 0; i < qconf->n_rx_queue; ++i)
- {
- rx_queue = &(qconf->rx_queue_list[i]);
- rx_queue->idle_hint = 0;
- portid = rx_queue->port_id;
- queueid = rx_queue->queue_id;
-
- nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst, MAX_PKT_BURST);
- stats[lcore_id].nb_rx_processed += nb_rx;
-
- if (unlikely(nb_rx == 0)) {
- /**
- * no packet received from rx queue, try to
- * sleep for a while forcing CPU enter deeper
- * C states.
- */
-
- rx_queue->zero_rx_packet_count++;
-
- if (rx_queue->zero_rx_packet_count <= MIN_ZERO_POLL_COUNT)
- continue;
-
- rx_queue->idle_hint = power_idle_heuristic(rx_queue->zero_rx_packet_count);
- lcore_rx_idle_count++;
- } else {
- rx_ring_length = rte_eth_rx_queue_count(portid, queueid);
-
- rx_queue->zero_rx_packet_count = 0;
-
- /**
- * do not scale up frequency immediately as
- * user to kernel space communication is costly
- * which might impact packet I/O for received
- * packets.
- */
-
- rx_queue->freq_up_hint = power_freq_scaleup_heuristic(lcore_id, rx_ring_length);
- }
-
- /* Prefetch and forward packets */
-
- // ...
- }
-
- if (likely(lcore_rx_idle_count != qconf->n_rx_queue)) {
- for (i = 1, lcore_scaleup_hint = qconf->rx_queue_list[0].freq_up_hint; i < qconf->n_rx_queue; ++i) {
- x_queue = &(qconf->rx_queue_list[i]);
-
- if (rx_queue->freq_up_hint > lcore_scaleup_hint)
-
- lcore_scaleup_hint = rx_queue->freq_up_hint;
- }
-
- if (lcore_scaleup_hint == FREQ_HIGHEST)
-
- rte_power_freq_max(lcore_id);
-
- else if (lcore_scaleup_hint == FREQ_HIGHER)
- rte_power_freq_up(lcore_id);
- } else {
- /**
- * All Rx queues empty in recent consecutive polls,
- * sleep in a conservative manner, meaning sleep as
- * less as possible.
- */
-
- for (i = 1, lcore_idle_hint = qconf->rx_queue_list[0].idle_hint; i < qconf->n_rx_queue; ++i) {
- rx_queue = &(qconf->rx_queue_list[i]);
- if (rx_queue->idle_hint < lcore_idle_hint)
- lcore_idle_hint = rx_queue->idle_hint;
- }
-
- if ( lcore_idle_hint < SLEEP_GEAR1_THRESHOLD)
- /**
- * execute "pause" instruction to avoid context
- * switch for short sleep.
- */
- rte_delay_us(lcore_idle_hint);
- else
- /* long sleep force ruining thread to suspend */
- usleep(lcore_idle_hint);
-
- stats[lcore_id].sleep_time += lcore_idle_hint;
- }
- }
- }