模块API之try_module_get
来源:互联网 发布:热血江湖自动登录源码 编辑:程序博客网 时间:2024/05/30 23:43
try_module_get的作用是如果一个模块处于活动状态,则对其引用计数加1.在kernel中使用的例程如下:struct file *anon_inode_getfile(const char *name,const struct file_operations *fops,void *priv, int flags){struct qstr this;struct path path;struct file *file;if (IS_ERR(anon_inode_inode))return ERR_PTR(-ENODEV);if (fops->owner && !try_module_get(fops->owner))return ERR_PTR(-ENOENT);}其源码如下:bool try_module_get(struct module *module){bool ret = true;//首先这个模块不能为nullif (module) {// 由于要增加模块的引用计数,因此需要通过preempt_disable()/preempt_enable()来禁止内核抢占preempt_disable();/* Note: here, we can fail to get a reference */// 首先通过module_is_live 判读模块处于活动状态,这个函数其实就是判断模块的flag是否是MODULE_STATE_GOING。然后通过atomic_inc_not_zero来增加模块的引用计数if (likely(module_is_live(module) && atomic_inc_not_zero(&module->refcnt) != 0))trace_module_get(module, _RET_IP_);elseret = false;preempt_enable();}return ret;}我们来看看atomic_inc_not_zero的实现#ifndef atomic_inc_not_zero#define atomic_inc_not_zero(v)atomic_add_unless((v), 1, 0)#endif继续看atomic_add_unlessstatic inline int atomic_add_unless(atomic_t *v, int a, int u){return __atomic_add_unless(v, a, u) != u;}替换一下等于调用__atomic_add_unless(v, 1, 0) != 0;其源码如下:#ifndef __atomic_add_unlessstatic inline int __atomic_add_unless(atomic_t *v, int a, int u){int c, old;//首先读取v这个地址里面的值,首先v这个地址里面的值不能是u,这里u等于0,因为前面已经判断过模块是活动的,因此这c肯定不等于0// 然后调用atomic_cmpxchgc = atomic_read(v);while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c)c = old;return c;}#endif#define atomic_cmpxchg(v, old, new)(cmpxchg(&((v)->counter), (old), (new)))#ifndef cmpxchg64_local#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))#endif#define cmpxchg(ptr, o, n)cmpxchg_local((ptr), (o), (n))static inline u64 __cmpxchg64_local_generic(volatile void *ptr,u64 old, u64 new){u64 prev;unsigned long flags;raw_local_irq_save(flags);prev = *(u64 *)ptr;if (prev == old)*(u64 *)ptr = new;raw_local_irq_restore(flags);return prev;}原来__cmpxchg64_local_generic的作用首先读取ptr这个地址里面的值,如果这个值等于old,就给ptr 赋值为new,但是返回ptr之前的旧值old回到__atomic_add_unless 中的atomic_cmpxchg,就是先读取v里面的值,如果值等于1的话,这时c就等于1,然后给v加1,这个时候v里面的值是2,返回c的值,也就是1最后总结一下:static inline int atomic_add_unless(atomic_t *v, int a, int u){return __atomic_add_unless(v, a, u) != u;}可以简单的认为: @a to @v, so long as @v was not already @u.Returns non-zero if @v was not @u, and zero otherwise.也就是返回非零表示v已经加上a了.
阅读全文
0 0
- 模块API之try_module_get
- 模块API之__module_address
- 模块API之__module_text_address
- 模块API之find_module
- 模块API之module_is_live
- 模块API之module_refcount
- 模块API之module_address_lookup
- 模块API之lookup_module_symbol_name
- 模块API之lookup_module_symbol_attrs
- 模块API之module_get_kallsym
- 模块API之print_modules
- 模块API之ref_module
- 模块API之register_module_notifier
- 模块API之each_symbol_section
- 模块API之symbol_put_addr
- 模块API之sprint_symbol
- 模块API之print_symbol
- 模块API之module_put/__module_get
- Android Studio手动配置Gradle的方法
- 学习解01背包问题的记录(Java描述)
- 17-11-03
- 主流嵌入式开源GUI比较
- nfs速度优化
- 模块API之try_module_get
- asdsadas
- 接口测试学习总结
- Python之scrapy使用教程
- PEID加密算法识别插件Krypto ANALyzer
- hadoop实现wordcount的三种方法
- 状态保持
- 吴恩达【深度学习工程师】学习笔记(六)
- Bootstrap学习笔记 10