fork 分配pid位图法

typedef struct pidmap {
 atomic_t nr_free; //表示已经分配多少的pid
 void *page; //页
} pidmap_t;
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;
}
总结一下 什么是位图法 一个页面就是4K
4K里面一共有4096字节 一个字节8个位那么也就是 4096*8=32768 能够表示的数就是0-32767 所以更加节约空间也更方便查询位 一与就知道分配了没

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值