Esempio n. 1
0
            internal ThreadBucketNode *next;  // offset 120

            internal static unsafe bool SearchFor(ThreadBucketNode *startNode, ulong threadId, ref ThreadBucketNode *bucketNode)
            {
                ThreadBucketNode *prev = startNode;

                while (startNode != null)
                {
                    if (startNode->threadId == threadId)
                    {
                        bucketNode = startNode;
                        return(true);
                    }

                    prev      = startNode;
                    startNode = startNode->next;
                }

                bucketNode = prev;
                return(false);
            }
Esempio n. 2
0
        // NOT Burst safe due to string usage
        // Thread safe
        internal static unsafe void ThreadSetInfo(ulong threadId, ulong sysTicksStart, bool frameIndependent, string threadGroup, string threadName)
        {
            ThreadBucketNode *thread = null;
            int bucket = (int)threadId & 255;

            if (threadHashTableHead != null)
            {
                // No need for locking yet - read operations on hash table are thread safe as long as we are careful about
                // modification during write and only allow one thread to write at a time.
                if (ThreadBucketNode.SearchFor(&threadHashTableHead->ThreadsBuffer[bucket], threadId, ref thread))
                {
                    return;
                }
            }

            // The thread info didn't exist in hash table. Need to lock so only one thread can modify at a time.
            // This path will usually only be taken during startup when creating threads - after which thread info
            // should be found in the above loop instead of needing to be created.
            PlayerConnectionMt_LockProfilerHashTables();

            if (thread == null)
            {
                if (threadHashTableHead == null)
                {
                    threadHashTableHead = FastHashTableBufferNode.Allocate(sizeof(ThreadBucketNode));
                    threadHashTableTail = threadHashTableHead;
                }

                thread = &threadHashTableHead->ThreadsBuffer[bucket];
            }

            // In case this bucket was added to while another thread had the lock, the end-of-bucket
            // pointer needs to be increased. Also, it's possible the same exact name appears now.
            if (ThreadBucketNode.SearchFor(thread, threadId, ref thread))
            {
                PlayerConnectionMt_UnlockProfilerHashTables();
                return;
            }

            ThreadBucketNode *oldThread = null;

            if (thread->nameBytes > 0 || thread->groupBytes > 0)
            {
                // There is already a valid thread here at the end of the linked list - add a new one
                threadHashTableTail = threadHashTableTail->ExtendPoolIfFull(sizeof(ThreadBucketNode));

                ThreadBucketNode *newThread = &threadHashTableTail->ThreadsBuffer[threadHashTableTail->size];
                threadHashTableTail->size++;
                oldThread = thread;
                thread    = newThread;
            }

            thread->init = false;
            Assert.IsTrue(thread->nameBytes <= k_MaxThreadNameLength);
            Assert.IsTrue(thread->groupBytes <= k_MaxThreadNameLength);

            fixed(char *c = threadGroup)
            thread->groupBytes = UTF8.GetBytes(c, threadGroup.Length, thread->groupUtf8, k_MaxThreadNameLength);

            fixed(char *c = threadName)
            thread->nameBytes = UTF8.GetBytes(c, threadName.Length, thread->nameUtf8, k_MaxThreadNameLength);

            thread->frameIndependent = frameIndependent;
            thread->sysTicksStart    = sysTicksStart;
            thread->threadId         = threadId;

            // Do this last so if we find the node before locking, we don't have access to it unless it is otherwise fully assigned
            if (oldThread != null)
            {
                oldThread->next = thread;
            }

            PlayerConnectionMt_UnlockProfilerHashTables();

            NeedsUpdate = true;
        }