Linux-算法学习(分配pid)
2014-03-27 20:37
211 查看
该分配进程pid的函数被定义在:kernel/pid.c 数据定义: typedef struct pidmap { atomic_t nr_free;//当前空闲的pid的个数 void *page;//用数组代表位图,每一项为一个字长,用位来表示是否该pid被分配. } pidmap_t; BITS_PE_PAGE:一个页面中可以表示的数的个数,32位的为2^15(页面大小4KB) BITS_PE_PAGE_MASK:BITS_PE_PAGE-1 代码解析 int alloc_pidmap(void) { int i, offset, max_scan, pid, last = last_pid; pidmap_t *map; pid = last + 1;//last为全局变量,表示上次分配pid时分出去的 if (pid >= pid_max) pid = RESERVED_PIDS;//300,前300个pid是固定的,不可以分配的 offset = pid & BITS_PER_PAGE_MASK;//找出pid在某一个页面中的偏移量 map = &pidmap_array[pid/BITS_PER_PAGE];//&pidmap_array[i]表示的是第i个描述pid使用状况的页面的地址. //pid/BITS_PER_PAGE代表的是该pid在第几个描述pid的页面 max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;//获得pid号在内存中表示占用的页面个数,32位的为1 //seem the page number for (i = 0; i <= max_scan; ++i) {//对每个页面进行扫描 if (unlikely(!map->page)) {//如果map所指的页的物理地址为空 unsigned long page = get_zeroed_page(GFP_KERNEL);//在内存中分配一个物理页面 //GFP_KERNEL wait|io|fs /* * Free the page if someone raced with us * installing it: */ spin_lock(&pidmap_lock); if (map->page)//因为可能是多处理器,或者进程的交叉执行,所以需要再次判断map所指的物理页面是否为空 free_page(page);//为空的话就把刚刚申请的页面释放 else map->page = (void *)page; spin_unlock(&pidmap_lock); if (unlikely(!map->page))//如果页面指针还是为空,分配失败,跳出循环,返回-1 break;// cannot alloc pid } if (likely(atomic_read(&map->nr_free))) {//如果该页面的空闲pid的个数不为0的话 do { if (!test_and_set_bit(offset, map->page)) {//判断该页面中offset偏移量表示的pid是否为空 atomic_dec(&map->nr_free);//为空在空闲的pid个数-- last_pid = pid;//全局变量更新 return pid; } offset = find_next_offset(map, offset);//失败则寻找下一个pid pid = mk_pid(map, offset);//根据map和offset的值获得pid //new pid /* * find_next_offset() found a bit, the pid from it * is in-bounds, and if we fell back to the last * bitmap block and the final block was the same * as the starting point, pid is before last_pid. */ } while (offset < BITS_PER_PAGE && pid < pid_max &&//判断offset是否超过一个页面可以表示的最大的pid数或者最大的pid (i != max_scan || pid < last ||//如果i==max_scan的话,如果pid>=last因为之前已经判断过,就没必要了 !((last+1) & BITS_PER_PAGE_MASK))); //对于max_scan等于1,也需要对其扫描两编,第一次是last之后的,第二次是last之前的. } if (map < &pidmap_array[(pid_max-1)/BITS_PER_PAGE]) { ++map;//如果map没有超过最大的pid所占的页面的地址 offset = 0; } else { map = &pidmap_array[0];//对于分配地一个pid的页面,前300是固定的,所以offset需要赋值为非0 offset = RESERVED_PIDS; if (unlikely(last == offset)) break; } pid = mk_pid(map, offset);//重新计算pid的值 } return -1; }
相关文章推荐
- linux 进程的pid分配策略——pid位图算法
- linux 进程的pid分配策略——pid位图算法 [转]
- linux 进程的pid分配策略——pid位图算法 [转]
- linux 进程的pid分配策略——pid位图算法
- 【linux 指令学习】 taskset -pc PID 查看线程占用cpu核
- 通过Linux的ACL学习ACL权限分配原理_Linux_it动力
- Linux学习一 I/O内存分配与I/O访问
- linux 进程学习笔记-进程ID,PID
- linux 进程的pid分配策略——pid位图算法
- linux中系统性能检测工具pidstat学习
- Linux内核内存管理之SLAB内存管理算法(三) --slab对象的分配与释放
- linux学习之路之加密类型及其相关算法
- linux下socket的分配算法
- Linux设备驱动程序学习(8)-分配内存
- Linux设备驱动程序学习(8)-分配内存
- linux学习之路之加密类型及其相关算法
- Linux学习--用户(组)管理,权限分配
- Linux设备驱动程序学习之数据类型与内存分配 .
- Linux设备驱动程序学习之分配内存
- Linux学习总结—进程切换和调度算法深入分析