static unsafe JobHandle Schedule <T>(ref T jobData, IntPtr arrayLengthPtr, int innerloopBatchCount, JobHandle dependsOn)
            where T : struct, IJobParallelForDefer
        {
#if UNITY_SINGLETHREADED_JOBS
            var arrayLength = UnsafeUtility.AsRef <int>(arrayLengthPtr.ToPointer());
            for (var i = 0; i < arrayLength; ++i)
            {
                jobData.Execute(i);
            }

            DoDeallocateOnJobCompletion(jobData);
            return(new JobHandle());
#else
            var jobStruct = new JobStructDefer <T>()
            {
                JobData        = jobData,
                ArrayLengthPtr = arrayLengthPtr,
            };

            var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <JobStructDefer <T> >(),
                                                  UnsafeUtility.AlignOf <JobStructDefer <T> >(), Allocator.TempJob);
            UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr);

            var scheduleParams = new JobsUtility.JobScheduleParameters(jobDataPtr, JobStructDefer <T> .Initialize(),
                                                                       dependsOn, ScheduleMode.Batched);
            return(JobsUtility.ScheduleParallelFor(ref scheduleParams, JobsUtility.JobQueueThreadCount, innerloopBatchCount));
#endif
        }
Example #2
0
        /// <summary>
        /// Schedule the job for execution on worker threads.
        /// forEachCount is a pointer to the number of iterations, when dependsOn has completed.
        /// This API is unsafe, it is recommended to use the NativeList based Schedule method instead.
        /// </summary>
        /// <param name="jobData"></param>
        /// <param name="forEachCount"></param>
        /// <param name="innerloopBatchCount"></param>
        /// <param name="dependsOn"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static unsafe JobHandle Schedule <T>(this T jobData, int *forEachCount, int innerloopBatchCount,
                                                    JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
        {
            var scheduleParams = new JobsUtility.JobScheduleParameters(
                UnsafeUtility.AddressOf(ref jobData),
                JobStructDefer <T> .Initialize(), dependsOn, ScheduleMode.Batched);

            var forEachListPtr = (byte *)forEachCount - sizeof(void *);

            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount,
                                                                 forEachListPtr, null));
        }
Example #3
0
        static unsafe JobHandle Schedule <T>(ref T jobData, IntPtr arrayLengthPtr, int innerloopBatchCount, JobHandle dependsOn)
            where T : struct, IJobParallelForDefer
        {
#if UNITY_SINGLETHREADED_JOBS
            var arrayLength = UnsafeUtility.AsRef <int>(arrayLengthPtr.ToPointer());
            for (var i = 0; i < arrayLength; ++i)
            {
                jobData.Execute(i);
            }

            DoDeallocateOnJobCompletion(jobData);
            return(new JobHandle());
#else
            // Protect against garbage collection
            if (!JobStructDefer <T> .ExecuteHandle.IsAllocated)
            {
                JobStructDefer <T> .ExecuteDelegate    = JobStructDefer <T> .Execute;
                JobStructDefer <T> .ExecuteHandle      = GCHandle.Alloc(JobStructDefer <T> .ExecuteDelegate);
                JobStructDefer <T> .ExecuteFunctionPtr = Marshal.GetFunctionPointerForDelegate(JobStructDefer <T> .ExecuteDelegate);
            }

            // Protect against garbage collection
            if (!JobStructDefer <T> .CleanupHandle.IsAllocated)
            {
                JobStructDefer <T> .CleanupDelegate    = JobStructDefer <T> .Cleanup;
                JobStructDefer <T> .CleanupHandle      = GCHandle.Alloc(JobStructDefer <T> .CleanupDelegate);
                JobStructDefer <T> .CleanupFunctionPtr = Marshal.GetFunctionPointerForDelegate(JobStructDefer <T> .CleanupDelegate);
            }

            var jobFunctionPtr    = JobStructDefer <T> .ExecuteFunctionPtr;
            var completionFuncPtr = JobStructDefer <T> .CleanupFunctionPtr;

            var jobStruct = new JobStructDefer <T>()
            {
                JobData        = jobData,
                ArrayLengthPtr = arrayLengthPtr,
            };

            var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <JobStructDefer <T> >(),
                                                  UnsafeUtility.AlignOf <JobStructDefer <T> >(), Allocator.TempJob);
            UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr);

            return(JobsUtility.ScheduleJobForEach(jobFunctionPtr, completionFuncPtr, new IntPtr(jobDataPtr),
                                                  JobsUtility.JobQueueThreadCount, innerloopBatchCount, dependsOn));
#endif
        }
Example #4
0
        /// <summary>
        /// Schedule the job for execution on worker threads.
        /// list.Length is used as the iteration count.
        /// Note that it is required to embed the list on the job struct as well.
        /// </summary>
        /// <param name="jobData">The job and data to schedule.</param>
        /// <param name="list">list.Length is used as the iteration count.</param>
        /// <param name="innerloopBatchCount">Granularity in which workstealing is performed. A value of 32, means the job queue will steal 32 iterations and then perform them in an efficient inner loop.</param>
        /// <param name="dependsOn">Dependencies are used to ensure that a job executes on workerthreads after the dependency has completed execution. Making sure that two jobs reading or writing to same data do not run in parallel.</param>
        /// <returns>JobHandle The handle identifying the scheduled job. Can be used as a dependency for a later job or ensure completion on the main thread.</returns>
        public static unsafe JobHandle Schedule <T, U>(this T jobData, NativeList <U> list, int innerloopBatchCount,
                                                       JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
            where U : struct
        {
            void *atomicSafetyHandlePtr = null;
            var   scheduleParams        = new JobsUtility.JobScheduleParameters(
                UnsafeUtility.AddressOf(ref jobData),
                JobStructDefer <T> .Initialize(), dependsOn, ScheduleMode.Batched);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var safety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref list);
            atomicSafetyHandlePtr = UnsafeUtility.AddressOf(ref safety);
#endif
            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount,
                                                                 NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref list), atomicSafetyHandlePtr));
        }