sleep 和 usleep的实现方法
int usleep (useconds_t useconds)
{
struct timespec ts = { .tv_sec = (long int) (useconds / 1000000),
.tv_nsec = (long int) (useconds % 1000000) * 1000ul };
/* Note the usleep() is a cancellation point. But since we call
nanosleep() which itself is a cancellation point we do not have
to do anything here. */
return __nanosleep (&ts, NULL);
}
/* We are going to use the `nanosleep' syscall of the kernel. But the
kernel does not implement the stupid SysV SIGCHLD vs. SIG_IGN
behaviour for this syscall. Therefore we have to emulate it here. */
unsigned int
__sleep (unsigned int seconds)
{
const unsigned int max
= (unsigned int) (((unsigned long int) (~((time_t) 0))) >> 1);
struct timespec ts;
sigset_t set, oset;
unsigned int result; /* This is not necessary but some buggy programs depend on this. */
if (__builtin_expect (seconds == 0, 0))
{
#ifdef CANCELLATION_P
CANCELLATION_P (THREAD_SELF);
#endif
return 0;
} ts.tv_sec = 0;
ts.tv_nsec = 0;
again:
if (sizeof (ts.tv_sec) <= sizeof (seconds))
{
/* Since SECONDS is unsigned assigning the value to .tv_sec can
overflow it. In this case we have to wait in steps. */
ts.tv_sec += MIN (seconds, max);
seconds -= (unsigned int) ts.tv_sec;
}
else
{
ts.tv_sec = (time_t) seconds;
seconds = 0;
} /* Linux will wake up the system call, nanosleep, when SIGCHLD
arrives even if SIGCHLD is ignored. We have to deal with it
in libc. We block SIGCHLD first. */
__sigemptyset (&set);
__sigaddset (&set, SIGCHLD);
if (__sigprocmask (SIG_BLOCK, &set, &oset))
return -1; /* If SIGCHLD is already blocked, we don't have to do anything. */
if (!__sigismember (&oset, SIGCHLD))
{
int saved_errno;
struct sigaction oact; __sigemptyset (&set);
__sigaddset (&set, SIGCHLD); /* We get the signal handler for SIGCHLD. */
if (__sigaction (SIGCHLD, (struct sigaction *) NULL, &oact) < 0)
{
saved_errno = errno;
/* Restore the original signal mask. */
(void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
__set_errno (saved_errno);
return -1;
} /* Note the sleep() is a cancellation point. But since we call
nanosleep() which itself is a cancellation point we do not
have to do anything here. */
if (oact.sa_handler == SIG_IGN)
{
//__libc_cleanup_push (cl, &oset); /* We should leave SIGCHLD blocked. */
while (1)
{
result = __nanosleep (&ts, &ts); if (result != 0 || seconds == 0)
break; if (sizeof (ts.tv_sec) <= sizeof (seconds))
{
ts.tv_sec = MIN (seconds, max);
seconds -= (unsigned int) ts.tv_nsec;
}
} //__libc_cleanup_pop (0); saved_errno = errno;
/* Restore the original signal mask. */
(void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
__set_errno (saved_errno); goto out;
} /* We should unblock SIGCHLD. Restore the original signal mask. */
(void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
} result = __nanosleep (&ts, &ts);
if (result == 0 && seconds != 0)
goto again; out:
if (result != 0)
/* Round remaining time. */
result = seconds + (unsigned int) ts.tv_sec + (ts.tv_nsec >= 500000000L); return result;
}
long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,const enum hrtimer_mode mode, const clockid_t clockid)
{
struct restart_block *restart;
struct hrtimer_sleeper t;
int ret = 0;
unsigned long slack;
slack = current->timer_slack_ns;
if (rt_task(current))
slack = 0;
hrtimer_init_on_stack(&t.timer, clockid, mode);
hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
if (do_nanosleep(&t, mode))
goto out;
/* Absolute timers do not update the rmtp value and restart: */
if (mode == HRTIMER_MODE_ABS) {
ret = -ERESTARTNOHAND;
goto out;
}
if (rmtp) {
ret = update_rmtp(&t.timer, rmtp);
if (ret <= 0)
goto out;
}
restart = ¤t_thread_info()->restart_block;
restart->fn = hrtimer_nanosleep_restart;
restart->nanosleep.clockid = t.timer.base->clockid;
restart->nanosleep.rmtp = rmtp;
restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer);
ret = -ERESTART_RESTARTBLOCK;
out:
destroy_hrtimer_on_stack(&t.timer);
return ret;
}
SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
struct timespec __user *, rmtp)
{
struct timespec tu;
if (copy_from_user(&tu, rqtp, sizeof(tu)))
return -EFAULT;
if (!timespec_valid(&tu))
return -EINVAL; return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
sleep 和 usleep的实现方法的更多相关文章
- javaSE27天复习总结
JAVA学习总结 2 第一天 2 1:计算机概述(了解) 2 (1)计算机 2 (2)计算机硬件 2 (3)计算机软件 2 (4)软件开发(理解) 2 (5) ...
- cocos2d-x 跨平台usleep方法
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #define usleep(t) Sleep(t) #else #include <unistd.h ...
- Android(Linux)控制GPIO的方法及实时性分析
Linux下控制GPIO的方法有N种,详细请参考<RPi GPIO Code Samples>,文中用十多种语言演示了如何控制GPIO,非常全面详尽.因此,这里不再多做赘述,仅把调试过程中 ...
- Linux平台延时之sleep、usleep、nanosleep、select比较
Linux平台延时之sleep.usleep.nanosleep.select比较 标签: 嵌入式thread线程cpu多线程 2015-05-05 15:28 369人阅读 评论(0) 收藏 举报 ...
- Linux 高精確的時序(sleep, usleep,nanosleep) from:http://blog.sina.com.cn/s/blog_533ab41c0100htae.html
Linux 高精確的時序(sleep, usleep,nanosleep) (2010-04-14 17:18:26) 转载▼ 标签: 杂谈 分类: linux 首先, 我会说不保证你在使用者模式 ( ...
- PHP截取IE浏览器并缩小原图的方法
这篇文章主要介绍了PHP截取IE浏览器并缩小原图的方法,涉及PHP调用com组件实现图像截取的相关技巧,需要的朋友可以参考下 本文实例讲述了PHP截取IE浏览器并缩小原图的方法.分享给大家供大家参考, ...
- 【转载】c/c++在windows下获取时间和计算时间差的几种方法总结
一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double difftime( time_t timer1, time_t time ...
- 检测iOS的APP性能的一些方法
首先如果遇到应用卡顿或者因为内存占用过多时一般使用Instruments里的来进行检测.但对于复杂情况可能就需要用到子线程监控主线程的方式来了,下面我对这些方法做些介绍: Time Profiler ...
- windows获取时间的方法
介绍 我们在衡量一个函数运行时间,或者判断一个算法的时间效率,或者在程序中我们需要一个定时器,定时执 行一个特定的操作,比如在多媒体中,比如在游戏中等,都会用到时间函数.还比如我们通过记录 ...
随机推荐
- 20145240 《Java程序设计》第四次实验报告
20145240 <Java程序设计>第四次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.26 实验 ...
- linux内核调试+qemu+eclipse【转】
本文转载自:https://blog.csdn.net/WANG__RONGWEI/article/details/54922727 一.调试环境: 在ubuntu16.04下,在虚拟机里边运行的ub ...
- Java Interface接口
Java 中接口概念 接口可以理解为一种特殊的 类,由 全局常量 和 公共的抽象方法 所组成. 类是一种具体实现体,而接口定义了某一批类所需要遵循的规范,接口不关心这些类的内部数据, 也不关心这些类里 ...
- juniper常用命令(二)
Juniper防火墙基本命令 常用查看命令 Get int查看接口配置信息 Get int ethx/x查看指定接口配置信息 Get mip查看映射ip关系 Get route查看路由表 Get po ...
- java基础(2)-面向对象(1)
面向对象 面向对象思想 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程:强调的是功能行为 面向对象:将功能封装进对象,强调具备了功能的对象 面向对象是基于面向过程的 面向对象举例 ...
- php提前输出响应及注意问题
1.浏览器和服务器之间是通过HTTP进行通信的,浏览器发送请求给服务器,服务器处理完请求后,发送响应结果给浏览器,浏览器展示给用户.如果服务器处理请求时间比较长,那么浏览器就需要等待服务器的处理结果. ...
- python快速学习-常用內建模块
- js命令模式
命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 从命令模式的结构图可以看出,它涉及到五个角色,它们分别是 ...
- tensorflow笔记:流程,概念和简单代码注释
tensorflow是google在2015年开源的深度学习框架,可以很方便的检验算法效果.这两天看了看官方的tutorial,极客学院的文档,以及综合tensorflow的源码,把自己的心得整理了一 ...
- HTML5 JS实现搜索匹配功能
http://www.codefans.net/jscss/code/4830.shtml <!DOCTYPE html><head><title>jQuery实现 ...