Refactor JobExecutionContext, add scheduler state support

- Refactored JobExecutionContext to use init-only properties and added State and SelfHandle for richer context.
- Updated JobInfo field layout for clarity and memory alignment.
- JobScheduler now accepts and exposes an optional state object, passed to each job context.
- Improved memory management by using _freeList for allocations and disposal.
- WorkerThread and benchmarks updated to use new JobExecutionContext pattern.
- Bumped version to 1.6.1 and performed minor code cleanup.
This commit is contained in:
2026-04-17 19:49:42 +09:00
parent ebee3bb7fb
commit d5616daa05
8 changed files with 164 additions and 32 deletions

View File

@@ -1,21 +1,136 @@
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
//BenchmarkRunner.Run<SPMDBenchmark>();
//AllocationManager.Initialize(AllocationManagerInitOpts.Default);
//var set = new UnsafeBitSet(100, AllocationHandle.Persistent, AllocationOption.Clear);
//set.SetBit(0);
//Console.WriteLine(set.NextSetBit(0));
AllocationManager.Initialize(AllocationManagerInitOpts.Default);
var set = new UnsafeBitSet(100, AllocationHandle.Persistent, AllocationOption.Clear);
set.SetBit(0);
Console.WriteLine(set.NextSetBit(0));
//set.Dispose();
//AllocationManager.Dispose();
set.Dispose();
AllocationManager.Dispose();
var span = Span<int>.Empty;
unsafe
{
fixed (int* ptr = span)
{
Console.WriteLine((IntPtr)ptr);
}
}
//unsafe
//{
// var testC = new TestC();
// testC.BindToVtables();
// testC.MyValue = 42;
// // 1. Casting to IB (Direct cast, offset 0)
// var pB = (IB.Interface*)&testC;
// pB->MethodA();
// pB->MethodB();
// // 2. Casting to IC (Pointer adjustment needed!)
// // We must offset the pointer by the size of one void* so it points to lpVtbl_IC
// var pC = (IC.Interface*)((byte*)&testC + sizeof(void*));
// pC->MethodC();
//}
//public interface IA
//{
// [StructLayout(LayoutKind.Sequential)]
// unsafe struct Interface
// {
// public void** lpVtbl;
// public void MethodA() => ((delegate*<Interface*, void>)lpVtbl[0])((Interface*)Unsafe.AsPointer(ref this));
// }
//}
//public interface IB : IA
//{
// [StructLayout(LayoutKind.Sequential)]
// new unsafe struct Interface
// {
// public void** lpVtbl;
// // IA Methods
// public void MethodA() => ((delegate*<Interface*, void>)lpVtbl[0])((Interface*)Unsafe.AsPointer(ref this));
// // IB Methods
// public void MethodB() => ((delegate*<Interface*, void>)lpVtbl[1])((Interface*)Unsafe.AsPointer(ref this));
// }
//}
//public interface IC
//{
// [StructLayout(LayoutKind.Sequential)]
// unsafe struct Interface
// {
// public void** lpVtbl;
// public void MethodC() => ((delegate*<Interface*, void>)lpVtbl[0])((Interface*)Unsafe.AsPointer(ref this));
// }
//}
//[StructLayout(LayoutKind.Sequential)]
//public unsafe partial struct TestC
//{
// // Offset 0: Primary VTable (Covers IB and IA)
// public void** lpVtbl_IB;
// // Offset 8 (on 64-bit): Secondary VTable (Covers IC)
// public void** lpVtbl_IC;
// // Offset 16: Fields
// public int MyValue;
//}
//public unsafe partial struct TestC
//{
// public struct Vtbl_IB
// {
// public delegate*<IB.Interface*, void> MethodA;
// public delegate*<IB.Interface*, void> MethodB;
// }
// public struct Vtbl_IC
// {
// public delegate*<IC.Interface*, void> MethodC;
// }
// [FixedAddressValueType]
// public static readonly Vtbl_IB Table_IB = new Vtbl_IB
// {
// MethodA = &Native_MethodA,
// MethodB = &Native_MethodB
// };
// [FixedAddressValueType]
// public static readonly Vtbl_IC Table_IC = new Vtbl_IC
// {
// MethodC = &Native_MethodC
// };
// public void BindToVtables()
// {
// fixed (Vtbl_IB* pIB = &Table_IB)
// lpVtbl_IB = (void**)pIB;
// fixed (Vtbl_IC* pIC = &Table_IC)
// lpVtbl_IC = (void**)pIC;
// }
// // --- IB & IA Implementations ---
// public static void Native_MethodA(IB.Interface* self)
// {
// // For IB/IA, no adjustment is needed because lpVtbl_IB is at offset 0
// var pThis = (TestC*)self;
// Console.WriteLine($"MethodA called. MyValue: {pThis->MyValue}");
// }
// public static void Native_MethodB(IB.Interface* self)
// {
// var pThis = (TestC*)self;
// Console.WriteLine($"MethodB called. MyValue: {pThis->MyValue}");
// }
// // --- IC Implementations ---
// public static void Native_MethodC(IC.Interface* self)
// {
// // WARNING: 'self' points to the lpVtbl_IC field, NOT the start of TestC!
// // We must shift the pointer backward by the size of lpVtbl_IB (sizeof(void*))
// // to reconstruct the original TestC pointer, otherwise we read garbage memory.
// var pThis = (TestC*)((byte*)self - sizeof(void*));
// Console.WriteLine($"MethodC called. MyValue: {pThis->MyValue}");
// }
//}