1 /* Copyright (c) 2008, Sandia National Laboratories */
3 #include <lwk/kernel.h>
4 #include <lwk/idspace.h>
18 calc_order(struct idspace *idspace)
20 size_t pages = DIV_ROUND_UP(idspace->size, PAGE_SIZE * 8);
21 return roundup_pow_of_two(pages);
25 idspace_create(id_t min_id, id_t max_id, idspace_t *idspace)
29 if ((min_id == ANY_ID) || (max_id == ANY_ID))
38 if (!(spc = kmem_alloc(sizeof(*spc))))
43 spc->size = max_id - min_id + 1;
47 if (!(spc->bitmap = kmem_get_pages(calc_order(spc)))) {
58 idspace_destroy(idspace_t idspace)
60 struct idspace *spc = idspace;
65 kmem_free_pages(spc->bitmap, calc_order(spc));
72 idspace_alloc_id(idspace_t idspace, id_t request, id_t *id)
74 struct idspace *spc = idspace;
80 if ((request != ANY_ID) &&
81 ((request < spc->min_id) || (request > spc->max_id)))
84 if (spc->size == spc->ids_in_use)
87 if (request == ANY_ID) {
88 /* Allocate any available id */
89 bit = find_next_zero_bit(spc->bitmap, spc->size, spc->offset);
90 /* Handle wrap-around */
92 bit = find_next_zero_bit(spc->bitmap, spc->offset, 0);
93 /* Next time start looking at the next id */
94 spc->offset = bit + 1;
95 if (spc->offset == spc->size)
98 /* Allocate a specific ID */
99 bit = request - spc->min_id;
102 if (test_and_set_bit(bit, spc->bitmap))
107 *id = bit + spc->min_id;
113 idspace_free_id(idspace_t idspace, id_t id)
115 struct idspace *spc = idspace;
121 if ((id == ANY_ID) || (id < spc->min_id) || (id > spc->max_id))
124 bit = id - spc->min_id;
125 if (test_and_clear_bit(bit, spc->bitmap) == 0)