must be called periodically, run all timer that expired */
| 652 | |
| 653 | /* must be called periodically, run all timer that expired */ |
| 654 | static void |
| 655 | __rte_timer_manage(struct rte_timer_data *timer_data) |
| 656 | { |
| 657 | union rte_timer_status status; |
| 658 | struct rte_timer *tim, *next_tim; |
| 659 | struct rte_timer *run_first_tim, **pprev; |
| 660 | unsigned lcore_id = rte_lcore_id(); |
| 661 | struct rte_timer *prev[MAX_SKIPLIST_DEPTH + 1]; |
| 662 | uint64_t cur_time; |
| 663 | int i, ret; |
| 664 | struct priv_timer *priv_timer = timer_data->priv_timer; |
| 665 | |
| 666 | /* timer manager only runs on EAL thread with valid lcore_id */ |
| 667 | assert(lcore_id < RTE_MAX_LCORE); |
| 668 | |
| 669 | __TIMER_STAT_ADD(priv_timer, manage, 1); |
| 670 | /* optimize for the case where per-cpu list is empty */ |
| 671 | if (priv_timer[lcore_id].pending_head.sl_next[0] == NULL) |
| 672 | return; |
| 673 | cur_time = rte_get_timer_cycles(); |
| 674 | |
| 675 | #ifdef RTE_ARCH_64 |
| 676 | /* on 64-bit the value cached in the pending_head.expired will be |
| 677 | * updated atomically, so we can consult that for a quick check here |
| 678 | * outside the lock */ |
| 679 | if (likely(priv_timer[lcore_id].pending_head.expire > cur_time)) |
| 680 | return; |
| 681 | #endif |
| 682 | |
| 683 | /* browse ordered list, add expired timers in 'expired' list */ |
| 684 | rte_spinlock_lock(&priv_timer[lcore_id].list_lock); |
| 685 | |
| 686 | /* if nothing to do just unlock and return */ |
| 687 | if (priv_timer[lcore_id].pending_head.sl_next[0] == NULL || |
| 688 | priv_timer[lcore_id].pending_head.sl_next[0]->expire > cur_time) { |
| 689 | rte_spinlock_unlock(&priv_timer[lcore_id].list_lock); |
| 690 | return; |
| 691 | } |
| 692 | |
| 693 | /* save start of list of expired timers */ |
| 694 | tim = priv_timer[lcore_id].pending_head.sl_next[0]; |
| 695 | |
| 696 | /* break the existing list at current time point */ |
| 697 | timer_get_prev_entries(cur_time, lcore_id, prev, priv_timer); |
| 698 | for (i = priv_timer[lcore_id].curr_skiplist_depth -1; i >= 0; i--) { |
| 699 | if (prev[i] == &priv_timer[lcore_id].pending_head) |
| 700 | continue; |
| 701 | priv_timer[lcore_id].pending_head.sl_next[i] = |
| 702 | prev[i]->sl_next[i]; |
| 703 | if (prev[i]->sl_next[i] == NULL) |
| 704 | priv_timer[lcore_id].curr_skiplist_depth--; |
| 705 | prev[i] ->sl_next[i] = NULL; |
| 706 | } |
| 707 | |
| 708 | /* transition run-list from PENDING to RUNNING */ |
| 709 | run_first_tim = tim; |
| 710 | pprev = &run_first_tim; |
| 711 |
no test coverage detected