Esempio n. 1
0
        public static unsafe IntPtr CreateJobReflectionData(Type type, Type _,
                                                            Delegate executeDelegate,
                                                            Delegate cleanupDelegate = null,
                                                            ManagedJobForEachDelegate codegenExecuteDelegate = null,
                                                            ManagedJobDelegate codegenCleanupDelegate        = null,
                                                            int codegenUnmanagedJobSize = -1,
                                                            ManagedJobMarshalDelegate codegenMarshalToBurstDelegate = null)
        {
            // Tiny doesn't use this on any codepath currently; may need future support for custom jobs.
            Assert.IsTrue(cleanupDelegate == null, "Runtime needs support for cleanup delegates in jobs.");

            Assert.IsTrue(codegenExecuteDelegate != null, "Code gen should have supplied an execute wrapper.");
#if ENABLE_UNITY_COLLECTIONS_CHECKS && !UNITY_DOTSRUNTIME_IL2CPP
            Assert.IsTrue((codegenUnmanagedJobSize != -1 && codegenMarshalToBurstDelegate != null) || (codegenUnmanagedJobSize == -1 && codegenMarshalToBurstDelegate == null), "Code gen should have supplied a marshal wrapper.");
#endif

            ReflectionDataProxy *reflectionDataPtr = (ReflectionDataProxy *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ReflectionDataProxy>(),
                                                                                                 UnsafeUtility.AlignOf <ReflectionDataProxy>(), Allocator.Persistent);

            var reflectionData = new ReflectionDataProxy();

            // Protect against garbage collector relocating delegate
            ReflectionDataStore store = new ReflectionDataStore(executeDelegate, codegenCleanupDelegate, codegenExecuteDelegate, codegenMarshalToBurstDelegate);
            store.next = Managed.reflectionDataStoreRoot;
            Managed.reflectionDataStoreRoot = store;

            reflectionData.ExecuteFunctionPtr = store.CodeGenExecuteFunctionPtr;
            if (codegenCleanupDelegate != null)
            {
                reflectionData.CleanupFunctionPtr = store.CodeGenCleanupFunctionPtr;
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS && !UNITY_DOTSRUNTIME_IL2CPP
            reflectionData.UnmanagedSize = codegenUnmanagedJobSize;
            if (codegenUnmanagedJobSize != -1)
            {
                reflectionData.MarshalToBurstFunctionPtr = store.CodeGenMarshalToBurstFunctionPtr;
            }
#endif

            UnsafeUtility.CopyStructureToPtr(ref reflectionData, reflectionDataPtr);

            return((IntPtr)reflectionDataPtr);
        }
Esempio n. 2
0
            public unsafe JobScheduleParameters(void *jobData,
                                                ReflectionDataProxy *reflectionData,
                                                JobHandle jobDependency,
                                                ScheduleMode scheduleMode,
                                                int jobDataSize = 0,
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                                                int producerJobPreSchedule = 1,
                                                int userJobPreSchedule     = 3,
#endif
                                                int isBursted = 5)
            {
                // Synchronize with InterfaceGen.cs!
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                const int k_ProducerScheduleReturnValue       = 4;
                const int k_UserScheduleReturnValue           = 2;
                const int k_UserScheduleReturnValueNoParallel = -2;
#endif

                const string k_PostFix = " Seeing this error indicates a bug in the dots compiler. We'd appreciate a bug report (About->Report a Bug...).";

                // Default is 0; code-gen should set to a correct size.
                if (jobDataSize == 0)
                {
                    throw new InvalidOperationException("JobScheduleParameters (size) should be set by code-gen." + k_PostFix);
                }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (producerJobPreSchedule != k_ProducerScheduleReturnValue)
                {
                    throw new InvalidOperationException(
                              "JobScheduleParameter (which is the return code of ProducerScheduleFn_Gen) should be set by code-gen." + k_PostFix);
                }
                if (userJobPreSchedule != k_UserScheduleReturnValue && userJobPreSchedule != k_UserScheduleReturnValueNoParallel)
                {
                    throw new InvalidOperationException(
                              "JobScheduleParameter (which is the return code of PrepareJobAtPreScheduleTimeFn_Gen) should be set by code-gen." + k_PostFix);
                }
#endif
                if (!(isBursted == 0 || isBursted == 1))
                {
                    throw new InvalidOperationException(
                              "JobScheduleParameter (which is the return code of RunOnMainThread_Gen) should be set by code-gen." + k_PostFix);
                }

                int          nWorkers = JobWorkerCount > 0 ? JobWorkerCount : 1;
                JobMetaData *mem      = AllocateJobHeapMemory(jobDataSize, nWorkers);

                // A copy of the JobData is needed *for each worker thread* as it will
                // get mutated in unique ways (threadIndex, safety.) The jobIndex is passed
                // to the Execute method, so a thread can look up the correct jobData to use.
                // Cleanup is always called on jobIndex=0.
                for (int i = 0; i < nWorkers; i++)
                {
                    UnsafeUtility.MemCpy(((byte *)mem + sizeof(JobMetaData) + jobDataSize * i), jobData, jobDataSize);
                }
                UnsafeUtility.AssertHeap(mem);

                JobMetaData jobMetaData = new JobMetaData();
                jobMetaData.jobDataSize = jobDataSize;
                // Indicate parallel for is an error
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (userJobPreSchedule == k_UserScheduleReturnValueNoParallel)
                {
                    jobMetaData.isParallelFor = -1;
                }
#endif
                UnsafeUtility.CopyStructureToPtr(ref jobMetaData, mem);

                Dependency     = jobDependency;
                JobDataPtr     = mem;
                ReflectionData = reflectionData;
#if UNITY_DOTSRUNTIME_MULTITHREAD_NOBURST
                // Allow debugging multithreaded code without burst when necessary
                ScheduleMode = scheduleMode;
#else
                // Normally, only bursted methods run on worker threads
                if (isBursted != 0)
                {
                    ScheduleMode = scheduleMode;
                }
                else
                {
                    // Both main thread schedule modes run immediately - the difference is that scheduling returns a job handle
                    // which must still be synced in order to maintain dependency safety, whereas run returns a default job handle
                    // not needing completion.
                    ScheduleMode = scheduleMode == ScheduleMode.Run ? ScheduleMode.RunOnMainThread : ScheduleMode.ScheduleOnMainThread;
                }
#endif
            }