前言
Linux内核实现了一下常用的内建数据结构,主要有:
链表
队列
映射
二叉树
映射也称为关联数组,就是每个唯一的id对应一个自定义的数据结构指针。感觉关于映射的知识比较复杂,没有深入理解,这里就记录一下一些常用的操作API。idr数据结构用于映射用户空间的UID。
初始化一个idr
建立一个idr的过程分两步,先静态定义或者动态创建一个idr数据结构,然后调用idr_init():
struct idr id; //静态定义idr结构体
idr_init(&id); //初始化idr结构体
分配一个UID
分配一个新的UID也分为两步:
第一步,告诉idr需要分配新的UID,调整后备树的大小
int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
//注意该函数成功时返回1,失败时返回0。
第二步,获取新的UID
int idr_get_new(struct idr *idp, void *ptr, int *id);
该方法使用idp指向的idr分配新的UID,将其关联到指针ptr上。成功时返回0,并将分配的UID存在id上。错误时返回非0的错误码,-EAGAIN表示需要再次调用idr_pre_get(),-ENOSPC表示idr已满。
例:
do {
if (!idr_pre_get(&idp, GFP_KERNEL))
return -ENOSPC;
ret = idr_get_new(&idp, ptr, &id);
printk(KERN_ALERT "id=%d\n", id);
} while(ret == -EAGAIN);
函数idr_get_new_above()作用与idr_get_new()作用相同,只不过指定了最小的UID限制,就是确保获取的新的UID大于等于传入的参数starting_id。
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
查找UID
在idr中查找UID,idr返回对应的指针。
void *idr_find(struct idr *idp, int id); //查找id对应的指针
如果成功返回id对应的指针,失败则返回空指针。
移除UID
从idr中移除UID
void idr_remove(struct idr *idp, int id); //移除id
void idr_remove_all(struct idr *idp); //移除所有id
若成功,则将id关联的指针和一起从映射中删除,若失败了也不会提示、、、
撤销idr
void idr_destroy(struct idr *idp); //销毁idr_layer空闲链表
该函数会释放idr中未使用的内存。并不会释放已分配给UID使用的内存。