idr_get_new() currently returns an incrementing counter in the top 8 bits of the counter. Which means that most users have to mask it off again, and we only have a 24-bit range. So remove that counter. Also: - Remove the BITS_PER_INT define due to namespace collision risk. - Make MAX_ID_SHIFT 31, so counters have a 0 to 2G-1 range. - Why is MAX_ID_SHIFT using sizeof(int) and not sizeof(long)? If it's for consistency across 32- and 64-bit machines, why not just make it "31"? - Does this still hold true with the counter removed? /* We can only use half the bits in the top level because there are only four possible bits in the top level (5 bits * 4 levels = 25 bits, but you only use 24 bits in the id). */ If not, what needs to change? --- 25-akpm/include/linux/idr.h | 18 +++++------------- 25-akpm/lib/idr.c | 19 +++---------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff -puN include/linux/idr.h~idr-remove-counter include/linux/idr.h --- 25/include/linux/idr.h~idr-remove-counter 2004-05-12 21:09:39.596676592 -0700 +++ 25-akpm/include/linux/idr.h 2004-05-12 21:18:10.491008848 -0700 @@ -11,8 +11,6 @@ #include #include -#define RESERVED_ID_BITS 8 - #if BITS_PER_LONG == 32 # define IDR_BITS 5 # define IDR_FULL 0xffffffff @@ -32,11 +30,8 @@ #define IDR_SIZE (1 << IDR_BITS) #define IDR_MASK ((1 << IDR_BITS)-1) -/* Define the size of the id's */ -#define BITS_PER_INT (sizeof(int)*8) - -#define MAX_ID_SHIFT (BITS_PER_INT - RESERVED_ID_BITS) -#define MAX_ID_BIT (1 << MAX_ID_SHIFT) +#define MAX_ID_SHIFT (sizeof(int)*8 - 1) +#define MAX_ID_BIT (1U << MAX_ID_SHIFT) #define MAX_ID_MASK (MAX_ID_BIT - 1) /* Leave the possibility of an incomplete final layer */ @@ -46,25 +41,23 @@ #define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL struct idr_layer { - unsigned long bitmap; /* A zero bit means "space here" */ + unsigned long bitmap; /* A zero bit means "space here" */ struct idr_layer *ary[1<= 0 )) { - idp->count++; - v += (idp->count << MAX_ID_SHIFT); - if ( unlikely( v == -1 )) - v += (1L << MAX_ID_SHIFT); - } return(v); } EXPORT_SYMBOL(idr_get_new_above); @@ -334,6 +320,7 @@ static void sub_remove(struct idr *idp, idp->layers = 0; } } + void idr_remove(struct idr *idp, int id) { struct idr_layer *p; _