免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1327 | 回复: 0
打印 上一主题 下一主题

完成变量completion [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-16 15:21 |只看该作者 |倒序浏览

完成变量的工作机制

完成变量是信号量的一种简单的实现。当一个任务运行需要请求某个资源或条件的情况下,wait_for_completion()函数将此任务放入等待队列,等待。另外一个任务使用完这个资源通过complete()函数发送一个完成变量,通知等待队列中的这个任务继续执行。

完成变量的实现函数

struct completion {
unsigned int done;
wait_queue_head_t wait;
};

void fastcall __sched wait_for_completion(struct completion *x)
{
might_sleep();

spin_lock_irq(&x->wait.lock);
if (!x->done) {
DECLARE_WAITQUEUE(wait, current);

wait.flags |= WQ_FLAG_EXCLUSIVE;
__add_wait_queue_tail(&x->wait, &wait);
do {
__set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&x->wait.lock);
schedule();
spin_lock_irq(&x->wait.lock);
} while (!x->done);
__remove_wait_queue(&x->wait, &wait);
}
x->done--;
spin_unlock_irq(&x->wait.lock);
}


void fastcall complete(struct completion *x)
{
unsigned long flags;

spin_lock_irqsave(&x->wait.lock, flags);
x->done++;
__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
1, 0, NULL);
spin_unlock_irqrestore(&x->wait.lock, flags);
}


完成变量的使用举例

demo程序

/*
* chardev.c: Creates a read-only char device that says how many times
* you've read from the dev file
*/

#include
#include
#include
#include
/* for put_user */
#include

#if 1
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
#endif
#define SUCCESS 0
#define DEVICE_NAME "chardev"
/* Dev name as it appears in /proc/devices   */
//#define BUF_LEN 80

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Edwin");

static int Major;
//struct completion mr_completion;
//init_completion(&mr_completion);

DECLARE_COMPLETION(mr_completion);

//struct completion mr_completion;



static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release
};

/*
* Functions
*/

int completion_init(void)
{
Major = register_chrdev(0, DEVICE_NAME, &fops);

if (Major printk("Registering the character device failed with %d\n",
Major);
return Major;
}
#if 1
printk("I was assigned major number %d.  To talk to\n", Major);
printk("the driver, create a dev file with\n");
printk("'mknod /dev/hello c %d 0'.\n", Major);
printk("Try various minor numbers.  Try to cat and echo to\n");
printk("the device file.\n");
printk("Remove the device file and module when done.\n");
#endif
return 0;
}

void completion_exit(void)
{
/*
* Unregister the device
*/
int ret = unregister_chrdev(Major, DEVICE_NAME);
if (ret printk("Error in unregister_chrdev: %d\n", ret);
else
printk("The %s moudle is released.\n",DEVICE_NAME);
}

module_init(completion_init);
module_exit(completion_exit);

/*
* Methods
*/

/*
* Called when a process tries to open the device file, like
* "cat /dev/mycharfile"
*/
static int device_open(struct inode *inode, struct file *file)
{

try_module_get(THIS_MODULE);

return SUCCESS;
}

/*
* Called when a process closes the device file.
*/
static int device_release(struct inode *inode, struct file *file)
{

/*
* Decrement the usage count, or else once you opened the file, you'll
* never get get rid of the module.
*/
module_put(THIS_MODULE);

return SUCCESS;
}

/*
* Called when a process, which already opened the dev file, attempts to
* read from it.
*/
static ssize_t device_read(struct file *filp,
/* see include/linux/fs.h   */

char *buffer,
size_t length,
loff_t * offset)
{

printk("the current process %i %s will sleep at once.\n", current->pid, current->comm);


wait_for_completion(&mr_completion);
printk("the completion sig is released.................................\n");
//printk(" device_read operation is executed\n");

return 0;

}

/*  
* Called when a process writes to dev file: echo "hi" > /dev/hello
*/
static ssize_t
device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
printk("the echo operation is executing \n");

complete(&mr_completion);
printk("the completion sig  is launched \n");

//printk("Sorry, this operation isn't supported.\n");
//return -EINVAL;
}


注:
具体参照
[1]
http://hi.baidu.com/phenix_yw/blog/item/4757f6243dcd83004c088dd9.html
[2]
http://aoqingy.spaces.live.com/blog/cns!153c2d72af27eb1c!308.entry




/* buffer to fill with data */
/* length of the buffer
*/


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/43047/showart_401611.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP