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);
}
}