系统调用之sys_nanosleep

这个系统调用会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;
}

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/80258235