免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
howtocaculategettimeofday

 how to caculate gettimeofday收藏

在mobile linux中的gettimeofday,按照user layer的定義,是micro second(us)的精度。 但是真的精確么?


gettimeofday --> sys_gettimeofday -->do_gettimeofday
void do_gettimeofday(struct timeval *tv)
{
    unsigned long flags;
    unsigned long seq;
    unsigned long usec, sec;

    do {
        seq = read_seqbegin_irqsave(&xtime_lock, flags);
        usec = system_timer->offset();
        sec = xtime.tv_sec;
        usec += xtime.tv_nsec / 1000;
    } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));

    /* usec may have gone up a lot: be safe */
    while (usec >= 1000000) {
        usec -= 1000000;
        sec++;
    }

    tv->tv_sec = sec;
    tv->tv_usec = usec;
}
由上函數(shù)可見(jiàn):
usec = system_timer->offset();
usec += xtime.tv_nsec / 1000;
是關(guān)鍵。
offset 是在time_init中賦值的:
void __init time_init(void)
{
#ifndef CONFIG_GENERIC_TIME
    if (system_timer->offset == NULL)
        system_timer->offset = dummy_gettimeoffset;
#endif
    system_timer->init();

#ifdef CONFIG_NO_IDLE_HZ
    if (system_timer->dyn_tick)
        system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED;
#endif
}
CONFIG_GENERIC_TIME 是定義了的,而且我們的system_timer->offset為空,system_timer是一個(gè)全局變量,
是在arch/arm/atxx.c中賦值:
MACHINE_START(INTEGRATOR, "ARM")
    .phys_io    = UART0_BASE,
    .io_pg_offst    = ((IO_ADDRESS(UART0_BASE)) >> 18) & 0xfffc,
    .boot_params    = PHYS_OFFSET + 0x00000100,
    .map_io        = ap_map_io,
    .init_irq    = ap_init_irq,
    .timer        = &ap_timer,
    .init_machine    = ap_init,
MACHINE_END
所以會(huì)用dummy_gettimeoffset,而這個(gè)函數(shù)是一個(gè)空函數(shù);
現(xiàn)在來(lái)看xtime的nano second是如何算出來(lái)的。
xtime的初始化在timekeeping_init
void __init timekeeping_init(void)
{
 ......
     clock = clocksource_get_next();
    clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
    clock->cycle_last = clocksource_read(clock);

    xtime.tv_sec = sec;
    xtime.tv_nsec = 0;

 ......
}

clock = clocksource_get_next();會(huì)選擇一個(gè)clock rate最高的clock source,在嵌入式環(huán)境中一般就只有一個(gè)
PIT(program interrupt timer),所以只會(huì)是這個(gè)。
xtime.tv_nsec = 0; 初始值是0;
那這個(gè)值是什么時(shí)候update的呢?
在 start_kernel中的init_timers中,會(huì)注冊(cè)叫 run_timer_softirq的softirq,來(lái)看一下這個(gè)函數(shù):
/*
 * This function runs timers and the timer-tq in bottom half context.
 */
static void run_timer_softirq(struct softirq_action *h)
{
    tvec_base_t *base = per_cpu(tvec_bases, raw_smp_processor_id());

    update_times();
    MARK(kernel_timer_update_time,
    "%8b %*.*r %*.*r",
        jiffies_64,
        sizeof(xtime), __alignof__(xtime), &xtime,
        sizeof(wall_to_monotonic), __alignof__(wall_to_monotonic),
        &wall_to_monotonic);
    hrtimer_run_queues();

    if (time_after_eq(jiffies, base->timer_jiffies))
        __run_timers(base);
}
然后是update_times-->update_wall_time

/**
 * update_wall_time - Uses the current clocksource to increment the wall time
 *
 * Called from the timer interrupt, must hold a write on xtime_lock.
 */
static void update_wall_time(void)
{
    cycle_t cycle_now;

    /* Make sure we're fully resumed: */
    if (unlikely(timekeeping_suspended))
        return;

#ifdef CONFIG_GENERIC_TIME
    cycle_now = clocksource_read(clock);  //read back jiffies
#else
    cycle_now = clock->cycle_last + clock->cycle_interval;
#endif
    clocksource_accumulate(clock, cycle_now);

    clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;

    /* normally this loop will run just once, however in the
     * case of lost or late ticks, it will accumulate correctly.
     */
    while (clock->cycle_accumulated >= clock->cycle_interval) {
        /* accumulate one interval */
        clock->xtime_nsec += clock->xtime_interval;
        clock->cycle_accumulated -= clock->cycle_interval;

        if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
            clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
            xtime.tv_sec++;
            second_overflow();
        }

        /* interpolator bits */
        time_interpolator_update(clock->xtime_interval
                        >> clock->shift);

        /* accumulate error between NTP and clock interval */
        clock->error += current_tick_length();
        clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
    }

    /* correct the clock when NTP error is too big */
    clocksource_adjust(clock->cycle_accumulated);

    /* store full nanoseconds into xtime */
    xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
    clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;

    /* check to see if there is a new clocksource to use */
    change_clocksource();
    update_vsyscall(&xtime, clock);
}
cycle_now = clocksource_read(clock); 這個(gè)clock就是timekeeping_init中,用clocksource_get_next選擇的
clock,在我們的例子里是:
#define JIFFIES_SHIFT 8
struct clocksource clocksource_jiffies = {
    .name        = "jiffies",
    .rating        = 1, /* lowest valid rating*/
    .read        = jiffies_read,
    .mask        = 0xffffffff, /*32bits*/
    .mult        = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
    .shift        = JIFFIES_SHIFT,
};
cycle_now 取得是就是jiffies,他的基準(zhǔn)值是jiffies,ns是一個(gè)估計(jì)出來(lái)的值。

結(jié)論:用gettimeofday計(jì)算jiffies以上的值是可以的,但是jiffies以下的精度會(huì)不夠。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux時(shí)間子系統(tǒng)之三:時(shí)間的維護(hù)者:timekeeper
Linux時(shí)間子系統(tǒng)之一:clock source(時(shí)鐘源)
18. 時(shí)鐘管理
Linux 時(shí)鐘管理
在linux內(nèi)核中獲得比jiffies精度更高的時(shí)間值
linux世界里的時(shí)間
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服