xref: /f-stack/dpdk/drivers/net/bnxt/tf_core/bitalloc.h (revision 2d9fd380)
1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  * Copyright(c) 2019-2020 Broadcom
3*2d9fd380Sjfb8856606  * All rights reserved.
4*2d9fd380Sjfb8856606  */
5*2d9fd380Sjfb8856606 
6*2d9fd380Sjfb8856606 #ifndef _BITALLOC_H_
7*2d9fd380Sjfb8856606 #define _BITALLOC_H_
8*2d9fd380Sjfb8856606 
9*2d9fd380Sjfb8856606 #include <stdint.h>
10*2d9fd380Sjfb8856606 
11*2d9fd380Sjfb8856606 /* Bitalloc works on uint32_t as its word size */
12*2d9fd380Sjfb8856606 typedef uint32_t bitalloc_word_t;
13*2d9fd380Sjfb8856606 
14*2d9fd380Sjfb8856606 struct bitalloc {
15*2d9fd380Sjfb8856606 	bitalloc_word_t size;
16*2d9fd380Sjfb8856606 	bitalloc_word_t free_count;
17*2d9fd380Sjfb8856606 	bitalloc_word_t storage[1];
18*2d9fd380Sjfb8856606 };
19*2d9fd380Sjfb8856606 
20*2d9fd380Sjfb8856606 #define BA_L0(s) (((s) + 31) / 32)
21*2d9fd380Sjfb8856606 #define BA_L1(s) ((BA_L0(s) + 31) / 32)
22*2d9fd380Sjfb8856606 #define BA_L2(s) ((BA_L1(s) + 31) / 32)
23*2d9fd380Sjfb8856606 #define BA_L3(s) ((BA_L2(s) + 31) / 32)
24*2d9fd380Sjfb8856606 #define BA_L4(s) ((BA_L3(s) + 31) / 32)
25*2d9fd380Sjfb8856606 
26*2d9fd380Sjfb8856606 #define BITALLOC_SIZEOF(size)                                    \
27*2d9fd380Sjfb8856606 	(sizeof(struct bitalloc) *				 \
28*2d9fd380Sjfb8856606 	 (((sizeof(struct bitalloc) +				 \
29*2d9fd380Sjfb8856606 	    sizeof(struct bitalloc) - 1 +			 \
30*2d9fd380Sjfb8856606 	    (sizeof(bitalloc_word_t) *				 \
31*2d9fd380Sjfb8856606 	     ((BA_L0(size) - 1) +				 \
32*2d9fd380Sjfb8856606 	      ((BA_L0(size) == 1) ? 0 : (BA_L1(size) + 1)) +	 \
33*2d9fd380Sjfb8856606 	      ((BA_L1(size) == 1) ? 0 : (BA_L2(size) + 1)) +	 \
34*2d9fd380Sjfb8856606 	      ((BA_L2(size) == 1) ? 0 : (BA_L3(size) + 1)) +	 \
35*2d9fd380Sjfb8856606 	      ((BA_L3(size) == 1) ? 0 : (BA_L4(size) + 1)))))) / \
36*2d9fd380Sjfb8856606 	  sizeof(struct bitalloc)))
37*2d9fd380Sjfb8856606 
38*2d9fd380Sjfb8856606 #define BITALLOC_MAX_SIZE (32 * 32 * 32 * 32 * 32 * 32)
39*2d9fd380Sjfb8856606 
40*2d9fd380Sjfb8856606 /* The instantiation of a bitalloc looks a bit odd. Since a
41*2d9fd380Sjfb8856606  * bit allocator has variable storage, we need a way to get a
42*2d9fd380Sjfb8856606  * a pointer to a bitalloc structure that points to the correct
43*2d9fd380Sjfb8856606  * amount of storage. We do this by creating an array of
44*2d9fd380Sjfb8856606  * bitalloc where the first element in the array is the
45*2d9fd380Sjfb8856606  * actual bitalloc base structure, and the remaining elements
46*2d9fd380Sjfb8856606  * in the array provide the storage for it. This approach allows
47*2d9fd380Sjfb8856606  * instances to be individual variables or members of larger
48*2d9fd380Sjfb8856606  * structures.
49*2d9fd380Sjfb8856606  */
50*2d9fd380Sjfb8856606 #define BITALLOC_INST(name, size)                      \
51*2d9fd380Sjfb8856606 	struct bitalloc name[(BITALLOC_SIZEOF(size) /  \
52*2d9fd380Sjfb8856606 			      sizeof(struct bitalloc))]
53*2d9fd380Sjfb8856606 
54*2d9fd380Sjfb8856606 /* Symbolic return codes */
55*2d9fd380Sjfb8856606 #define BA_SUCCESS           0
56*2d9fd380Sjfb8856606 #define BA_FAIL             -1
57*2d9fd380Sjfb8856606 #define BA_ENTRY_FREE        0
58*2d9fd380Sjfb8856606 #define BA_ENTRY_IN_USE      1
59*2d9fd380Sjfb8856606 #define BA_NO_ENTRY_FOUND   -1
60*2d9fd380Sjfb8856606 
61*2d9fd380Sjfb8856606 /**
62*2d9fd380Sjfb8856606  * Initializates the bitallocator
63*2d9fd380Sjfb8856606  *
64*2d9fd380Sjfb8856606  * Returns 0 on success, -1 on failure.  Size is arbitrary up to
65*2d9fd380Sjfb8856606  * BITALLOC_MAX_SIZE
66*2d9fd380Sjfb8856606  */
67*2d9fd380Sjfb8856606 int ba_init(struct bitalloc *pool, int size);
68*2d9fd380Sjfb8856606 
69*2d9fd380Sjfb8856606 /**
70*2d9fd380Sjfb8856606  * Returns -1 on failure, or index of allocated entry
71*2d9fd380Sjfb8856606  */
72*2d9fd380Sjfb8856606 int ba_alloc(struct bitalloc *pool);
73*2d9fd380Sjfb8856606 int ba_alloc_index(struct bitalloc *pool, int index);
74*2d9fd380Sjfb8856606 
75*2d9fd380Sjfb8856606 /**
76*2d9fd380Sjfb8856606  * Returns -1 on failure, or index of allocated entry
77*2d9fd380Sjfb8856606  */
78*2d9fd380Sjfb8856606 int ba_alloc_reverse(struct bitalloc *pool);
79*2d9fd380Sjfb8856606 
80*2d9fd380Sjfb8856606 /**
81*2d9fd380Sjfb8856606  * Query a particular index in a pool to check if its in use.
82*2d9fd380Sjfb8856606  *
83*2d9fd380Sjfb8856606  * Returns -1 on invalid index, 1 if the index is allocated, 0 if it
84*2d9fd380Sjfb8856606  * is free
85*2d9fd380Sjfb8856606  */
86*2d9fd380Sjfb8856606 int ba_inuse(struct bitalloc *pool, int index);
87*2d9fd380Sjfb8856606 
88*2d9fd380Sjfb8856606 /**
89*2d9fd380Sjfb8856606  * Variant of ba_inuse that frees the index if it is allocated, same
90*2d9fd380Sjfb8856606  * return codes as ba_inuse
91*2d9fd380Sjfb8856606  */
92*2d9fd380Sjfb8856606 int ba_inuse_free(struct bitalloc *pool, int index);
93*2d9fd380Sjfb8856606 
94*2d9fd380Sjfb8856606 /**
95*2d9fd380Sjfb8856606  * Find next index that is in use, start checking at index 'idx'
96*2d9fd380Sjfb8856606  *
97*2d9fd380Sjfb8856606  * Returns next index that is in use on success, or
98*2d9fd380Sjfb8856606  * -1 if no in use index is found
99*2d9fd380Sjfb8856606  */
100*2d9fd380Sjfb8856606 int ba_find_next_inuse(struct bitalloc *pool, int idx);
101*2d9fd380Sjfb8856606 
102*2d9fd380Sjfb8856606 /**
103*2d9fd380Sjfb8856606  * Variant of ba_find_next_inuse that also frees the next in use index,
104*2d9fd380Sjfb8856606  * same return codes as ba_find_next_inuse
105*2d9fd380Sjfb8856606  */
106*2d9fd380Sjfb8856606 int ba_find_next_inuse_free(struct bitalloc *pool, int idx);
107*2d9fd380Sjfb8856606 
108*2d9fd380Sjfb8856606 /**
109*2d9fd380Sjfb8856606  * Multiple freeing of the same index has no negative side effects,
110*2d9fd380Sjfb8856606  * but will return -1.  returns -1 on failure, 0 on success.
111*2d9fd380Sjfb8856606  */
112*2d9fd380Sjfb8856606 int ba_free(struct bitalloc *pool, int index);
113*2d9fd380Sjfb8856606 
114*2d9fd380Sjfb8856606 /**
115*2d9fd380Sjfb8856606  * Returns the pool's free count
116*2d9fd380Sjfb8856606  */
117*2d9fd380Sjfb8856606 int ba_free_count(struct bitalloc *pool);
118*2d9fd380Sjfb8856606 
119*2d9fd380Sjfb8856606 /**
120*2d9fd380Sjfb8856606  * Returns the pool's in use count
121*2d9fd380Sjfb8856606  */
122*2d9fd380Sjfb8856606 int ba_inuse_count(struct bitalloc *pool);
123*2d9fd380Sjfb8856606 
124*2d9fd380Sjfb8856606 #endif /* _BITALLOC_H_ */
125