本文共 1979 字,大约阅读时间需要 6 分钟。
这个系统调用会sleep 一段时间其源码分析如下:SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, struct timespec __user *, rmtp){ struct timespec64 tu; #得到user space需要设置sleep的时间 if (get_timespec64(&tu, rqtp)) return -EFAULT; #检查要睡眠的时间是否合法 if (!timespec64_valid(&tu)) return -EINVAL; #修改当前current的restart_block current->restart_block.nanosleep.type = rmtp ? TT_NATIVE : TT_NONE; current->restart_block.nanosleep.rmtp = rmtp; #调用高精度时钟来睡眠 return hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC);}long hrtimer_nanosleep(const struct timespec64 *rqtp, const enum hrtimer_mode mode, const clockid_t clockid){ struct restart_block *restart; struct hrtimer_sleeper t; int ret = 0; u64 slack; slack = current->timer_slack_ns; if (dl_task(current) || rt_task(current)) slack = 0; #在栈上新建一个高精度的timer hrtimer_init_on_stack(&t.timer, clockid, mode); #设置到期时间 hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack); #开始睡眠,在do_nanosleep中会调用shedule 让出当前cpu ret = do_nanosleep(&t, mode); if (ret != -ERESTART_RESTARTBLOCK) goto out; /* Absolute timers do not update the rmtp value and restart: */ if (mode == HRTIMER_MODE_ABS) { ret = -ERESTARTNOHAND; goto out; } #sleep时间到期后,修改回当前进程的restart_block restart = ¤t->restart_block; restart->fn = hrtimer_nanosleep_restart; restart->nanosleep.clockid = t.timer.base->clockid; restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);out: #销毁栈上的高精度timer destroy_hrtimer_on_stack(&t.timer); return ret;}static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode){ struct restart_block *restart; hrtimer_init_sleeper(t, current); do { set_current_state(TASK_INTERRUPTIBLE); hrtimer_start_expires(&t->timer, mode); if (likely(t->task)) #核心code 调用shedule 让出cpu 其中#define freezable_schedule() schedule() freezable_schedule(); hrtimer_cancel(&t->timer); mode = HRTIMER_MODE_ABS; } while (t->task && !signal_pending(current)); __set_current_state(TASK_RUNNING); return -ERESTART_RESTARTBLOCK;}
转载地址:http://njnmi.baihongyu.com/