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

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

像struct class *cls = class_create();这种语句,其中返回的指针值并不行kmalloc一样这么简单,只判断是否为NULL就可以了,内核是返回其错误值。那么我怎么来判断它呢,总不能用if()来将每个错误例出来吧,这里我们的IS_ERR()宏就发挥作用了。先看源代码,再讲原理,看看内核中的巧妙设计思路。
/*    include/linux/err.h    */
static inline long __must_check IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
内核中的函数常常返回指针,问题是如果出错,也希望能够通过返回的指针体现出来。
所幸的是,内核返回的指针一般是指向页面的边界(4K边界),即
ptr & 0xfff == 0
这样ptr的值不可能落在(0xfffff000,0xffffffff)之间,而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long,正好在(0xfffff000,0xffffffff)之间。因此可以用
(unsigned long)ptr > (unsigned long)-1000L
也就等效于(x) >= (unsigned long)-MAX_ERRNO
其中MAX_ERRNO 为4095

来判断内核函数的返回值是一个有效的指针,还是一个出错代码。

涉及到的任何一个指针,必然有三种情况,一种是有效指针,一种是NULL,空指针,一种是错误指针,或者说无效指针.而所谓的错误指针就是指其已经到达了 最后一个page.比如对于32bit的系统来说,内核空间最高地址0xffffffff,那么最后一个page就是指的 0xfffff000~0xffffffff(假设4k一个page).这段地址是被保留的,如果超过这个地址,则肯定是错误的。

而我们的错误码的值在内存中定义都是这样的(include/linux/errno.h):
......
#define    ENOLCK        77    /* No record locks available */
#define    ENOSYS        78    /* Function not implemented */
#define    ENOMSG        80    /* No message of desired type */
#define    EIDRM        81    /* Identifier removed */
#define    ENOSR        82    /* Out of streams resources */
#define    ETIME        83    /* Timer expired */
#define    EBADMSG        84    /* Not a data message */
#define    EPROTO        85    /* Protocol error */
#define    ENODATA        86    /* No data available */
#define    ENOSTR        87    /* Device not a stream */.
........
现在应该知道为什么我写返回错误码的时候也加个负号如 -ENOSYS这样子了。
至于PTR_ERR(), ERR_PTR(),只是强制转换以下而已,源代码如下(include/linux/err.h) :
static inline void * __must_check ERR_PTR(long error)
{
return (void *) error;
}
static inline long __must_check PTR_ERR(const void *ptr)
{
return (long) ptr;
}
所以像上面的cls例子可以这样写:
struct class *cls = class_create(....);
if(IS_ERR(cls))
{
ret =PTR_ERR(cls);
return ret;
}

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

你可能感兴趣的文章
Android开发者,2020,你还敢再忽视LeakCanary?
查看>>
干货分享:Android RecyclerView(进阶篇)
查看>>
Android设计模式七大原则,原来还可以这么玩?
查看>>
入门:给Android开发者 UI 自动化测试上手指南
查看>>
干货分享:Android图片资源导入之Vector Asset
查看>>
赶紧试试,Android 中心区域选中图表 WheelChart!!!
查看>>
Flutter常用组件-ListView 列表组件
查看>>
从源码的角度去解析Android Fragment (一)
查看>>
从源码的角度去解析Android Fragment(二)
查看>>
入门的Android架构师需要掌握哪些技能?
查看>>
玩GitHub?你必须知道的十个开源项目!!!
查看>>
三分钟带你了解AndroidAutoLayout
查看>>
Android最强技术实现:最强保活黑科技
查看>>
字节iOS开发岗面试真题,我挂了,希望你们加油!
查看>>
干货分享:基于IntelliJ IDEA实现AndroidStudio自定义插件:创建模板工程(包含:文件IO处理、弹框定制等技术点)
查看>>
干货分享:如何用Retrofit直接获得Json数据(字符串)
查看>>
大厂划重点总结5个Kotlin 小特性
查看>>
Android一行解决所有双击优化的问题
查看>>
你有几种实现方案Android 设备唯一标识?
查看>>
重磅来袭:Android UI 线程更新UI也会崩溃???
查看>>