Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int i, offset, max_scan, pid, last = last_pid;
- pidmap_t *map;
- pid = last + 1;
- if (pid >= pid_max)
- pid = RESERVED_PIDS;
- offset = pid & BITS_PER_PAGE_MASK;
- map = &pidmap_array[pid/BITS_PER_PAGE];
- max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
- for (i = 0; i <= max_scan; ++i) {
- if (unlikely(!map->page)) {
- 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;
- }
- offset = find_next_offset(map, offset);
- 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;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement