atomic 学习记录

来源:互联网 发布:阿里云备案承诺书模板 编辑:程序博客网 时间:2024/04/30 04:10

1. atomic 不具有等待性

static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,char *buf){int n = atomic_read(&atomic_lock);printk("liuj %d\n",n);//~ while( !atomic_read(&atomic_lock) ){//~ mdelay(1000);//~ printk("liuj2 %d\n",n);//~ }atomic_dec(&atomic_lock);mdelay(5000);atomic_inc(&atomic_lock);return sprintf(buf, "%d\n", foo);}


Conditin 1:如上所示

Terminal 1

test_atomic.sh

cat /sys/kernel/sample-kobject/foo &

cat /sys/kernel/sample-kobject/foo


连个同时显示0 。

Condition 2:去掉注释

test_atomic.sh

cat /sys/kernel/sample-kobject/foo &

cat /sys/kernel/sample-kobject/foo


[ 1509.615937] liuj 1 #第一个cat
[ 1509.620529] liuj 0 #第二个cat
[ 1510.613593] liuj2 0 #循环atomic_read
[ 1511.606650] liuj2 0
[ 1512.599705] liuj2 0
[ 1513.592767] liuj2 0

[ 1514.585821] liuj2 0

显示第二个0 时间大概为10s.

与预期符合。


2. 其中遇到的曲折。

2-1. 不知道这个atomic 不具有等待性。

cat /sys/kernel/sample-kobject/foo &

cat /sys/kernel/sample-kobject/foo


以为是64位机器的关系。

一度使用atomic_t atomic_lock = ATOMIC_INIT(1);

atomic64_dec(&atomic_lock);

atomic64_inc(&atomic_lock);

结果还是跟上面一样。


2-2. 源代码从别处考来,没有注意到-r-xr--r--

坑死我了,浪费>30 min.


参考实例:

/* -3 linux kernel/sample/kobject/kobject-example.c*/

/* * Sample kobject implementation * * Copyright (C) 2004-2007 Greg Kroah-Hartman <greg@kroah.com> * Copyright (C) 2007 Novell Inc. * * Released under the GPL version 2 only. * */#include <linux/kobject.h>#include <linux/string.h>#include <linux/sysfs.h>#include <linux/module.h>#include <linux/init.h>#include <asm/atomic.h>#include <asm/uaccess.h>#include <linux/delay.h>/* * This module shows how to create a simple subdirectory in sysfs called * /sys/kernel/kobject-example  In that directory, 3 files are created: * "foo", "baz", and "bar".  If an integer is written to these files, it can be * later read out of it. */static atomic_t atomic_lock=ATOMIC_INIT(1);static int foo;static int baz;static int bar;/* * The "foo" file where a static variable is read from and written to. */static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,char *buf){int n = atomic_read(&atomic_lock);printk("liuj %d\n",n);//while(atomic_dec_and_test(&atomic_lock))//;while( !atomic_read(&atomic_lock) ){mdelay(1000);printk("liuj2 %d\n",n);}atomic_dec(&atomic_lock);mdelay(5000);atomic_inc(&atomic_lock);return sprintf(buf, "%d\n", foo);}static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count){atomic_dec(&atomic_lock);//printk("222222222\n");mdelay(5000);sscanf(buf, "%du", &foo);atomic_inc(&atomic_lock);return count;}static struct kobj_attribute foo_attribute =__ATTR(foo, 0666, foo_show, foo_store);/* * More complex function where we determine which variable is being accessed by * looking at the attribute for the "baz" and "bar" files. */static ssize_t b_show(struct kobject *kobj, struct kobj_attribute *attr,      char *buf){int var;if (strcmp(attr->attr.name, "baz") == 0)var = baz;elsevar = bar;return sprintf(buf, "%d\n", var);}static ssize_t b_store(struct kobject *kobj, struct kobj_attribute *attr,       const char *buf, size_t count){int var;sscanf(buf, "%du", &var);if (strcmp(attr->attr.name, "baz") == 0)baz = var;elsebar = var;return count;}static struct kobj_attribute baz_attribute =__ATTR(baz, 0666, b_show, b_store);static struct kobj_attribute bar_attribute =__ATTR(bar, 0666, b_show, b_store);/* * Create a group of attributes so that we can create and destroy them all * at once. */static struct attribute *attrs[] = {&foo_attribute.attr,&baz_attribute.attr,&bar_attribute.attr,NULL,/* need to NULL terminate the list of attributes */};/* * An unnamed attribute group will put all of the attributes directly in * the kobject directory.  If we specify a name, a subdirectory will be * created for the attributes with the directory being the name of the * attribute group. */static struct attribute_group attr_group = {.attrs = attrs,};static struct kobject *example_kobj;static int __init example_init(void){int retval;/* * Create a simple kobject with the name of "kobject_example", * located under /sys/kernel/ * * As this is a simple directory, no uevent will be sent to * userspace.  That is why this function should not be used for * any type of dynamic kobjects, where the name and number are * not known ahead of time. */example_kobj = kobject_create_and_add("kobject_example", kernel_kobj);if (!example_kobj)return -ENOMEM;/* Create the files associated with this kobject */retval = sysfs_create_group(example_kobj, &attr_group);if (retval)kobject_put(example_kobj);return retval;}static void __exit example_exit(void){kobject_put(example_kobj);}module_init(example_init);module_exit(example_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");

/* -4 linux kernel/sample/kobject/kobject-example.c*/

#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/miscdevice.h>#include <asm/uaccess.h>#include <asm/atomic.h>//  定义设备文件名#define DEVICE_NAME "atomic"static int atom = 1; //  0: 多个进程可以同时打开atomic设备文件//  非0:同时只能有一个进程打开atomic设备文件static atomic_t int_atomic_available = ATOMIC_INIT(1);static int atomic_open(struct inode *node, struct file *file){if (atom){if (!atomic_dec_and_test(&int_atomic_available)){atomic_inc(&int_atomic_available);return -EBUSY;}}return 0;}static int atomic_release(struct inode *node, struct file *file){if (atom){atomic_inc(&int_atomic_available);}return 0;}static struct file_operations dev_fops ={ .owner = THIS_MODULE, .open = atomic_open, .release = atomic_release };static struct miscdevice misc ={ .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops };//  初始化Linux驱动static int __init atomic_init(void){//  建立设备文件int ret = misc_register(&misc);printk("atomic_init_success\n");return ret;}// 卸载Linux驱动static void __exit atomic_exit(void){printk("atomic_exit_success\n");//  删除设备文件misc_deregister(&misc);}//  注册初始化Linux驱动的函数module_init( atomic_init);//  注册卸载Linux驱动的函数module_exit( atomic_exit);module_param(atom, int, S_IRUGO|S_IWUSR);MODULE_LICENSE("GPL");


0 0
原创粉丝点击