Blame view

include/linux/idr.h 4.71 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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.
   */
f668ab1ac   Luben Tuikov   include/linux: en...
11
12
13
  
  #ifndef __IDR_H__
  #define __IDR_H__
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
  #include <linux/types.h>
  #include <linux/bitops.h>
199f0ca51   Akinobu Mita   idr: create idr_l...
16
  #include <linux/init.h>
2027d1abc   Nadia Derbey   idr: change the i...
17
  #include <linux/rcupdate.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
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
  
  #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" */
d2c2486bc   Arnd Bergmann   idr: __rcu annota...
52
  	struct idr_layer __rcu	*ary[1<<IDR_BITS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  	int			 count;	 /* When zero, we can release it */
6ff2d39b9   Manfred Spraul   lib/idr.c: fix rc...
54
  	int			 layer;	 /* distance from leaf */
2027d1abc   Nadia Derbey   idr: change the i...
55
  	struct rcu_head		 rcu_head;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  };
  
  struct idr {
d2c2486bc   Arnd Bergmann   idr: __rcu annota...
59
  	struct idr_layer __rcu *top;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  	struct idr_layer *id_free;
6ff2d39b9   Manfred Spraul   lib/idr.c: fix rc...
61
  	int		  layers; /* only valid without concurrent changes */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
64
65
66
67
68
69
70
71
  	int		  id_free_cnt;
  	spinlock_t	  lock;
  };
  
  #define IDR_INIT(name)						\
  {								\
  	.top		= NULL,					\
  	.id_free	= NULL,					\
  	.layers 	= 0,					\
  	.id_free_cnt	= 0,					\
e4d919188   Ingo Molnar   [PATCH] lockdep: ...
72
  	.lock		= __SPIN_LOCK_UNLOCKED(name.lock),	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
  }
  #define DEFINE_IDR(name)	struct idr name = IDR_INIT(name)
944ca05c7   Nadia Derbey   idr: error checki...
75
76
77
78
79
  /* 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)
f9c46d6ea   Nadia Derbey   idr: make idr_fin...
80
  /**
56083ab17   Randy Dunlap   docbook: add idr/...
81
   * DOC: idr sync
f9c46d6ea   Nadia Derbey   idr: make idr_fin...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
   * 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).
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
99
100
  /*
   * This is what we export.
   */
  
  void *idr_find(struct idr *idp, int id);
fd4f2df24   Al Viro   [PATCH] gfp_t: lib/*
101
  int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
  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);
96d7fa421   Kristian Hoegsberg   lib: add idr_for_...
104
105
  int idr_for_each(struct idr *idp,
  		 int (*fn)(int id, void *p, void *data), void *data);
38460b48d   KAMEZAWA Hiroyuki   cgroup: CSS ID su...
106
  void *idr_get_next(struct idr *idp, int *nextid);
5806f07cd   Jeff Mahoney   [PATCH] lib: add ...
107
  void *idr_replace(struct idr *idp, void *ptr, int id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
  void idr_remove(struct idr *idp, int id);
23936cc0b   Kristian Hoegsberg   lib: add idr_remo...
109
  void idr_remove_all(struct idr *idp);
8d3b35914   Andrew Morton   [PATCH] inotify/i...
110
  void idr_destroy(struct idr *idp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  void idr_init(struct idr *idp);
f668ab1ac   Luben Tuikov   include/linux: en...
112

72dba584b   Tejun Heo   ida: implement id...
113
114
115
116
  
  /*
   * IDA - IDR based id allocator, use when translation from id to
   * pointer isn't necessary.
ed9f524ac   Namhyung Kim   ida: document IDA...
117
118
119
   *
   * IDA_BITMAP_LONGS is calculated to be one less to accommodate
   * ida_bitmap->nr_busy so that the whole struct fits in 128 bytes.
72dba584b   Tejun Heo   ida: implement id...
120
121
   */
  #define IDA_CHUNK_SIZE		128	/* 128 bytes per chunk */
ed9f524ac   Namhyung Kim   ida: document IDA...
122
123
  #define IDA_BITMAP_LONGS	(IDA_CHUNK_SIZE / sizeof(long) - 1)
  #define IDA_BITMAP_BITS 	(IDA_BITMAP_LONGS * sizeof(long) * 8)
72dba584b   Tejun Heo   ida: implement id...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
  
  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);
88eca0207   Rusty Russell   ida: simplified f...
144
145
146
  int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end,
  		   gfp_t gfp_mask);
  void ida_simple_remove(struct ida *ida, unsigned int id);
199f0ca51   Akinobu Mita   idr: create idr_l...
147
  void __init idr_init_cache(void);
f668ab1ac   Luben Tuikov   include/linux: en...
148
  #endif /* __IDR_H__ */