summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h
blob: bc7be4fcee71ca5a4baa838bf7aeac607bafc4ad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
/* SPDX-License-Identifier: BSD-2-Clause */

/**
 * @file
 *
 * @brief RTEMS File Systems Bitmap Routines
 *
 * @ingroup rtems_rfs
 *
 * RTEMS File Systems Bitmap Routines.
 *
 * These functions manage bit maps. A bit map consists of the map of bit
 * allocated in a block and a search map where a bit represents 32 actual
 * bits. The search map allows for a faster search for an available bit as 32
 * search bits can checked in a test.
 */

/*
 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


#if !defined (_RTEMS_RFS_BITMAPS_H_)
#define _RTEMS_RFS_BITMAPS_H_

#include <rtems/rfs/rtems-rfs-buffer.h>
#include <rtems/rfs/rtems-rfs-file-system-fwd.h>
#include <rtems/rfs/rtems-rfs-trace.h>

/**
 * Define the way the bits are configured. We can have them configured as clear
 * being 0 or clear being 1. This does not effect how masks are defined. A mask
 * always has a 1 for set and 0 for clear.
 */
#define RTEMS_RFS_BITMAP_CLEAR_ZERO 0

#if RTEMS_RFS_BITMAP_CLEAR_ZERO
/*
 * Bit set is a 1 and clear is 0.
 */
#define RTEMS_RFS_BITMAP_BIT_CLEAR          0
#define RTEMS_RFS_BITMAP_BIT_SET            1
#define RTEMS_RFS_BITMAP_ELEMENT_SET        (RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK)
#define RTEMS_RFS_BITMAP_ELEMENT_CLEAR      (0)
#define RTEMS_RFS_BITMAP_SET_BITS(_t, _b)   ((_t) | (_b))
#define RTEMS_RFS_BITMAP_CLEAR_BITS(_t, _b) ((_t) & ~(_b))
#define RTEMS_RFS_BITMAP_TEST_BIT(_t, _b)   (((_t) & (1 << (_b))) != 0 ? true : false)
#else
/*
 * Bit set is a 0 and clear is 1.
 */
#define RTEMS_RFS_BITMAP_BIT_CLEAR          1
#define RTEMS_RFS_BITMAP_BIT_SET            0
#define RTEMS_RFS_BITMAP_ELEMENT_SET        (0)
#define RTEMS_RFS_BITMAP_ELEMENT_CLEAR      (RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK)
#define RTEMS_RFS_BITMAP_SET_BITS(_t, _b)   ((_t) & ~(_b))
#define RTEMS_RFS_BITMAP_CLEAR_BITS(_t, _b) ((_t) | (_b))
#define RTEMS_RFS_BITMAP_TEST_BIT(_t, _b)   (((_t) & (1 << (_b))) == 0 ? true : false)
#endif

/**
 * Invert a mask. Masks are always 1 for set and 0 for clear.
 */
#define RTEMS_RFS_BITMAP_INVERT_MASK(_mask) (~(_mask))

/**
 * This is the full mask of the length of the element. A mask is always a 1 for
 * set and 0 for clear. It is not effected by the state of
 * RTEMS_RFS_BITMAP_CLEAR_ZERO.
 */
#define RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK (0xffffffffUL)

/**
 * The bitmap search window. Searches occur around a seed in either direction
 * for half the window.
 */
#define RTEMS_RFS_BITMAP_SEARCH_WINDOW (rtems_rfs_bitmap_element_bits () * 64)

/**
 * A bit in a map.
 */
typedef int32_t rtems_rfs_bitmap_bit;

/**
 * The basic element of a bitmap. A bitmap is manipulated by elements.
 */
typedef uint32_t rtems_rfs_bitmap_element;

/**
 * The power of 2 number of bits in the element.
 */
#define RTEMS_RFS_ELEMENT_BITS_POWER_2 (5)

/**
 * A bitmap or map is an array of bitmap elements.
 */
typedef rtems_rfs_bitmap_element* rtems_rfs_bitmap_map;

/**
 * The bitmap control is a simple way to manage the various parts of a bitmap.
 */
typedef struct rtems_rfs_bitmap_control_s
{
  rtems_rfs_buffer_handle* buffer;      //< Handle the to buffer with the bit
                                        //map.
  rtems_rfs_file_system*   fs;          //< The map's file system.
  rtems_rfs_buffer_block   block;       //< The map's block number on disk.
  size_t                   size;        //< Number of bits in the map. Passed
                                        //to create.
  size_t                   free;        //< Number of bits in the map that are
                                        //free (clear).
  rtems_rfs_bitmap_map     search_bits; //< The search bit map memory.
} rtems_rfs_bitmap_control;

/**
 * Return the number of bits for the number of bytes provided.
 */
#define rtems_rfs_bitmap_numof_bits(_bytes) (8 * (_bytes))

/**
 * Return the number of bits for the number of bytes provided.  The search
 * element and the element must have the same number of bits.
 */
#define rtems_rfs_bitmap_element_bits() \
  rtems_rfs_bitmap_numof_bits (sizeof (rtems_rfs_bitmap_element))

/**
 * Return the number of bits a search element covers.
 */
#define rtems_rfs_bitmap_search_element_bits() \
  (rtems_rfs_bitmap_element_bits() * rtems_rfs_bitmap_element_bits())

/**
 * Return the number of elements for a given number of bits.
 */
#define rtems_rfs_bitmap_elements(_bits) \
  ((((_bits) - 1) / rtems_rfs_bitmap_element_bits()) + 1)

/**
 * Release the bitmap buffer back to the buffer pool or cache.
 */
#define rtems_rfs_bitmap_release_buffer(_fs, _bm)    \
  rtems_rfs_buffer_handle_release (_fs, (_bm)->buffer)

/**
 * Return the element index for a given bit. We use a macro to hide any
 * implementation assuptions. Typically this would be calculated by dividing
 * the bit index by the number of bits in an element. Given we have a power of
 * 2 as the number of bits we can avoid the division by using a shift. A good
 * compiler should figure this out but I would rather enforce this than rely on
 * the specific backend of a compiler to do the right thing.
 */
#define rtems_rfs_bitmap_map_index(_b) \
  ((_b) >> RTEMS_RFS_ELEMENT_BITS_POWER_2)

/**
 * Return the bit offset for a given bit in an element in a map. See @ref
 * rtems_rfs_bitmap_map_index for a detailed reason why.
 */
#define rtems_rfs_bitmap_map_offset(_b) \
  ((_b) & ((1 << RTEMS_RFS_ELEMENT_BITS_POWER_2) - 1))

/**
 * Return the size of the bitmap.
 */
#define rtems_rfs_bitmap_map_size(_c) ((_c)->size)

/**
 * Return the number of free bits in the bitmap.
 */
#define rtems_rfs_bitmap_map_free(_c) ((_c)->free)

/**
 * Return the buffer handle.
 */
#define rtems_rfs_bitmap_map_handle(_c) ((_c)->buffer)

/**
 * Return the bitmap map block.
 */
#define rtems_rfs_bitmap_map_block(_c) ((_c)->block)

/**
 * Create a bit mask with the specified number of bits up to an element's
 * size. The mask is aligned to bit 0 of the element.
 *
 * @param[in] size is the number of bits in the mask.
 *
 * @return The mask of the argument size number of bits.
 */
rtems_rfs_bitmap_element rtems_rfs_bitmap_mask (unsigned int size);

/**
 * Create a bit mask section. A mask section is a mask that is not aligned to
 * an end of the element.
 *
 * @param[in] start is the first bit of the mask numbered from 0.
 * @param[in] end is the end bit of the mask numbered from 0.
 *
 * @return Mask section as defined by the start and end arguments.
 */
rtems_rfs_bitmap_element rtems_rfs_bitmap_mask_section (unsigned int start,
                                                        unsigned int end);

/**
 * Set a bit in a map and if all the bits are set, set the search map bit as
 * well.
 *
 * @param[in] control is the control for the map.
 * @param[in] bit is the bit in the map to set.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
                              rtems_rfs_bitmap_bit      bit);

/**
 * Clear a bit in a map and make sure the search map bit is clear so a search
 * will find this bit available.
 *
 * @param[in] control is the control for the map.
 * @param[in] bit is the bit in the map to clear.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
                                rtems_rfs_bitmap_bit      bit);

/**
 * Test a bit in the map.
 *
 * @param[in] control is the bitmap control.
 * @param[in] bit is the bit to test.
 * @param[in] state is the state of the bit if no error is returned.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int
rtems_rfs_bitmap_map_test (rtems_rfs_bitmap_control* control,
                           rtems_rfs_bitmap_bit      bit,
                           bool*                     state);

/**
 * Set all bits in the bitmap and set the dirty bit.
 *
 * @param[in] control is the bitmap control.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_map_set_all (rtems_rfs_bitmap_control* control);

/**
 * Clear all bits in the bitmap and set the dirty bit.
 *
 * @param[in] control is the bitmap control.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_map_clear_all (rtems_rfs_bitmap_control* control);

/**
 * Find a free bit searching from the seed up and down until found. The search
 * is performing by moving up from the seed for the window distance then to
 * search down from the seed for the window distance. This is repeated out
 * from the seed for each window until a free bit is found. The search is
 * performed by checking the search map to see if the map has a free bit.
 *
 * @param[in] control is the map control.
 * @param[in] seed is the bit to search out from.
 * @param[out] allocate A bit was allocated.
 * @param[out] bit will contain the bit found free if true is returned.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_map_alloc (rtems_rfs_bitmap_control* control,
                                rtems_rfs_bitmap_bit      seed,
                                bool*                     allocate,
                                rtems_rfs_bitmap_bit*     bit);

/**
 * Create a search bit map from the actual bit map.
 *
 * @param[in] control is the map control.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_create_search (rtems_rfs_bitmap_control* control);

/**
 * Open a bitmap control with a map and search map.
 *
 * @param[in] control is the map control.
 * @param[in] fs is the file system data.
 * @param[in]  buffer is a pointer to the buffer handle the map is
 *           stored in.
 * @param[in] size is the number of bits in the map.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_open (rtems_rfs_bitmap_control* control,
                           rtems_rfs_file_system*    fs,
                           rtems_rfs_buffer_handle*  buffer,
                           size_t                    size,
                           rtems_rfs_buffer_block    block);

/**
 * Close a bitmap.
 *
 * @param[in] control is the bit map control.
 *
 * @retval 0 Successful operation.
 * @retval error_code An error occurred.
 */
int rtems_rfs_bitmap_close (rtems_rfs_bitmap_control* control);

#endif