首页 > 代码库 > 04lock_05seqlock

04lock_05seqlock

  1 #include <linux/module.h>  //MODULE_LICENSE("GPL");   2 #include <linux/init.h>   //module_init  module_exit  3 #include <linux/kernel.h>  //printk  4 #include <linux/io.h>    //ioremap  iounremap  5 #include <linux/ioport.h>  //request_mem_region  6   7   8 #include <linux/miscdevice.h>  9 #include <linux/fs.h>   //file_operations  结构体的定义 10 #include <linux/slab.h>  //kmalloc 11 #include <linux/delay.h> 12  13 #include <asm/uaccess.h>    //copy_to_user  copy_form_user 14  15 #include <linux/spinlock.h>  //自旋锁 16 #include <linux/rwlock.h>  //读写自旋锁 17 #include <linux/seqlock.h>  //顺序锁 18  19 /* 20 该设备只能同时被一个进程打开 21 */ 22  23  24 #define   DEVNAME  "my_led" 25 #define  MEMSIZE  100 26  27  28 int test = 1; 29  30 struct ldm_info 31 { 32     struct  miscdevice dev;       //设备节点 33     struct  file_operations  ops;  //文件操作 34     unsigned char mem[MEMSIZE] ;  //数组, 内核的空间 35     //rwlock_t  myrwlock; 36     seqlock_t   seq; 37 }; 38  39 //struct ldm_info  ldm; 40 struct ldm_info  ldm;  //结构体的指针,分配空间 41  42 static  int ldm_open(struct inode * inode, struct file * file) 43 { 44     //printk("kernel: ldm_open\n"); 45     test++; 46     //如何传递私有变量 47     //Linux任何一个文件,都会有一个file指针, 48     //有一个成员  private_data  void *   通用指针 49     file->private_data =    http://www.mamicode.com/(void *)&test; 50  51     return 0; 52 } 53  54 /* 55 copy_to_user 56 copy_form_user 57 */ 58  59 static  ssize_t ldm_write(struct file * file, const char __user * buf, size_t size, loff_t *   offt) 60 { 61     int i =0; 62  63     int val = *(int *)file->private_data; 64  65     //write_lock(&ldm.myrwlock); 66     write_seqlock(&ldm.seq); 67     for(;i < size; i++) { 68         //每拷贝一个字节,睡眠1s 69         copy_from_user(ldm.mem + i, buf + i, 1); 70         printk("write:%c  val = %d\n",  ldm.mem[i], val); 71         ssleep(1); //延迟1s 72     } 73     //write_unlock(&ldm.myrwlock); 74     write_sequnlock(&ldm.seq); 75  76     return 0; 77 } 78  79  80 ssize_t ldm_read(struct file * file, char __user *  buf, size_t size, loff_t * offt) 81 { 82     //每隔一秒拷贝一个字节到用户层 83     int i =0; 84  85     int val = *(int *)file->private_data; 86  87     int seq = 0; 88     do { 89         seq = read_seqbegin(&ldm.seq); 90         //printk("seq = %d\n", seq); 91  92         for(;i < size; i++) { 93             //seq = read_seqbegin(&ldm.seq); 94             //每拷贝一个字节,睡眠1s 95             copy_to_user(buf + i, ldm.mem + i, 1); 96             printk("read:%c, val = %d\n",  ldm.mem[i], val); 97             ssleep(1); //延迟1s 98         } 99     }while(read_seqretry(&ldm.seq, seq));100     101     return 0;102 }103 104 int ldm_release(struct inode * inode, struct file *file)105 {106     //printk("kernel: close\n");107     test--;108     return 0;109 }110 111 static int test_init(void)112 {113     int ret = 0;114 115     printk("%s:%s:%d   init\n", __FILE__, __FUNCTION__, __LINE__);116 117 118     ldm.dev.minor  = MISC_DYNAMIC_MINOR;  //系统自动分配次设备119     ldm.dev.name = DEVNAME;//该名称将决定节点名称, 成功注册 linux 系统中120     ldm.dev.fops = &ldm.ops;  //关联文件操作121     ldm.ops.open = ldm_open;122     ldm.ops.write = ldm_write;123     ldm.ops.read = ldm_read;124     ldm.ops.release = ldm_release;125 126 127     ret = misc_register(&ldm.dev);128 129     //rwlock_init(&ldm.myrwlock);130     seqlock_init(&ldm.seq);131 132     if(ret < 0) {133         printk("misc_register  failed\n");134         goto  err_misc_register;135     }136 137     return 0;138 err_misc_register:139     return ret;140 141 }142 143 //卸载144 static void test_exit(void)145 {146     printk("%s:%s:%d   init\n", __FILE__, __FUNCTION__, __LINE__);147 148 149     //注销misc 150     misc_deregister(&ldm.dev);151     //释放映射的虚拟地址152 153 }154 155 module_init(test_init);156 module_exit(test_exit);157 158 159 MODULE_LICENSE("GPL");  //加入GPL许可

 

04lock_05seqlock