这个系统调用会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;
}
系统调用之sys_nanosleep
最新推荐文章于 2024-07-01 11:29:28 发布