| 963 | |
| 964 | |
| 965 | void handle_timer_job(void) |
| 966 | { |
| 967 | struct os_timer *t; |
| 968 | ssize_t l; |
| 969 | utime_t _ijiffies,_ijiffies_extra; |
| 970 | |
| 971 | /* read one "os_timer" pointer from the pipe (non-blocking) */ |
| 972 | l = read( timer_fd_out, &t, sizeof(t) ); |
| 973 | if (l==-1) { |
| 974 | if (errno==EAGAIN || errno==EINTR || errno==EWOULDBLOCK ) |
| 975 | return; |
| 976 | LM_ERR("read failed:[%d] %s\n", errno, strerror(errno)); |
| 977 | return; |
| 978 | } |
| 979 | |
| 980 | |
| 981 | /* |
| 982 | Scheduling and handling of the timer task happens without drifting |
| 983 | ================================================================== |
| 984 | [time_keeper proc] *ijiffies increments: |
| 985 | V ITIMER_TICK V ITIMER_TICK V |
| 986 | ->|<----------------------------->|<------------------------------->|<-- |
| 987 | +ITIMER_TICK +ITIMER_TICK +ITIMER_TICK |
| 988 | |
| 989 | [timer proc] ^schedule timer job |
| 990 | t->trigger_time |
| 991 | [Timer handler proc] ^handling timer job |
| 992 | |
| 993 | The timer task was scheduled before a drift adjustement |
| 994 | ======================================================= |
| 995 | [time_keeper proc] *ijiffies increments: |
| 996 | V ITIMER_TICK V ITIMER_TICK V |
| 997 | ->|<----------------------------->|<----------->|<----------------->|<-- |
| 998 | +ITIMER_TICK +ITIMER_TICK +DRIFT +ITIMER_TICK |
| 999 | ^*ijifies_drift_base |
| 1000 | [timer proc] ^schedule timer job || ^schedule timer job |
| 1001 | t->trigger_time |
| 1002 | [Timer handler proc] ^handling timer job |
| 1003 | */ |
| 1004 | |
| 1005 | /* Cache the entry values for jiffies */ |
| 1006 | _ijiffies = *ijiffies; |
| 1007 | /* if we read from the queue after or while a drift was detecte |
| 1008 | * -> take the drift value into consideration too */ |
| 1009 | _ijiffies_extra = |
| 1010 | (t->trigger_time > *ijiffies_drift_base) ? 0 : *ijiffies_drift; |
| 1011 | |
| 1012 | profiling_proc_enter( LEVEL_FULL, t->label, 0 ); |
| 1013 | |
| 1014 | /* run the handler */ |
| 1015 | if (t->flags&TIMER_FLAG_IS_UTIMER) { |
| 1016 | |
| 1017 | if (t->trigger_time<(_ijiffies-_ijiffies_extra-ITIMER_TICK) ) { |
| 1018 | LM_WARN("utimer job <%s> has a %lld us delay in execution: " |
| 1019 | "trigger_time=%lld ijiffies=%lld ijiffies_extra=%lld\n", |
| 1020 | t->label, _ijiffies-t->trigger_time-_ijiffies_extra, |
| 1021 | t->trigger_time, _ijiffies, _ijiffies_extra); |
| 1022 | } |