idr.h 4.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * include/linux/idr.h
 * 
 * 2002-10-18  written by Jim Houston jim.houston@ccur.com
 *	Copyright (C) 2002 by Concurrent Computer Corporation
 *	Distributed under the GNU GPL license version 2.
 *
 * Small id to pointer translation service avoiding fixed sized
 * tables.
 */
11 12 13 14

#ifndef __IDR_H__
#define __IDR_H__

L
Linus Torvalds 已提交
15 16
#include <linux/types.h>
#include <linux/bitops.h>
17
#include <linux/init.h>
N
Nadia Derbey 已提交
18
#include <linux/rcupdate.h>
L
Linus Torvalds 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

#if BITS_PER_LONG == 32
# define IDR_BITS 5
# define IDR_FULL 0xfffffffful
/* We can only use two of the bits in the top level because there is
   only one possible bit in the top level (5 bits * 7 levels = 35
   bits, but you only use 31 bits in the id). */
# define TOP_LEVEL_FULL (IDR_FULL >> 30)
#elif BITS_PER_LONG == 64
# define IDR_BITS 6
# define IDR_FULL 0xfffffffffffffffful
/* We can only use two of the bits in the top level because there is
   only one possible bit in the top level (6 bits * 6 levels = 36
   bits, but you only use 31 bits in the id). */
# define TOP_LEVEL_FULL (IDR_FULL >> 62)
#else
# error "BITS_PER_LONG is not 32 or 64"
#endif

#define IDR_SIZE (1 << IDR_BITS)
#define IDR_MASK ((1 << IDR_BITS)-1)

#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 */
#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS

/* Number of id_layer structs to leave in free list */
#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL

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 */
55
	int			 layer;	 /* distance from leaf */
N
Nadia Derbey 已提交
56
	struct rcu_head		 rcu_head;
L
Linus Torvalds 已提交
57 58 59 60 61
};

struct idr {
	struct idr_layer *top;
	struct idr_layer *id_free;
62
	int		  layers; /* only valid without concurrent changes */
L
Linus Torvalds 已提交
63 64 65 66 67 68 69 70 71 72
	int		  id_free_cnt;
	spinlock_t	  lock;
};

#define IDR_INIT(name)						\
{								\
	.top		= NULL,					\
	.id_free	= NULL,					\
	.layers 	= 0,					\
	.id_free_cnt	= 0,					\
73
	.lock		= __SPIN_LOCK_UNLOCKED(name.lock),	\
L
Linus Torvalds 已提交
74 75 76
}
#define DEFINE_IDR(name)	struct idr name = IDR_INIT(name)

N
Nadia Derbey 已提交
77 78 79 80 81 82
/* Actions to be taken after a call to _idr_sub_alloc */
#define IDR_NEED_TO_GROW -2
#define IDR_NOMORE_SPACE -3

#define _idr_rc_to_errno(rc) ((rc) == -1 ? -EAGAIN : -ENOSPC)

N
Nadia Derbey 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
/**
 * idr synchronization (stolen from radix-tree.h)
 *
 * idr_find() is able to be called locklessly, using RCU. The caller must
 * ensure calls to this function are made within rcu_read_lock() regions.
 * Other readers (lock-free or otherwise) and modifications may be running
 * concurrently.
 *
 * It is still required that the caller manage the synchronization and
 * lifetimes of the items. So if RCU lock-free lookups are used, typically
 * this would mean that the items have their own locks, or are amenable to
 * lock-free access; and that the items are freed by RCU (or only freed after
 * having been deleted from the idr tree *and* a synchronize_rcu() grace
 * period).
 */

L
Linus Torvalds 已提交
99 100 101 102 103
/*
 * This is what we export.
 */

void *idr_find(struct idr *idp, int id);
A
Al Viro 已提交
104
int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
L
Linus Torvalds 已提交
105 106
int idr_get_new(struct idr *idp, void *ptr, int *id);
int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
K
Kristian Hoegsberg 已提交
107 108
int idr_for_each(struct idr *idp,
		 int (*fn)(int id, void *p, void *data), void *data);
K
KAMEZAWA Hiroyuki 已提交
109
void *idr_get_next(struct idr *idp, int *nextid);
J
Jeff Mahoney 已提交
110
void *idr_replace(struct idr *idp, void *ptr, int id);
L
Linus Torvalds 已提交
111
void idr_remove(struct idr *idp, int id);
K
Kristian Hoegsberg 已提交
112
void idr_remove_all(struct idr *idp);
A
Andrew Morton 已提交
113
void idr_destroy(struct idr *idp);
L
Linus Torvalds 已提交
114
void idr_init(struct idr *idp);
115

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144

/*
 * IDA - IDR based id allocator, use when translation from id to
 * pointer isn't necessary.
 */
#define IDA_CHUNK_SIZE		128	/* 128 bytes per chunk */
#define IDA_BITMAP_LONGS	(128 / sizeof(long) - 1)
#define IDA_BITMAP_BITS		(IDA_BITMAP_LONGS * sizeof(long) * 8)

struct ida_bitmap {
	long			nr_busy;
	unsigned long		bitmap[IDA_BITMAP_LONGS];
};

struct ida {
	struct idr		idr;
	struct ida_bitmap	*free_bitmap;
};

#define IDA_INIT(name)		{ .idr = IDR_INIT(name), .free_bitmap = NULL, }
#define DEFINE_IDA(name)	struct ida name = IDA_INIT(name)

int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
int ida_get_new(struct ida *ida, int *p_id);
void ida_remove(struct ida *ida, int id);
void ida_destroy(struct ida *ida);
void ida_init(struct ida *ida);

145 146
void __init idr_init_cache(void);

147
#endif /* __IDR_H__ */