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获取时间的方法
介绍 我们在衡量一个函数运行时间,或者判断一个算法的时间效率,或者在程序中我们需要一个定时器,定时执 行一个特定的操作,比如在多媒体中,比如在游戏中等,都会用到时间函数.还比如我们通过记录 ...
随机推荐
- 互联网高并发之Hystrix实现服务隔离和降级
当大多数人在使用Tomcat时,多个HTTP服务会共享一个线程池,假设其中一个HTTP服务访问的数据库响应非常慢,这将造成服务响应时间延迟增加,大多数线程阻塞等待数据响应返回,导致整个Tomcat线程 ...
- HBase学习1(hbase基础)
认识NoSQL NoSQL:泛指非关系数据库(Not only SQL) NoSQL两重要特征:使用硬盘和把随机存储器作为存储载体 NoSQL分类(按照存储格式) 1)键值(Key-Value)存储数 ...
- 利用Phoenix为HBase创建二级索引
为什么需要Secondary Index 对于Hbase而言,如果想精确地定位到某行记录,唯一的办法是通过rowkey来查询.如果不通过rowkey来查找数据,就必须逐行地比较每一列的值,即全表扫瞄. ...
- Freemarker 使用
Freemarker 使用 博客分类: JAVA freemarker 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个 ...
- JAVA中代码前加@有什么作用
严格说@符号并未在java 语言中作为操作符使用.而是在其他附属技术中使用比如1.javadoc 文档关键字/*** @author* @version* @since* @see*/用于自动生成 ...
- [thinkphp使用phpspreadsheet时出现]Cannot redeclare xxxxxx() (previously declared in C:\WWW\xxx.xxx:xxx)
[thinkphp使用phpspreadsheet时出现]Cannot redeclare xxxxxx() (previously declared in C:\WWW\xxx.xxx:xxx) 一 ...
- srvany把程序作为Windows服务运行
srvany.exe是什么? srvany.exe是Microsoft Windows Resource Kits工具集的一个实用的小工具,用于将任何EXE程序作为Windows服务运行.也就是说sr ...
- ASP.NET Core 开源项目整理
前言: 对 .NET Core 的热情一直没有下降过,新起的项目几乎都是采用 Core 来做开发. 跨平台是一个方面,另外就是 Core 很轻,性能远超很多开发语言(不坑). 一.ASP.NET Co ...
- requests 简单应用
http://docs.python-requests.org/zh_CN/latest/user/quickstart.html ,官方文档.自己有空看看顺便敲两下熟悉一下. 还有别把文件放的太深 ...
- 【JAVA XXE攻击】微信支付官方回应XML外部实体注入漏洞
官方回应连接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5 其中明确指出了代码修改的地方. 然后看到此文档后,我就改公司项 ...