Skip to content

Commit 345c667

Browse files
committed
Changed allocator structure: split iteration and lookup arrays for thread safety
1 parent 0aaaf0d commit 345c667

1 file changed

Lines changed: 35 additions & 18 deletions

File tree

src/Box2D.NET/B2ArenaAllocator.cs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: MIT
44

55
using System;
6+
using System.Collections.Generic;
67

78
namespace Box2D.NET
89
{
@@ -11,53 +12,69 @@ public class B2ArenaAllocator
1112
private readonly object _lock;
1213

1314
private int _capacity;
15+
private IB2ArenaAllocatable[] _lookup;
1416
private IB2ArenaAllocatable[] _allocators;
15-
private int _allocatorCount;
1617

17-
public int Count => _allocatorCount;
18+
public int Count => _allocators.Length;
1819

1920
public B2ArenaAllocator(int capacity)
2021
{
2122
_lock = new object();
2223
_capacity = capacity;
24+
_lookup = Array.Empty<IB2ArenaAllocatable>();
2325
_allocators = Array.Empty<IB2ArenaAllocatable>();
24-
_allocatorCount = 0;
2526
}
2627

2728
public B2ArenaAllocatorTyped<T> GetOrCreateFor<T>() where T : new()
2829
{
30+
// 1 2 가 동시에 들어 왔을 경우, 어떻게 밑에까지 맞출것인가?
2931
var index = B2ArenaAllocatorIndexer.Index<T>();
30-
if (_allocators.Length <= index || null == _allocators[index])
32+
if (_lookup.Length <= index || null == _lookup[index])
3133
{
3234
lock (_lock)
3335
{
3436
// grow
35-
if (_allocators.Length <= index)
37+
if (_lookup.Length <= index)
3638
{
37-
IB2ArenaAllocatable[] temp = new IB2ArenaAllocatable[index + 16];
38-
if (0 < _allocators.Length)
39-
{
40-
Array.Copy(_allocators, temp, _allocators.Length);
41-
}
42-
43-
_allocators = temp;
39+
_lookup = Resize(_lookup, index + 16);
4440
}
45-
41+
4642
// new
47-
if (null == _allocators[index])
43+
if (null == _lookup[index])
4844
{
49-
_allocators[index] = B2ArenaAllocators.b2CreateArenaAllocator<T>(_capacity);
50-
_allocatorCount++;
45+
var newAllocator = B2ArenaAllocators.b2CreateArenaAllocator<T>(_capacity);
46+
_lookup[index] = newAllocator;
47+
48+
//
49+
var tempAllocators = Resize(_allocators, _allocators.Length + 1);
50+
tempAllocators[_allocators.Length] = newAllocator;
51+
_allocators = tempAllocators;
5152
}
5253
}
5354
}
5455

55-
return _allocators[index] as B2ArenaAllocatorTyped<T>;
56+
return _lookup[index] as B2ArenaAllocatorTyped<T>;
57+
}
58+
59+
private static IB2ArenaAllocatable[] Resize(IB2ArenaAllocatable[] source, int count)
60+
{
61+
IB2ArenaAllocatable[] temp = source;
62+
if (source.Length < count)
63+
{
64+
temp = new IB2ArenaAllocatable[count];
65+
}
66+
67+
if (0 < source.Length)
68+
{
69+
Array.Copy(source, temp, source.Length);
70+
}
71+
72+
return temp;
5673
}
5774

5875
public Span<IB2ArenaAllocatable> AsSpan()
5976
{
60-
return new Span<IB2ArenaAllocatable>(_allocators, 0, _allocatorCount);
77+
return new Span<IB2ArenaAllocatable>(_allocators);
6178
}
6279
}
6380
}

0 commit comments

Comments
 (0)