using System.Runtime.InteropServices; namespace Misaki.HighPerformance.Jobs; /// /// Represents a job that performs a single unit of work. /// public interface IJob { /// /// Executes the job logic. /// /// The context of the job execution, providing access to thread-specific information and job scheduling capabilities. void Execute(ref readonly JobExecutionContext ctx); } /// /// Represents a job that performs the same operation for a set of items, executed in parallel. /// public interface IJobParallelFor { /// /// Executes the job for a single item at the given index. /// /// The index of the item to process. /// The context of the job execution, providing access to thread-specific information and job scheduling capabilities. void Execute(int loopIndex, ref readonly JobExecutionContext ctx); } /// /// Represents a job that performs the same operation for a set of items, executed in parallel. /// public interface IJobParallel { /// /// Executes an operation over a specified range, optionally associating the execution with a particular thread index. /// /// The zero-based index at which to begin the operation. /// The zero-based index at which to end the operation. /// The context of the job execution, providing access to thread-specific information and job scheduling capabilities. void Execute(int startIndex, int endIndex, ref readonly JobExecutionContext ctx); } /// /// Represents a custom job with user-defined execution and cleanup logic, allowing for more flexible job definitions beyond the standard interfaces. /// /// public interface ICustomJob { /// /// Executes the job logic, providing access to the job's own state, the job ranges for parallel execution, and the job execution context for thread-specific information and scheduling capabilities. /// /// The job instance to execute. /// The ranges of items to process. /// The context of the job execution. static abstract void Execute(ref TSelf job, ref JobRanges jobRanges, ref readonly JobExecutionContext ctx); /// /// Frees any resources associated with the job after execution, allowing for cleanup of unmanaged resources or other necessary finalization steps. /// /// The job instance to clean up. static abstract void Free(ref TSelf job); } internal unsafe struct CombinedDependenciesJob : IJob { public JobHandle* dependencies; public int dependencyCount; public readonly void Execute(ref readonly JobExecutionContext ctx) { var span = new Span(dependencies, dependencyCount); ctx.JobScheduler.WaitAll(span); NativeMemory.Free(dependencies); } } public static class IJobExtensions { /// /// Runs the job in the calling thread, blocking until the job is complete. /// /// The type of the job. /// The job to run. /// The job execution context. public static void Run(this T job, ref readonly JobExecutionContext ctx) where T : IJob { job.Execute(in ctx); } /// /// Runs the job by reference in the calling thread, blocking until the job is complete. /// /// The type of the job. /// The job to run. /// The job execution context. public static void RunRef(this ref T job, ref readonly JobExecutionContext ctx) where T : struct, IJob { job.Execute(in ctx); } } public static class IJobParallelForExtensions { /// /// Runs the job in the calling thread, blocking until the job is complete. /// /// The type of the job. /// The job to run. /// The total number of iterations. /// The job execution context. public static void Run(this T job, int totalIterations, ref readonly JobExecutionContext ctx) where T : IJobParallelFor { for (var i = 0; i < totalIterations; i++) { job.Execute(i, in ctx); } } /// /// Runs the job by reference in the calling thread, blocking until the job is complete. /// /// The type of the job. /// The job to run. /// The total number of iterations. /// The job execution context. public static void RunRef(this ref T job, int totalIterations, ref readonly JobExecutionContext ctx) where T : struct, IJobParallelFor { for (var i = 0; i < totalIterations; i++) { job.Execute(i, in ctx); } } } public static class IJobParallelExtensions { /// /// Runs the job in the calling thread, blocking until the job is complete. /// /// The type of the job. /// The job to run. /// The total number of iterations. /// The job execution context. public static void Run(this T job, int totalIterations, ref readonly JobExecutionContext ctx) where T : IJobParallel { job.Execute(0, totalIterations, in ctx); } /// /// Runs the job by reference in the calling thread, blocking until the job is complete. /// /// The type of the job. /// The job to run. /// The total number of iterations. /// The job execution context. public static void RunRef(this ref T job, int totalIterations, ref readonly JobExecutionContext ctx) where T : struct, IJobParallel { job.Execute(0, totalIterations, in ctx); } }