clock_settime源码
时间: 2023-10-30 18:06:01 浏览: 48
以下是clock_settime函数的简化版源码,用于设置指定时钟的时间:
```c
#include <time.h>
#include <errno.h>
int clock_settime(clockid_t clockid, const struct timespec *tp)
{
if (clockid != CLOCK_REALTIME && clockid != CLOCK_MONOTONIC) {
errno = EINVAL;
return -1;
}
if (tp == NULL) {
errno = EFAULT;
return -1;
}
// 调用底层函数设置时钟时间
// ...
return 0;
}
```
该函数的实现会检查传入的时钟ID和时间参数是否合法,并调用底层函数来设置指定时钟的时间。在 Linux 中,clock_settime 的底层实现通过 syscall 系统调用来调用内核函数实现。
相关问题
调度器初始化cfs_rq 的源码
调度器初始化 cfs_rq 的源码位于 Linux 内核的 sched_init() 函数中。sched_init() 函数是在内核启动时被调用,用于初始化调度器和调度器相关的数据结构。该函数的定义在文件 kernel/sched/core.c 中。
以下是 sched_init() 函数中初始化 cfs_rq 的代码片段:
```
void __init sched_init(void)
{
...
for_each_possible_cpu(i) {
struct rq *rq = cpu_rq(i);
struct cfs_rq *cfs_rq = &rq->cfs;
/* Initialize cfs_rq */
rq->nr_running = 0;
rq->nr_uninterruptible = 0;
cfs_rq->min_vruntime = (u64)(-(1LL << 20));
cfs_rq->tasks_timeline = RB_ROOT_CACHED;
cfs_rq->load.weight = SCHED_LOAD_SCALE;
cfs_rq->nr_running = 0;
cfs_rq->nr_spread_over = 0;
cfs_rq->last_weight = 0;
cfs_rq->avg.load_sum = 0;
cfs_rq->avg.util_sum = 0;
cfs_rq->avg.runnable_sum = 0;
cfs_rq->avg.load_avg = 0;
cfs_rq->avg.util_avg = 0;
cfs_rq->avg.runnable_avg = 0;
cfs_rq->avg.last_update_time = sched_clock();
cfs_rq->next = cfs_rq->prev = cfs_rq;
cfs_rq->h_load.next = cfs_rq->h_load.prev = NULL;
cfs_rq->leaf_cfs_rq_list.next = cfs_rq->leaf_cfs_rq_list.prev = cfs_rq;
init_rq_bintree(rq);
atomic_set(&rq->nr_iowait, 0);
rq->online = 1;
rq->cpu_capacity_orig = capacity_orig_of(i);
rq->cpu_capacity = rq->cpu_capacity_orig;
rq->cpu_capacity_boosted = 0;
rq->cpu_capacity_orig_boosted = 0;
rq->idle_at_tick = 0;
rq->last_schedule_tick = 0;
rq->skip_clock_update = 0;
rq->avg_idle = 0;
rq->avg_idle_sum = 0;
rq->avg_idle_mis = 0;
rq->avg_idle_mis_sum = 0;
rq->clock_update_flags = 0;
rq->next_balance = jiffies + HZ;
rq->next_task_fair = jiffies;
rq->clock = 0;
rq->clock_task = NULL;
rq->idle_stamp = jiffies;
rq->last_load_update_tick = jiffies;
rq->nr_iowait = 0;
rq->iowait_contrib = 0;
rq->nr_iowait_last = 0;
init_cfs_bandwidth(&cfs_rq->bandwidth);
}
...
}
```
在上述代码中,通过 for_each_possible_cpu(i) 遍历每个 CPU,并分别初始化它们的 cfs_rq 数据结构。具体来说,调用 cpu_rq(i) 函数得到第 i 个 CPU 的 rq 对象,然后将 rq->cfs 指向的 cfs_rq 对象的各个成员初始化为默认值。其中包括 min_vruntime、tasks_timeline、load 等字段。这样,所有 CPU 的 cfs_rq 对象都被初始化完成,调度器初始化工作也就完成了。
linux内核timer_interrupt()源码
以下是Linux内核4.19版本中timer_interrupt()函数的源码实现:
```
asmlinkage __visible void __weak timer_interrupt(struct pt_regs *regs)
{
struct cpu_data *cpu = get_cpu_ptr(smp_processor_id());
struct clock_event_device *evt = cpu->evtdev;
unsigned long next_jiffies = jiffies + 1;
if (unlikely(time_after_eq(next_jiffies, cpu->last_jiffies + TICK_NSEC))) {
/*
* Some of this is really subtle. If we're in the middle of a tick
* already, we don't want to update the tick count - that could
* confuse the heck out of anyone trying to do timing. So make sure
* we don't update the tick until after the tick period has
* expired.
*/
if (time_after(next_jiffies, cpu->last_jiffies + TICK_NSEC)) {
int clock_was_set = 0;
while (time_after_eq(next_jiffies, cpu->last_jiffies + TICK_NSEC)) {
cpu->last_jiffies += TICK_NSEC;
update_wall_time();
clock_was_set = tick_nohz_update_jiffies(&cpu->tick_dep_mask);
if (cpu_is_offline(smp_processor_id()))
return;
}
if (clock_was_set)
tick_program_event(evt, cpu->next_timer_interrupt);
}
/*
* We must make sure that the jiffies update is visible
* before we test time_after_eq().
*/
smp_wmb();
if (time_after_eq(next_jiffies, READ_ONCE(jiffies)))
__generic_touch_nmi_watchdog();
if (unlikely(in_nmi()))
return;
/*
* If we missed any timer interrupts, correct this now
* by advancing the local timer and updating wall time
* again.
*/
while (time_after_eq(next_jiffies, READ_ONCE(jiffies))) {
cpu->last_jiffies += TICK_NSEC;
update_wall_time();
tick_nohz_idle_enter();
}
}
evt->event_handler(evt);
}
```
timer_interrupt()函数是中断处理程序,用于处理定时器中断。该函数首先获取当前CPU的事件设备指针,然后计算出下一次中断的时间,如果下一次中断的时间已经到了,则更新 jiffies 值并调用事件处理函数。如果下一次中断的时间还没有到,则继续等待下一次中断。函数中还包含了一些调用其他函数的代码块,用于更新时间值、设置时钟事件等。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)