diff --git a/Misaki.HighPerformance.Image/Misaki.HighPerformance.Image.csproj b/Misaki.HighPerformance.Image/Misaki.HighPerformance.Image.csproj
index 8c3570d..9bcdaa0 100644
--- a/Misaki.HighPerformance.Image/Misaki.HighPerformance.Image.csproj
+++ b/Misaki.HighPerformance.Image/Misaki.HighPerformance.Image.csproj
@@ -3,7 +3,7 @@
Public Domain
true
- net9.0
+ net10.0
Misaki
1.0.0
$(AssemblyVersion)
diff --git a/Misaki.HighPerformance.Jobs/JobScheduler.cs b/Misaki.HighPerformance.Jobs/JobScheduler.cs
index 9464071..3e8ae66 100644
--- a/Misaki.HighPerformance.Jobs/JobScheduler.cs
+++ b/Misaki.HighPerformance.Jobs/JobScheduler.cs
@@ -30,10 +30,10 @@ public sealed unsafe class JobScheduler : IDisposable
private bool _disposed = false;
- public int WorkerCount => _workerThreads.Length;
-
internal bool IsCancellationRequested => _cts.IsCancellationRequested;
+ public int WorkerCount => _workerThreads.Length;
+
///
/// Initializes a new instance of the class with the specified number of worker threads.
///
@@ -481,7 +481,7 @@ public sealed unsafe class JobScheduler : IDisposable
var completedCount = 0;
foreach (var handle in handles)
{
- if (!_jobInfoPool.Contain(handle._id, handle._generation))
+ if (!_jobInfoPool.Contains(handle._id, handle._generation))
{
completedCount++;
}
@@ -514,7 +514,7 @@ public sealed unsafe class JobScheduler : IDisposable
{
foreach (var handle in handles)
{
- if (!_jobInfoPool.Contain(handle._id, handle._generation))
+ if (!_jobInfoPool.Contains(handle._id, handle._generation))
{
return handle;
}
@@ -542,6 +542,7 @@ public sealed unsafe class JobScheduler : IDisposable
_jobQueue.Clear();
_jobDataAllocator.Dispose();
+ _workSignal.Dispose();
_cts.Dispose();
_disposed = true;
diff --git a/Misaki.HighPerformance.Jobs/Misaki.HighPerformance.Jobs.csproj b/Misaki.HighPerformance.Jobs/Misaki.HighPerformance.Jobs.csproj
index a052e6f..908b0f1 100644
--- a/Misaki.HighPerformance.Jobs/Misaki.HighPerformance.Jobs.csproj
+++ b/Misaki.HighPerformance.Jobs/Misaki.HighPerformance.Jobs.csproj
@@ -2,7 +2,7 @@
Library
- net9.0
+ net10.0
enable
enable
True
@@ -14,8 +14,17 @@
https://git.personalnas.com/Misaki/Misaki.HighPerformance.git
+
+ True
+
+
+
+ True
+
+
+
diff --git a/Misaki.HighPerformance.LowLevel/Buffer/AllocationManager.cs b/Misaki.HighPerformance.LowLevel/Buffer/AllocationManager.cs
index f0ff442..ed142a8 100644
--- a/Misaki.HighPerformance.LowLevel/Buffer/AllocationManager.cs
+++ b/Misaki.HighPerformance.LowLevel/Buffer/AllocationManager.cs
@@ -8,7 +8,7 @@ namespace Misaki.HighPerformance.LowLevel.Buffer;
///
/// Holds information about a memory allocation.
///
-public readonly unsafe struct AllocationInfo
+public readonly struct AllocationInfo
{
///
/// Get the size of the allocation in bytes.
@@ -69,7 +69,7 @@ public static unsafe class AllocationManager
{
var selfPtr = (ArenaAllocator*)instance;
var newPtr = selfPtr->_arena.Allocate(newSize, alignment, allocationOption);
- MemCpy(newPtr, ptr, newSize);
+ MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
if (allocationOption.HasFlag(AllocationOption.Clear))
{
@@ -149,7 +149,7 @@ public static unsafe class AllocationManager
private static void* Reallocate(void* instance, void* ptr, nuint oldSize, nuint newSize, nuint alignment, AllocationOption allocationOption)
{
var newPtr = s_stack.Allocate(newSize, alignment, AllocationOption.None);
- MemCpy(newPtr, ptr, newSize);
+ MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
if (allocationOption.HasFlag(AllocationOption.Clear))
{
@@ -174,7 +174,7 @@ public static unsafe class AllocationManager
}
}
- private const uint _DEFAULT_MEMORY_POOL_SIZE = 512 * 1024;
+ private const uint _DEFAULT_MEMORY_POOL_SIZE = 512 * 1024; // 512 KB
private static readonly ArenaAllocator* s_pArenaAllocator;
private static readonly HeapAllocator* s_pHeapAllocator;
@@ -438,12 +438,10 @@ public static unsafe class AllocationManager
}
var newPtr = AlignedRealloc(ptr, newSize, alignment);
- if (allocationOption.HasFlag(AllocationOption.Clear))
+ if (allocationOption.HasFlag(AllocationOption.Clear)
+ && newSize > oldSize)
{
- if (newSize > oldSize)
- {
- MemClear((byte*)newPtr + oldSize, newSize - oldSize);
- }
+ MemClear((byte*)newPtr + oldSize, newSize - oldSize);
}
return newPtr;
@@ -535,7 +533,7 @@ public static unsafe class AllocationManager
if (unfreeBytes > 0u)
{
- throw new MemoryLeakException(snapshot);
+ throw new MemoryLeakException(CollectionsMarshal.AsSpan(snapshot));
}
}
else if (s_activeHeapAllocations != 0)
diff --git a/Misaki.HighPerformance.LowLevel/Collections/ReadOnlyUnsafeCollection.cs b/Misaki.HighPerformance.LowLevel/Collections/ReadOnlyUnsafeCollection.cs
index 9aa9aff..5c1c0ad 100644
--- a/Misaki.HighPerformance.LowLevel/Collections/ReadOnlyUnsafeCollection.cs
+++ b/Misaki.HighPerformance.LowLevel/Collections/ReadOnlyUnsafeCollection.cs
@@ -1,4 +1,4 @@
-using Misaki.HighPerformance.LowLevel.Utilities;
+using Misaki.HighPerformance.LowLevel.Utilities;
using System.Collections;
using System.Runtime.CompilerServices;
@@ -20,36 +20,21 @@ public readonly unsafe struct ReadOnlyUnsafeCollection : IEnumerable
{
private readonly ReadOnlyUnsafeCollection _collection;
private int _index;
- private T _value;
-
- public readonly T Current
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => _value;
- }
+ public readonly T Current => _collection[_index];
readonly object IEnumerator.Current => Current;
public Enumerator(ref readonly ReadOnlyUnsafeCollection array)
{
_collection = array;
_index = -1;
- _value = default;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
_index++;
-
- if (_index < _collection.Count)
- {
- _value = UnsafeUtility.ReadArrayElement(_collection._buffer, _index);
- return true;
- }
-
- _value = default;
- return false;
+ return _index < _collection.Count;
}
public void Reset()
@@ -79,7 +64,8 @@ public readonly unsafe struct ReadOnlyUnsafeCollection : IEnumerable
get => UnsafeUtility.ReadArrayElement(_buffer, index);
}
- public IEnumerator GetEnumerator() => new Enumerator(in this);
+ public Enumerator GetEnumerator() => new Enumerator(in this);
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public ReadOnlyUnsafeCollection(T* buffer, int count)
diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs
index 9b3f2ee..1230893 100644
--- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs
+++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs
@@ -14,47 +14,38 @@ public unsafe struct UnsafeBitSet : IDisposable
private const int _MASK = (1 << 5) - 1; // 0x1F, the mask to get the bit index inside a uint
private static readonly int s_padding = Vector.Count; // The padding used for vectorization, the amount of uints required for being vectorized basically
- ///
- /// Determines the required length of an to hold the passed id or bit.
- ///
- /// The id or bit.
- /// A size of required s for the bitset.
- public static int RequiredLength(int id)
- {
- return (id >> 5) + int.Sign(id & _BIT_SIZE);
- }
-
- ///
- /// Rounds the given length to the next padding size.
- ///
- /// The length to round.
- /// The rounded length.
- public static int RoundToPadding(int length)
- {
- return (length + s_padding - 1) / s_padding * s_padding;
- }
-
- ///
- /// The bits from the bitset.
- ///
private UnsafeArray _bits;
+ private int _highestBit;
+ private int _max;
+
+ ///
+ /// The highest uint index in use inside the -array.
+ ///
+ public readonly int HighestIndex => _max;
///
/// The highest bit set.
///
- private int _highestBit;
+ public readonly int HighestBit => _highestBit;
///
- /// The maximum -index current in use.
+ /// Returns the count of the bitset, how many uints it consists of.
///
- private int _max;
+ public readonly int Count => _bits.Count;
+
+ ///
+ /// Gets the total number of bits represented by the current instance.
+ ///
+ public readonly int BitCount => _bits.Count << _INDEX_SIZE;
+
+ public readonly bool IsCreated => _bits.IsCreated;
///
/// Initializes a new instance of the class.
///
public UnsafeBitSet()
{
- _bits = new UnsafeArray(s_padding, Allocator.Persistent, AllocationOption.None);
+ _bits = new UnsafeArray(0, Allocator.Invalid, AllocationOption.None);
}
///
@@ -94,33 +85,19 @@ public unsafe struct UnsafeBitSet : IDisposable
}
}
- ///
- /// The highest uint index in use inside the -array.
- ///
- public int HighestIndex
+ private static int RoundToPadding(int length)
{
- get => _max;
+ return (length + s_padding - 1) / s_padding * s_padding;
}
///
- /// The highest bit set.
+ /// Determines the required length of an to hold the passed id or bit.
///
- public int HighestBit
+ /// The id or bit.
+ /// A size of required s for the bitset.
+ public static int RequiredLength(int id)
{
- get => _highestBit;
- }
-
- ///
- /// Returns the length of the bitset, how many ints it consists of.
- ///
- public int Length
- {
- get => _bits.Count;
- }
-
- public bool IsCreated
- {
- get => _bits.IsCreated;
+ return (id >> _INDEX_SIZE) + int.Sign(id & _BIT_SIZE);
}
///
@@ -128,7 +105,7 @@ public unsafe struct UnsafeBitSet : IDisposable
///
/// The index.
/// True if it is, otherwise false
- public bool IsSet(int index)
+ public readonly bool IsSet(int index)
{
var b = index >> _INDEX_SIZE;
if (b >= _bits.Count)
@@ -149,9 +126,10 @@ public unsafe struct UnsafeBitSet : IDisposable
var b = index >> _INDEX_SIZE;
if (b >= _bits.Count)
{
- _bits.Resize(RoundToPadding(b));
+ _bits.Resize(index);
}
+
// Track highest set bit
_highestBit = Math.Max(_highestBit, index);
_max = _highestBit / (_BIT_SIZE + 1) + 1;
@@ -228,9 +206,12 @@ public unsafe struct UnsafeBitSet : IDisposable
public void Resize(int minimalLength, AllocationOption option = AllocationOption.None)
{
+ var oldSize = _bits.Count;
var uints = (minimalLength >> _INDEX_SIZE) + int.Sign(minimalLength & _BIT_SIZE);
var length = RoundToPadding(uints);
+
_bits.Resize(length, option);
+ _bits.AsSpan()[oldSize..].Clear();
}
///
@@ -238,10 +219,9 @@ public unsafe struct UnsafeBitSet : IDisposable
///
/// The other .
/// True if they match, false if not.
- [SkipLocalsInit]
- public bool All(UnsafeBitSet other)
+ public readonly bool All(UnsafeBitSet other)
{
- var min = Math.Min(Math.Min(Length, other.Length), _max);
+ var min = Math.Min(Math.Min(Count, other.Count), _max);
if (!Vector.IsHardwareAccelerated || min < s_padding)
{
var bits = _bits.AsSpan();
@@ -300,9 +280,9 @@ public unsafe struct UnsafeBitSet : IDisposable
///
/// The other .
/// True if they match, false if not.
- public bool Any(UnsafeBitSet other)
+ public readonly bool Any(UnsafeBitSet other)
{
- var min = Math.Min(Math.Min(Length, other.Length), _max);
+ var min = Math.Min(Math.Min(Count, other.Count), _max);
if (!Vector.IsHardwareAccelerated || min < s_padding)
{
var bits = _bits.AsSpan();
@@ -361,9 +341,9 @@ public unsafe struct UnsafeBitSet : IDisposable
///
/// The other .
/// True if none match, false if not.
- public bool None(UnsafeBitSet other)
+ public readonly bool None(UnsafeBitSet other)
{
- var min = Math.Min(Math.Min(Length, other.Length), _max);
+ var min = Math.Min(Math.Min(Count, other.Count), _max);
if (!Vector.IsHardwareAccelerated || min < s_padding)
{
var bits = _bits.AsSpan();
@@ -403,9 +383,9 @@ public unsafe struct UnsafeBitSet : IDisposable
///
/// The other .
/// True if they match, false if not.
- public bool Exclusive(UnsafeBitSet other)
+ public readonly bool Exclusive(UnsafeBitSet other)
{
- var min = Math.Min(Math.Min(Length, other.Length), _max);
+ var min = Math.Min(Math.Min(Count, other.Count), _max);
if (!Vector.IsHardwareAccelerated || min < s_padding)
{
@@ -460,152 +440,85 @@ public unsafe struct UnsafeBitSet : IDisposable
return true;
}
- public unsafe void AndOperation(UnsafeBitSet other)
+ public void And(UnsafeBitSet other)
{
- var min = Math.Min(Length, other.Length);
- var temp = stackalloc uint[min];
-
- if (!Vector.IsHardwareAccelerated || min < s_padding)
+ if (Count != other.Count)
{
- for (var i = 0; i < min; i++)
+ throw new ArgumentException("Bitsets must be of the same length for AND operation.");
+ }
+
+ if (!Vector.IsHardwareAccelerated || Count < s_padding)
+ {
+ for (var i = 0; i < Count; i++)
{
- temp[i] = _bits[i] & other._bits[i];
+ _bits[i] &= other._bits[i];
}
}
else
{
- for (var i = 0; i < min; i += s_padding)
+ for (var i = 0; i < Count; i += s_padding)
{
var vectorLeft = new Vector(_bits.AsSpan()[i..]);
var vectorRight = new Vector(other._bits.AsSpan()[i..]);
var resultVector = Vector.BitwiseAnd(vectorLeft, vectorRight);
- resultVector.CopyTo(new Span(temp + i, s_padding));
+
+ resultVector.CopyTo(_bits.AsSpan(i, s_padding));
}
}
-
- _bits.CopyFrom(new Span(temp, min));
}
- public unsafe void OrOperation(UnsafeBitSet other)
+ public void Or(UnsafeBitSet other)
{
- var min = Math.Min(Length, other.Length);
- var temp = stackalloc uint[min];
-
- if (!Vector.IsHardwareAccelerated || min < s_padding)
+ if (Count != other.Count)
{
- for (var i = 0; i < min; i++)
+ throw new ArgumentException("Bitsets must be of the same length for AND operation.");
+ }
+
+ if (!Vector.IsHardwareAccelerated || Count < s_padding)
+ {
+ for (var i = 0; i < Count; i++)
{
- temp[i] = _bits[i] | other._bits[i];
+ _bits[i] |= other._bits[i];
}
}
else
{
- for (var i = 0; i < min; i += s_padding)
+ for (var i = 0; i < Count; i += s_padding)
{
var vectorLeft = new Vector(_bits.AsSpan()[i..]);
var vectorRight = new Vector(other._bits.AsSpan()[i..]);
var resultVector = Vector.BitwiseOr(vectorLeft, vectorRight);
- resultVector.CopyTo(new Span(temp + i, s_padding));
+
+ resultVector.CopyTo(_bits.AsSpan(i, s_padding));
}
}
-
- _bits.CopyFrom(new Span(temp, min));
}
- public unsafe void XorOperation(UnsafeBitSet other)
+ public void Xor(UnsafeBitSet other)
{
- var min = Math.Min(Length, other.Length);
- var temp = stackalloc uint[min];
-
- if (!Vector.IsHardwareAccelerated || min < s_padding)
+ if (Count != other.Count)
{
- for (var i = 0; i < min; i++)
+ throw new ArgumentException("Bitsets must be of the same length for AND operation.");
+ }
+
+ if (!Vector.IsHardwareAccelerated || Count < s_padding)
+ {
+ for (var i = 0; i < Count; i++)
{
- temp[i] = _bits[i] ^ other._bits[i];
+ _bits[i] ^= other._bits[i];
}
}
else
{
- for (var i = 0; i < min; i += s_padding)
+ for (var i = 0; i < Count; i += s_padding)
{
var vectorLeft = new Vector(_bits.AsSpan()[i..]);
var vectorRight = new Vector(other._bits.AsSpan()[i..]);
var resultVector = Vector.Xor(vectorLeft, vectorRight);
- resultVector.CopyTo(new Span(temp + i, s_padding));
- }
- }
- _bits.CopyFrom(new Span(temp, min));
- }
-
- public static UnsafeBitSet operator &(UnsafeBitSet left, UnsafeBitSet right)
- {
- var min = Math.Min(left.Length, right.Length);
- var result = new UnsafeBitSet(min, Allocator.Persistent);
- if (!Vector.IsHardwareAccelerated || min < s_padding)
- {
- for (var i = 0; i < min; i++)
- {
- result._bits[i] = left._bits[i] & right._bits[i];
+ resultVector.CopyTo(_bits.AsSpan(i, s_padding));
}
}
- else
- {
- for (var i = 0; i < min; i += s_padding)
- {
- var vectorLeft = new Vector(left._bits.AsSpan()[i..]);
- var vectorRight = new Vector(right._bits.AsSpan()[i..]);
- var resultVector = Vector.BitwiseAnd(vectorLeft, vectorRight);
- resultVector.CopyTo(result._bits.AsSpan(i, s_padding));
- }
- }
- return result;
- }
-
- public static UnsafeBitSet operator |(UnsafeBitSet left, UnsafeBitSet right)
- {
- var min = Math.Min(left.Length, right.Length);
- var result = new UnsafeBitSet(min, Allocator.Persistent);
- if (!Vector.IsHardwareAccelerated || min < s_padding)
- {
- for (var i = 0; i < min; i++)
- {
- result._bits[i] = left._bits[i] | right._bits[i];
- }
- }
- else
- {
- for (var i = 0; i < min; i += s_padding)
- {
- var vectorLeft = new Vector(left._bits.AsSpan()[i..]);
- var vectorRight = new Vector(right._bits.AsSpan()[i..]);
- var resultVector = Vector.BitwiseOr(vectorLeft, vectorRight);
- resultVector.CopyTo(result._bits.AsSpan(i, s_padding));
- }
- }
- return result;
- }
-
- public static UnsafeBitSet operator ~(UnsafeBitSet bitSet)
- {
- if (!Vector.IsHardwareAccelerated || bitSet.Length < s_padding)
- {
- for (var i = 0; i < bitSet.Length; i++)
- {
- bitSet._bits[i] = ~bitSet._bits[i];
- }
- }
- else
- {
- for (var i = 0; i < bitSet.Length; i += s_padding)
- {
- var vector = new Vector(bitSet._bits.AsSpan()[i..]);
- var resultVector = ~vector;
- resultVector.CopyTo(bitSet._bits.AsSpan(i, s_padding));
- }
- }
-
- return bitSet;
}
///
@@ -624,10 +537,10 @@ public unsafe struct UnsafeBitSet : IDisposable
/// The to copy into.
/// If true, it will zero the unused space from the .
/// The .
- public Span AsSpan(Span span, bool zero = true)
+ public readonly Span AsSpan(Span span, bool zero = true)
{
// Copy everything thats possible from one to another
- var length = Math.Min(Length, span.Length);
+ var length = Math.Min(Count, span.Length);
for (var index = 0; index < length; index++)
{
span[index] = _bits[index];
@@ -639,10 +552,10 @@ public unsafe struct UnsafeBitSet : IDisposable
span[index] = 0;
}
- return span[..Length];
+ return span[..Count];
}
- public override string ToString()
+ public readonly override string ToString()
{
// Convert uint to binary form for pretty printing
var binaryBuilder = new StringBuilder();
@@ -652,7 +565,7 @@ public unsafe struct UnsafeBitSet : IDisposable
}
binaryBuilder.Length--;
- return $"{nameof(_bits)}: {binaryBuilder}, {nameof(Length)}: {Length}";
+ return $"{nameof(_bits)}: {binaryBuilder}, {nameof(Count)}: {Count}";
}
public void Dispose()
diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs
index 165e283..da64ba7 100644
--- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs
+++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs
@@ -57,7 +57,7 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
public readonly int Count => _count;
public readonly int Capacity => _capacity;
- public readonly bool IsCreated => _data.IsCreated && _freeSlots.IsCreated;
+ public readonly bool IsCreated => _data.IsCreated && _generations.IsCreated && _freeSlots.IsCreated && _validBits.IsCreated;
public Enumerator GetEnumerator() => new((UnsafeSlotMap*)UnsafeUtility.AddressOf(ref this));
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
@@ -239,7 +239,7 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
throw new ArgumentOutOfRangeException(nameof(slotIndex), "Slot index is out of range.");
}
- if (!_validBits.IsSet(slotIndex)|| _generations[slotIndex] != generation)
+ if (!_validBits.IsSet(slotIndex) || _generations[slotIndex] != generation)
{
throw new InvalidOperationException($"Slot {slotIndex} is not occupied.");
}
@@ -294,7 +294,7 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
_count = 0;
}
- public readonly unsafe void* GetUnsafePtr()
+ public readonly void* GetUnsafePtr()
{
return _data.GetUnsafePtr();
}
@@ -303,6 +303,7 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection
{
_data.Dispose();
_freeSlots.Dispose();
+ _validBits.Dispose();
_count = 0;
_capacity = 0;
diff --git a/Misaki.HighPerformance.LowLevel/MemoryLeakException.cs b/Misaki.HighPerformance.LowLevel/MemoryLeakException.cs
index 69a002d..a07ec28 100644
--- a/Misaki.HighPerformance.LowLevel/MemoryLeakException.cs
+++ b/Misaki.HighPerformance.LowLevel/MemoryLeakException.cs
@@ -10,12 +10,21 @@ namespace Misaki.HighPerformance.LowLevel;
/// An array of AllocationInfo containing details about the memory leaks.
public class MemoryLeakException : Exception
{
- private readonly IEnumerable? _infos;
- private readonly string _message = string.Empty;
+ private readonly string _message;
- public MemoryLeakException(IEnumerable infos)
+ public override string Message => _message;
+
+ public MemoryLeakException(ReadOnlySpan infos)
{
- _infos = infos;
+ var stringBuilder = new StringBuilder();
+ stringBuilder.AppendLine($"Found {infos.Length} memory lakes!");
+
+ foreach (var info in infos)
+ {
+ stringBuilder.AppendLine(GetMessage(info.StackTrace));
+ }
+
+ _message = stringBuilder.ToString();
}
public MemoryLeakException(string message)
@@ -44,25 +53,4 @@ public class MemoryLeakException : Exception
return stringBuilder.ToString();
}
-
- public override string Message
- {
- get
- {
- if (_infos == null)
- {
- return _message;
- }
-
- var stringBuilder = new StringBuilder();
- stringBuilder.AppendLine($"Found {_infos.Count()} memory lakes!");
-
- foreach (var info in _infos)
- {
- stringBuilder.AppendLine(GetMessage(info.StackTrace));
- }
-
- return stringBuilder.ToString();
- }
- }
}
\ No newline at end of file
diff --git a/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj b/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj
index d83aca1..7cf9f5f 100644
--- a/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj
+++ b/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
enable
enable
True
@@ -21,10 +21,6 @@
True
-
-
-
-
TextTemplatingFileGenerator
diff --git a/Misaki.HighPerformance.Mathematics.CodeGen/Generators/VectorGenerator.cs b/Misaki.HighPerformance.Mathematics.CodeGen/Generators/VectorGenerator.cs
index b429c16..91298df 100644
--- a/Misaki.HighPerformance.Mathematics.CodeGen/Generators/VectorGenerator.cs
+++ b/Misaki.HighPerformance.Mathematics.CodeGen/Generators/VectorGenerator.cs
@@ -422,7 +422,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
return new {typeName}({string.Join(", ", s_vectorComponents.Take(typeInfo.Row).Select(c => $"lhs + rhs.{c}"))});
}}
-#if false //NET10_0_OR_GREATER
+#if NET10_0_OR_GREATER
{INLINE_METHOD_ATTRIBUTE}
public void operator +=({typeName} other)
{{");
diff --git a/Misaki.HighPerformance.Mathematics/Misaki.HighPerformance.Mathematics.csproj b/Misaki.HighPerformance.Mathematics/Misaki.HighPerformance.Mathematics.csproj
index 13f0af6..8826c5a 100644
--- a/Misaki.HighPerformance.Mathematics/Misaki.HighPerformance.Mathematics.csproj
+++ b/Misaki.HighPerformance.Mathematics/Misaki.HighPerformance.Mathematics.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
enable
enable
True
@@ -13,6 +13,14 @@
https://git.personalnas.com/Misaki/Misaki.HighPerformance.git
+
+ True
+
+
+
+ True
+
+
diff --git a/Misaki.HighPerformance.Test/Benchmark/MathematicsBenchmark.cs b/Misaki.HighPerformance.Test/Benchmark/MathematicsBenchmark.cs
index 5d96feb..e730ed5 100644
--- a/Misaki.HighPerformance.Test/Benchmark/MathematicsBenchmark.cs
+++ b/Misaki.HighPerformance.Test/Benchmark/MathematicsBenchmark.cs
@@ -1,7 +1,6 @@
-using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Attributes;
using Misaki.HighPerformance.Mathematics;
using System.Numerics;
-using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace Misaki.HighPerformance.Test.Benchmark;
@@ -25,7 +24,7 @@ public unsafe class MathematicsBenchmark
public static f4 operator +(f4 a, f4 b)
{
var result = a._vec + b._vec;
- return Unsafe.As, f4>(ref result);
+ return new f4(result);
}
}
@@ -108,7 +107,7 @@ public unsafe class MathematicsBenchmark
}
[Benchmark]
- public unsafe Vector128 v128Add()
+ public Vector128 v128Add()
{
var a = Vector128.Create(1f, 2f, 3f, 4f);
var b = Vector128.Create(5f, 6f, 7f, 8f);
diff --git a/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj b/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj
index 2293916..38ec73f 100644
--- a/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj
+++ b/Misaki.HighPerformance.Test/Misaki.HighPerformance.Test.csproj
@@ -2,7 +2,7 @@
Exe
- net9.0
+ net10.0
enable
enable
True
diff --git a/Misaki.HighPerformance.Test/Program.cs b/Misaki.HighPerformance.Test/Program.cs
index 42157eb..629061a 100644
--- a/Misaki.HighPerformance.Test/Program.cs
+++ b/Misaki.HighPerformance.Test/Program.cs
@@ -20,7 +20,7 @@
//using Misaki.HighPerformance.Test.Benchmark;
-//BenchmarkDotNet.Running.BenchmarkRunner.Run();
+BenchmarkDotNet.Running.BenchmarkRunner.Run();
//using Misaki.HighPerformance.LowLevel.Buffer;
//using Misaki.HighPerformance.LowLevel.Collections;
@@ -40,17 +40,3 @@
// }
//}
-using Misaki.HighPerformance.LowLevel.Buffer;
-using Misaki.HighPerformance.LowLevel.Collections;
-
-//AllocationManager.EnableDebugLayer();
-//var array = new UnsafeArray(10, Allocator.Persistent);
-//var array2 = new UnsafeArray(10, Allocator.Persistent);
-//array.Dispose();
-//array2.Dispose();
-//AllocationManager.Dispose();
-
-using (AllocationManager.CreateStackScope())
-{
- var arr = new UnsafeArray(10, Allocator.Stack);
-}
\ No newline at end of file
diff --git a/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeBitSet.cs b/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeBitSet.cs
new file mode 100644
index 0000000..96053c9
--- /dev/null
+++ b/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeBitSet.cs
@@ -0,0 +1,78 @@
+using Misaki.HighPerformance.LowLevel.Buffer;
+using Misaki.HighPerformance.LowLevel.Collections;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+
+namespace Misaki.HighPerformance.Test.UnitTest.Collections;
+
+[TestClass]
+public class TestUnsafeBitSet
+{
+ private UnsafeBitSet _set1;
+ private UnsafeBitSet _set2;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ _set1 = new UnsafeBitSet(16, Allocator.Persistent, AllocationOption.Clear);
+ _set2 = new UnsafeBitSet(16, Allocator.Persistent, AllocationOption.Clear);
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ _set1.Dispose();
+ _set2.Dispose();
+ }
+
+ [TestMethod]
+ public void TestBitCount()
+ {
+ Assert.AreEqual(256, _set1.BitCount);
+ }
+
+ [TestMethod]
+ public void TestSetAndGet()
+ {
+ Assert.IsFalse(_set1.IsSet(0));
+ _set1.SetBit(0);
+ Assert.IsTrue(_set1.IsSet(0));
+ _set1.ClearBit(0);
+ Assert.IsFalse(_set1.IsSet(0));
+ }
+
+ [TestMethod]
+ public void TestClearAll()
+ {
+ for (int i = 0; i < _set1.BitCount; i++)
+ {
+ _set1.SetBit(i);
+ }
+
+ _set1.ClearAll();
+ for (int i = 0; i < _set1.BitCount; i++)
+ {
+ Assert.IsFalse(_set1.IsSet(i));
+ }
+ }
+
+ [TestMethod]
+ public void TestAndOperation()
+ {
+ _set1.SetBit(0);
+ _set1.SetBit(1);
+
+ _set2.SetBit(1);
+ _set2.SetBit(2);
+
+ _set1.And(_set2);
+
+ Assert.IsFalse(_set1.IsSet(0));
+ Assert.IsTrue(_set1.IsSet(1));
+ Assert.IsFalse(_set1.IsSet(2));
+ }
+}
\ No newline at end of file
diff --git a/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeSlotMap.cs b/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeSlotMap.cs
index 626c73e..eb7741b 100644
--- a/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeSlotMap.cs
+++ b/Misaki.HighPerformance.Test/UnitTest/Collections/TestUnsafeSlotMap.cs
@@ -11,7 +11,7 @@ public class TestUnsafeSlotMap
[TestInitialize]
public void Initialize()
{
- _slotMap = new UnsafeSlotMap(16, Allocator.Persistent, AllocationOption.Clear);
+ _slotMap = new UnsafeSlotMap(16, Allocator.Persistent);
}
[TestCleanup]
diff --git a/Misaki.HighPerformance/Collections/ConcureentSlotMap.cs b/Misaki.HighPerformance/Collections/ConcureentSlotMap.cs
index 8498e64..1a6f1b8 100644
--- a/Misaki.HighPerformance/Collections/ConcureentSlotMap.cs
+++ b/Misaki.HighPerformance/Collections/ConcureentSlotMap.cs
@@ -1,4 +1,4 @@
-using System.Collections;
+using System.Collections;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
@@ -207,7 +207,7 @@ public class ConcurrentSlotMap : IEnumerable
return false; // Another thread already removed it
}
- public bool Contain(int slotIndex, int generation)
+ public bool Contains(int slotIndex, int generation)
{
if (slotIndex < 0 || slotIndex >= Volatile.Read(ref _capacity))
{
diff --git a/Misaki.HighPerformance/Misaki.HighPerformance.csproj b/Misaki.HighPerformance/Misaki.HighPerformance.csproj
index cd3809e..966abd0 100644
--- a/Misaki.HighPerformance/Misaki.HighPerformance.csproj
+++ b/Misaki.HighPerformance/Misaki.HighPerformance.csproj
@@ -1,7 +1,7 @@
- net9.0
+ net10.0
enable
enable
True