博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
timerfd机制
阅读量:4216 次
发布时间:2019-05-26

本文共 2575 字,大约阅读时间需要 8 分钟。

timerfd是linux为用户提供的基于文件描述符的定时器接口,主要的系统调用有三个。分别如下:timerfd_create -- 新建一个fdtimerfd_settime -- 设置fd的超时时间timerfd_gettime -- 获得fd的超时时间一般用户设置fd的超时时间后就可以通过read来读取fd来poll当前的时间.timerfd 基本就是一个内存文件。这点可以从timerfd_create的实现中看到.可以看道timerfd_create 有两个输入蚕食分别是clockid 和 flagsSYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags){	int ufd;	struct timerfd_ctx *ctx;	/* Check the TFD_* constants for consistency.  */	BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);	BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK);#这里看到clockid只能去这个if中的固定值	if ((flags & ~TFD_CREATE_FLAGS) ||	    (clockid != CLOCK_MONOTONIC &&	     clockid != CLOCK_REALTIME &&	     clockid != CLOCK_REALTIME_ALARM &&	     clockid != CLOCK_BOOTTIME &&	     clockid != CLOCK_BOOTTIME_ALARM))		return -EINVAL;	if ((clockid == CLOCK_REALTIME_ALARM ||	     clockid == CLOCK_BOOTTIME_ALARM) &&	    !capable(CAP_WAKE_ALARM))		return -EPERM;	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);	if (!ctx)		return -ENOMEM;	init_waitqueue_head(&ctx->wqh);	spin_lock_init(&ctx->cancel_lock);	ctx->clockid = clockid;#是不是alarm	if (isalarm(ctx))		alarm_init(&ctx->t.alarm,			   ctx->clockid == CLOCK_REALTIME_ALARM ?			   ALARM_REALTIME : ALARM_BOOTTIME,			   timerfd_alarmproc);	else		hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS);	ctx->moffs = ktime_mono_to_real(0);#这里就是timerfd的本质,即是内存中的一个文件	ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,			       O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));	if (ufd < 0)		kfree(ctx);	return ufd;}当用户通过timerfd_sertime之后就会通过read来poll这个fd,我们看看timerfd的read函数实现如下:static const struct file_operations timerfd_fops = {	.release	= timerfd_release,	.poll		= timerfd_poll,	.read		= timerfd_read,	.llseek		= noop_llseek,	.show_fdinfo	= timerfd_show,	.unlocked_ioctl	= timerfd_ioctl,};可以看到read的实现函数为timerfd_readstatic ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,			    loff_t *ppos){	struct timerfd_ctx *ctx = file->private_data;	ssize_t res;	u64 ticks = 0;	if (count < sizeof(ticks))		return -EINVAL;	spin_lock_irq(&ctx->wqh.lock);#这里可以看到在创建timerfd的时候可以选择是否阻塞,如果是非阻塞的话,调用read的函数时候如果时间#没有到的话就直接返回了	if (file->f_flags & O_NONBLOCK)		res = -EAGAIN;	else#如果是阻塞方式,则调用read的时候,就会通过下面的wait函数阻塞在这里		res = wait_event_interruptible_locked_irq(ctx->wqh, ctx->ticks);	/*	 * If clock has changed, we do not care about the	 * ticks and we do not rearm the timer. Userspace must	 * reevaluate anyway.	 */	if (timerfd_canceled(ctx)) {		ctx->ticks = 0;		ctx->expired = 0;		res = -ECANCELED;	}	spin_unlock_irq(&ctx->wqh.lock);	if (ticks)		res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks);	return res;}

 

转载地址:http://wpnmi.baihongyu.com/

你可能感兴趣的文章
test-definitions/blob/master/toolset/util/parallel_cmds.py
查看>>
中断API之irq_activate
查看>>
中断API之tasklet_disable_nosync/tasklet_trylock/tasklet_unlock
查看>>
中断API之tasklet_init/tasklet_kill
查看>>
内存管理API之__free_pages
查看>>
内存管理API之__get_free_pages
查看>>
内存管理API之__get_vm_area
查看>>
内存管理API之krealloc
查看>>
内存管理API之ksize
查看>>
内存管理API之alloc_pages
查看>>
linux performance tool
查看>>
test-definitions/blob/master/auto-test/bazel/bazel.sh
查看>>
test-definitions/blob/master/auto-test/bigdata/bigdata.sh
查看>>
/test-definitions/blob/master/auto-test/blktrace/blktrace.sh
查看>>
test-definitions/blob/master/auto-test/blogbench/blogbench.sh
查看>>
test-definitions/blob/master/auto-test/boost/boost.sh
查看>>
Java多态性理解
查看>>
Intellij Idea 工具在java文件中怎么避免 import .*包,以及import包顺序的问题
查看>>
IDEA Properties中文unicode转码问题
查看>>
Oracle中Blob转换成Clob
查看>>