1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | // |
6 | |
7 | // -------------------------------------------------------------------------------- |
8 | // BitMask.h |
9 | // -------------------------------------------------------------------------------- |
10 | |
11 | // -------------------------------------------------------------------------------- |
12 | // BitMask is an arbitrarily large sized bitfield which has optimal storage |
13 | // for 32 bits or less. |
14 | // Storage is proportional to the highest index which is set. |
15 | // -------------------------------------------------------------------------------- |
16 | |
17 | |
18 | #include <clrtypes.h> |
19 | |
20 | #ifndef _BITMASK_H_ |
21 | #define _BITMASK_H_ |
22 | |
23 | class BitMask |
24 | { |
25 | public: |
26 | |
27 | BitMask(); |
28 | ~BitMask(); |
29 | |
30 | BOOL TestBit(int bit); |
31 | void SetBit(int bit); |
32 | void ClearBit(int bit); |
33 | |
34 | // returns true if any bit is set |
35 | BOOL TestAnyBit(); |
36 | |
37 | void ClearAllBits(); |
38 | |
39 | // Allocation exposed for ngen save/fixup |
40 | size_t GetAllocatedBlockOffset(); |
41 | void *GetAllocatedBlock(); |
42 | COUNT_T GetAllocatedBlockSize(); |
43 | |
44 | private: |
45 | |
46 | static const int BIT_SIZE_SHIFT = 5; |
47 | static const int BIT_SIZE = (1<<BIT_SIZE_SHIFT); |
48 | static const int BIT_SIZE_MASK = BIT_SIZE-1; |
49 | |
50 | static const COUNT_T MIN_ARRAY_ALLOCATION = 3; |
51 | |
52 | // The first bit is used to indicate whether we've got a flat mask or |
53 | // an array of mask elements |
54 | BOOL IsArray(); |
55 | |
56 | // Indexing computations |
57 | COUNT_T BitToIndex(int bit); |
58 | COUNT_T BitToShift(int bit); |
59 | |
60 | // Generic mask array access. Works for either case (array or non-array). |
61 | COUNT_T *GetMaskArray(); |
62 | COUNT_T GetMaskArraySize(); |
63 | |
64 | // Need more bits... |
65 | void GrowArray(COUNT_T newSize); |
66 | |
67 | union |
68 | { |
69 | COUNT_T m_mask; |
70 | COUNT_T *m_maskArray; // first array element is size of rest of array |
71 | }; |
72 | }; |
73 | |
74 | // provides a wrapper around the BitMask class providing synchronized reads/writes safe for multithreaded access. |
75 | // I've only added the public methods that were required by Module which needs a thread-safe BitMask. add others as required. |
76 | class SynchronizedBitMask |
77 | { |
78 | public: |
79 | // Allow Module access so we can use Offsetof on this class's private members during native image creation (determinism) |
80 | friend class Module; |
81 | SynchronizedBitMask(); |
82 | ~SynchronizedBitMask() {} |
83 | |
84 | BOOL TestBit(int bit); |
85 | void SetBit(int bit); |
86 | void ClearBit(int bit); |
87 | |
88 | BOOL TestAnyBit(); |
89 | |
90 | void ClearAllBits(); |
91 | |
92 | private: |
93 | |
94 | BitMask m_bitMask; |
95 | |
96 | // note that this lock (at present) doesn't support promotion from reader->writer so be very careful |
97 | // when taking this lock else you might deadlock your own thread! |
98 | SimpleRWLock m_bitMaskLock; |
99 | }; |
100 | |
101 | #include <bitmask.inl> |
102 | |
103 | #endif // _BITMASK_H_ |
104 | |