Ejemplo n.º 1
0
        public static void CheckWriteAndThrow(AtomicSafetyHandle handle)
        {
            if (handle.IsAllowedToWrite())
            {
                return;
            }

            if (Unity.Jobs.LowLevel.Unsafe.JobsUtility.IsExecutingJob())
            {
                throw new System.InvalidOperationException("You are not allowed to write this native container or resource");
            }

            unsafe
            {
                AtomicSafetyNode *node = handle.GetInternalNode();
                if (node == null)
                {
                    throw new System.InvalidOperationException("The safety handle is no longer valid -- a native container or other protected resource has been deallocated");
                }

                // @@TODO Need native support
                //If !main thread
                //throw "Native container or resource being used from thread which is not main or belonging to job"

                // @@TODO Need native support
                //if (!CheckDidSyncFence(node->writer.fence))
                //{
                //    Assert(!AtomicSafetyHandle::ValidateIsAllowedToWriteEarlyOut(buffer));
                //    return ReturnErrorMsg(kNativeArrayWriteMainThreadAgainstWriteJob, node->writer, errorMsg);
                //}

                // @@TODO Need code IL post processing
                //for (size_t i = 0; i != node->readers.size(); i++)
                //{
                //    // Only allowed to access data if someone called sync fence on the job or on a job that depends on it.
                //    if (!CheckDidSyncFence(node->readers[i].fence))
                //    {
                //        Assert(!AtomicSafetyHandle::ValidateIsAllowedToWriteEarlyOut(buffer));
                //        return ReturnErrorMsg(kNativeArrayWriteMainThreadAgainstReadJob, node->readers[i], errorMsg);
                //    }
                //}

                if ((node->flags & AtomicSafetyNodeFlags.AllowSecondaryWriting) == 0 && handle.UncheckedIsSecondaryVersion())
                {
                    throw new System.InvalidOperationException("Native container has been declared [ReadOnly] but you are attemping to write to it");
                }

                // If we are write protected, but are no longer in a job and no other safety checks failed, we can remove write protection
                node->version0 &= AtomicSafetyNodeVersionMask.WriteUnprotect;
                if ((node->flags & AtomicSafetyNodeFlags.AllowSecondaryWriting) == AtomicSafetyNodeFlags.AllowSecondaryWriting)
                {
                    node->version1 &= AtomicSafetyNodeVersionMask.WriteUnprotect;
                }
            }

            UnityEngine.Assertions.Assert.IsTrue(handle.IsAllowedToWrite());
        }
Ejemplo n.º 2
0
 public JobHandle GetWriter()
 {
     unsafe
     {
         AtomicSafetyNode *node = GetInternalNode();
         if (node != null)
         {
             return(node->writer.fence);
         }
     }
     return(new JobHandle());
 }
Ejemplo n.º 3
0
        public unsafe int GetReaderArray(int maxCount, JobHandle *handles)
        {
            AtomicSafetyNode *node = GetInternalNode();

            if (node == null)
            {
                return(0);
            }

            int count = node->readerCount < maxCount ? node->readerCount : maxCount;

            for (int i = 0; i < count; i++)
            {
                handles[i] = node->readers[i].fence;
            }

            return(node->readerCount);
        }
Ejemplo n.º 4
0
        public static void Release(AtomicSafetyHandle handle)
        {
            unsafe
            {
                // Can throw if corrupted or unallowed job
                // Otherwise return null if released already (based on version mismatch), where we will throw
                AtomicSafetyNode *node = handle.GetInternalNode();
                if (node == null)
                {
                    throw new System.InvalidOperationException("The Handle has already been released");
                }

                // Clear all protections and increment version to protect from any other remaining AtomicSafetyHandles
                node->version0 = (node->version0 & AtomicSafetyNodeVersionMask.ReadWriteDisposeUnprotect) + AtomicSafetyNodeVersionMask.VersionInc;
                node->version1 = (node->version1 & AtomicSafetyNodeVersionMask.ReadWriteDisposeUnprotect) + AtomicSafetyNodeVersionMask.VersionInc;
                PushAtomicNode((void *)handle.nodePtrPtr);
            }
        }
Ejemplo n.º 5
0
        public static void CheckGetSecondaryDataPointerAndThrow(AtomicSafetyHandle handle)
        {
            if (handle.IsAllowedToRead())
            {
                return;
            }

            if (Unity.Jobs.LowLevel.Unsafe.JobsUtility.IsExecutingJob())
            {
                throw new System.InvalidOperationException("You are not allowed to read this native container or resource");
            }

            unsafe
            {
                AtomicSafetyNode *node = handle.GetInternalNode();
                if (node == null)
                {
                    throw new System.InvalidOperationException("The safety handle is no longer valid -- a native container or other protected resource has been deallocated");
                }

                UnityEngine.Assertions.Assert.IsFalse(handle.UncheckedIsSecondaryVersion());

                // @@TODO Need native support
                //If !main thread
                //throw "Native container or resource being used from thread which is not main or belonging to job"

                // @@TODO Need code IL post processing
                // The primary buffer might (List) might resize
                // The secondary buffer does not resize (Array)
                // Thus if it was scheduled as a secondary buffer, we can safely access it
                //if (node->writer.wasScheduledWithSecondaryBuffer == 1)
                //    return;

                // @@TODO Need native support
                //if (!CheckDidSyncFence(node->writer.fence))
                //return;
            }

            UnityEngine.Assertions.Assert.IsFalse(handle.IsAllowedToRead());
            throw new System.InvalidOperationException("The previously scheduled job writes to the NativeList. You must call JobHandle.Complete() on the job before you can cast the NativeList to a NativeArray safely or use NativeList.AsDeferredJobArray() to cast the array when the job executes.");
        }
Ejemplo n.º 6
0
        public static void CheckReadAndThrow(AtomicSafetyHandle handle)
        {
            if (handle.IsAllowedToRead())
            {
                return;
            }

            if (Unity.Jobs.LowLevel.Unsafe.JobsUtility.IsExecutingJob())
            {
                throw new System.InvalidOperationException("You are not allowed to read this native container or resource");
            }

            unsafe
            {
                AtomicSafetyNode *node = handle.GetInternalNode();
                if (node == null)
                {
                    throw new System.InvalidOperationException("The safety handle is no longer valid -- a native container or other protected resource has been deallocated");
                }

                // @@TODO Need native support
                //If !main thread
                //throw "Native container or resource being used from thread which is not main or belonging to job"

                // @@TODO Need native support
                //if (!CheckDidSyncFence(node->writer.fence))
                //{
                //    Assert(!AtomicSafetyHandle::ValidateIsAllowedToReadEarlyOut(buffer));
                //    return ReturnErrorMsg(kNativeArrayReadMainThreadAgainstWriteJob, node->writer, errorMsg);
                //}

                // If we are read protected, but are no longer in a job and no other safety checks failed, we can remove read protection
                node->version0 &= AtomicSafetyNodeVersionMask.ReadUnprotect;
                node->version1 &= AtomicSafetyNodeVersionMask.ReadUnprotect;
            }

            UnityEngine.Assertions.Assert.IsTrue(handle.IsAllowedToRead());
        }