sched_clock_postinit()

 

sched_clock_postinit()

kernel/time/sched_clock.c

void __init sched_clock_postinit(void)
{
        /*
         * If no sched_clock function has been provided at that point,
         * make it the final one one.
         */
        if (read_sched_clock == jiffy_sched_clock_read)
                sched_clock_register(jiffy_sched_clock_read, BITS_PER_LONG, HZ);

        update_sched_clock();

        /*
         * Start the timer to keep sched_clock() properly updated and
         * sets the initial epoch.
         */
        hrtimer_init(&sched_clock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        sched_clock_timer.function = sched_clock_poll;
        hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
}

sched_clock 용 클럭소스로 최종 업데이트 하고 약 1시간 단위로 epoch 값을 갱신하게 한다.

  • 코드 라인 7~8에서 최종 클럭소스가 지정되지 않은 경우 jiffies 를 사용하여 sched_clock으로 사용한다.
  • 코드 라인 10에서 sched_clock용 클럭소스를 사용하여 갱신한다.
  • 코드 라인 16에서 hrtimer를 사용하여 약 1시간 단위로 epoch 값을 갱신하게 한다.

 

update_sched_clock()

kernel/time/sched_clock.c

/*
 * Atomically update the sched_clock epoch.
 */
static void notrace update_sched_clock(void)
{
        unsigned long flags;
        u64 cyc;
        u64 ns;

        cyc = read_sched_clock();
        ns = cd.epoch_ns +
                cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask,
                          cd.mult, cd.shift);

        raw_local_irq_save(flags);
        raw_write_seqcount_begin(&cd.seq);
        cd.epoch_ns = ns;
        cd.epoch_cyc = cyc;
        raw_write_seqcount_end(&cd.seq);
        raw_local_irq_restore(flags);
}

 

 

참고

 

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.