-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathThreadSafeBitSet
More file actions
103 lines (85 loc) · 2.99 KB
/
ThreadSafeBitSet
File metadata and controls
103 lines (85 loc) · 2.99 KB
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
using System.Runtime.CompilerServices;
using System.Threading;
using Unity.Assertions;
using Unity.Burst;
using Unity.Collections;
namespace NSS.Data
{
public static class ThreadSafeBit
{
/// <summary>
/// check if the nth bit is set
/// </summary>
/// <param name="temp">some memory</param>
/// <param name="index">zero based index in bits</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[BurstCompile]
unsafe public static bool IsSet(byte data, byte index)
{
byte mask = (byte)(1 << (byte)index);
return (data & mask) == mask;
}
/// <summary>
/// check if a bit is set
/// </summary>
/// <param name="data"></param>
/// <param name="index">zero based bit index</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[BurstCompile]
unsafe public static bool IsSet(uint data, byte index)
{
uint mask = (uint)(1 << index);
return (data & mask) == mask;
}
/// <summary>
/// threadsafe set-bit
/// </summary>
/// <param name="bit"></param>
/// <param name="bitmap"></param>
[BurstCompatible]
unsafe static public void SetBitSafe(int bit_index, int* bitmap)
{
int index = bit_index >> 5;
int bit = 1 << (bit_index & 31);
int i = 0;
do
{
int current = bitmap[index];
// check if set
if ((current & bit) == bit) return;
int next = current | bit;
int value = Interlocked.CompareExchange(ref bitmap[index], next, current);
if (value == current)
{
// value set, it didnt change meanwhile
return;
}
// value was changed while trying to set it, restart procedure
Assert.IsTrue(i++ < 100);
}
while (true);
}
/// <summary>
/// set nth bit of memory to value
/// </summary>
/// <param name="temp">some memory</param>
/// <param name="index">index in bits</param>
/// <param name="value"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[BurstCompile]
unsafe public static void SetBitUnsafe(ref byte data, byte index, bool value)
{
byte mask = (byte)(1 << (byte)index);
data = value ? (byte)(data | mask) : (byte)(data & ~mask);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[BurstCompile]
unsafe public static void SetBitUnsafe(ref uint data, byte index, bool value)
{
uint mask = (uint)(1 << index);
data = value ? (uint)(data | mask) : (uint)(data & ~mask);
}
}
}