int alloc_pidmap(void)
{
int i, offset, max_scan, pid, last = last_pid;//last_pid 是全局变量
pidmap_t *map; //分配的单位 看结构体
pid = last + 1;//先给全局的最后的pid+1
if (pid >= pid_max)//* 这个要注意一下 首先这个pid_max=32768 是可以修改的 别傻傻认为是不变的 不然底下的工作就没有多少意义了
pid = RESERVED_PIDS;//这个是表示如果超过了pid_max把pid=300 可以认为就是一个参数检查
offset = pid & BITS_PER_PAGE_MASK;//偏移量
map = &pidmap_array[pid/BITS_PER_PAGE];//页面地址 这个就出来了 如果一直认为是pid 小于pid_max 那么一直都是0;
max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;//页面个数
for (i = 0; i <= max_scan; ++i) {
if (unlikely(!map->page)) {//表示如果第一次分配页面地址map那么就要开始分配页面了
unsigned long page = get_zeroed_page(GFP_KERNEL);//分配一个空的页面
/*
* Free the page if someone raced with us
* installing it:
*/
spin_lock(&pidmap_lock);//加锁表示肯定防止冲突
if (map->page)
free_page(page);
else
map->page = (void *)page;
spin_unlock(&pidmap_lock);
if (unlikely(!map->page))
break;
}
if (likely(atomic_read(&map->nr_free))) {
do {
if (!test_and_set_bit(offset, map->page)) {
atomic_dec(&map->nr_free);
last_pid = pid;
return pid;
}//表示如果这个pid 如果没有被分配那就把全局的last_pid分配了
offset = find_next_offset(map, offset);//如果pid已经分配了就从头寻找第一个为0的pid //为什么要检查 因为pid 可能进程不用了肯定要回收 所有可能最后的可能还会被占用pid
pid = mk_pid(map, offset);
/*
* 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 &&
(i != max_scan || pid < last ||
!((last+1) & BITS_PER_PAGE_MASK)));
}
if (map < &pidmap_array[(pid_max-1)/BITS_PER_PAGE]) {
++map;
offset = 0;
} else {
map = &pidmap_array[0];
offset = RESERVED_PIDS;
if (unlikely(last == offset))
break;
}
pid = mk_pid(map, offset);
}
return -1;
}