Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 119534
b: refs/heads/master
c: 6ff2d39
h: refs/heads/master
v: v3
  • Loading branch information
Manfred Spraul authored and Linus Torvalds committed Dec 2, 2008
1 parent c6b359e commit 7fce5e2
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1d678f365dae28420fa7329a2a35390b3582678d
refs/heads/master: 6ff2d39b91aec3dcae951afa982059e3dd9b49dc
3 changes: 2 additions & 1 deletion trunk/include/linux/idr.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ struct idr_layer {
unsigned long bitmap; /* A zero bit means "space here" */
struct idr_layer *ary[1<<IDR_BITS];
int count; /* When zero, we can release it */
int layer; /* distance from leaf */
struct rcu_head rcu_head;
};

struct idr {
struct idr_layer *top;
struct idr_layer *id_free;
int layers;
int layers; /* only valid without concurrent changes */
int id_free_cnt;
spinlock_t lock;
};
Expand Down
14 changes: 12 additions & 2 deletions trunk/lib/idr.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
new = get_from_free_list(idp);
if (!new)
return -1;
new->layer = l-1;
rcu_assign_pointer(p->ary[m], new);
p->count++;
}
Expand All @@ -210,6 +211,7 @@ static int idr_get_empty_slot(struct idr *idp, int starting_id,
if (unlikely(!p)) {
if (!(p = get_from_free_list(idp)))
return -1;
p->layer = 0;
layers = 1;
}
/*
Expand Down Expand Up @@ -237,6 +239,7 @@ static int idr_get_empty_slot(struct idr *idp, int starting_id,
}
new->ary[0] = p;
new->count = 1;
new->layer = layers-1;
if (p->bitmap == IDR_FULL)
__set_bit(0, &new->bitmap);
p = new;
Expand Down Expand Up @@ -493,17 +496,21 @@ void *idr_find(struct idr *idp, int id)
int n;
struct idr_layer *p;

n = idp->layers * IDR_BITS;
p = rcu_dereference(idp->top);
if (!p)
return NULL;
n = (p->layer+1) * IDR_BITS;

/* Mask off upper bits we don't use for the search. */
id &= MAX_ID_MASK;

if (id >= (1 << n))
return NULL;
BUG_ON(n == 0);

while (n > 0 && p) {
n -= IDR_BITS;
BUG_ON(n != p->layer*IDR_BITS);
p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
}
return((void *)p);
Expand Down Expand Up @@ -582,8 +589,11 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
int n;
struct idr_layer *p, *old_p;

n = idp->layers * IDR_BITS;
p = idp->top;
if (!p)
return ERR_PTR(-EINVAL);

n = (p->layer+1) * IDR_BITS;

id &= MAX_ID_MASK;

Expand Down

0 comments on commit 7fce5e2

Please sign in to comment.