⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 virtualprocessor.h

📁 C语言库函数的原型,有用的拿去
💻 H
📖 第 1 页 / 共 2 页
字号:
        // Owning ring -- may change
        SchedulingRing *m_pOwningRing;

        // Owning virtual processor root
        IVirtualProcessorRoot *m_pOwningRoot;

        // Sub allocator
        SubAllocator *m_pSubAllocator;

        // Flag that specifies if the virtual processor is working on a ring that is different from it's owning
        // ring.
        volatile LONG m_fRambling;

        // The index that this Virtual Processor is at in its list array
        int m_listArrayIndex;

        // Statistics data counters
        unsigned int m_enqueuedTaskCounter;
        unsigned int m_dequeuedTaskCounter;

        // Statistics data checkpoints
        unsigned int m_enqueuedTaskCheckpoint;
        unsigned int m_dequeuedTaskCheckpoint;

        // Internal context that is affinitized to and executing on this virtual processor
        // This is always an InternalContextBase except on UMS in very special circumstances.
        IExecutionContext * m_pExecutingContext;

        _HyperNonReentrantLock m_lock;

        // Unique identifier for vprocs within a scheduler.
        unsigned int m_id;

        // Flag specifying whether this is a virtual processor created as a result of a call to Oversubscribe.
        bool m_fOversubscribed;

        // Flag that is set when the virtual processor should remove itself from the scheduler at a yield point,
        // i.e, either when the context executing on it calls Block or Yield, or when it is in the dispatch loop
        // looking for work.
        bool m_fMarkedForRetirement;

        // Whether this virtual processor has reached a safe point in the code
        // Used to demark when all virtual processors have reached safe points and a list array deletion
        // can occur
        bool m_fReachedSafePoint;

        // A hidden virtual processor is one that was created for Oversubscribe but whose activation is throttled.
        bool m_fHidden;

        /// <summary>
        ///     Causes the virtual processor to remove itself from the scheduler. This is used either when oversubscription
        ///     ends or when the resource manager asks the vproc to retire.
        /// </summary>
        virtual void Retire();

        // The internal context that caused this virtual processor to be created, if this is an oversubscribed vproc.
        InternalContextBase * m_pOversubscribingContext;

        /// <summary>
        ///     Affinitizes an internal context to the virtual processor.
        /// </summary>
        /// <param name="pContext">
        ///     The internal context to affinitize.
        /// </param>
        virtual void Affinitize(InternalContextBase *pContext);

        /// <summary>
        ///     Returns a type-cast of pContext to an InternalContextBase or NULL if it is not.
        /// </summary>
        virtual InternalContextBase *ToInternalContext(IExecutionContext *pContext);

        /// <summary>
        ///     Initializes the virtual processor. This API is called by the constructor, and when a virtual processor is to
        ///     be re-initialized, when it is pulled of the free pool in the list array.
        /// </summary>
        /// <param name="pOwningNode">
        ///     The owning schedule node for this virtual processor
        /// </param>
        /// <param name="pOwningRoot">
        ///     The owning IVirtualProcessorRoot
        /// </param>
        virtual void Initialize(SchedulingNode *pOwningNode, IVirtualProcessorRoot *pOwningRoot);

    private:
        friend class SchedulerBase;
        friend class ContextBase;
        friend class InternalContextBase;
        friend class ThreadInternalContext;
        friend class UMSThreadInternalContext;
        friend class UMSSchedulingContext;
        friend class ScheduleGroup;
        friend class FairScheduleGroup;
        friend class CacheLocalScheduleGroup;
        friend class SchedulingNode;
        friend class WorkSearchContext;
        template <class T> friend class ListArray;
        template<class T, class Counter> friend class List;

        // Indication of throttling.
        bool m_fThrottled;

        // Links for throttling
        VirtualProcessor *m_pNext;
        VirtualProcessor *m_pPrev;

        // Intrusive links for list array.
        SLIST_ENTRY m_listArrayFreeLink;

        // The safe point marker.
        SafePointMarker m_safePointMarker;

#if _UMSTRACE
        _TraceBuffer m_traceBuffer;
#endif // _UMSTRACE

        /// <summary>
        ///     Start a worker context executing on this.virtual processor.
        /// </summary>
        virtual void StartupWorkerContext(ScheduleGroupBase* pGroup);

        /// <summary>
        ///     Oversubscribes the virtual processor by creating a new virtual processor root affinitized to the same
        ///     execution resource as that of the current root
        /// </summary>
        /// <returns>
        ///     A virtual processor that oversubscribes this one.
        /// </returns>
        virtual VirtualProcessor * Oversubscribe();

        /// <summary>
        ///     Marks the the virtual processor such that it removes itself from the scheduler, once the context it is executing
        ///     reaches a safe yield point. Alternatively, if the context has not started executing yet, it can be retired immediately.
        /// </summary>
        void MarkForRetirement();

#if _UMSTRACE
        void TraceSearchedLocalRunnables();
#endif // _UMSTRACE

        /// <summary>
        ///     Steals a context from the local runnables queue of this virtual processor.
        /// </summary>
        InternalContextBase *StealLocalRunnableContext()
        {
#if _UMSTRACE
            TraceSearchedLocalRunnables();
#endif // _UMSTRACE

            InternalContextBase *pContext = m_localRunnableContexts.Steal();
            if (pContext != NULL)
            {
#if defined(_DEBUG)
                Concurrency::details::SetContextDebugBits(pContext, CTX_DEBUGBIT_STOLENFROMLOCALRUNNABLECONTEXTS);
#endif // _DEBUG
            }

            return pContext;
        }

        /// <summary>
        ///     Pops a runnable context from the local runnables queue of the vproc, if it can find one.
        /// </summary>
        InternalContextBase *GetLocalRunnableContext()
        {
#if _UMSTRACE
            TraceSearchedLocalRunnables();
#endif // _UMSTRACE

            if (m_localRunnableContexts.Count() > 0) // Is this check worthwhile?  Yes, I believe.  We'd take a fence to check otherwise.
            {
                InternalContextBase *pContext = m_localRunnableContexts.Pop();
#if defined(_DEBUG)
                Concurrency::details::SetContextDebugBits(pContext, CTX_DEBUGBIT_POPPEDFROMLOCALRUNNABLECONTEXTS);
#endif // _DEBUG
                return pContext;
            }
            return NULL;
        }

        /// <summary>
        ///     Resets the count of work coming in.
        /// </summary>
        /// <remarks>
        ///     This function is using modulo 2 behavior of unsigned ints to avoid overflow and
        ///     reset problems. For more detail look at ExternalStatistics class in externalcontextbase.h.
        /// </remarks>
        /// <returns>
        ///     Previous value of the counter.
        /// </returns>
        unsigned int GetEnqueuedTaskCount()
        {
            unsigned int currentValue = m_enqueuedTaskCounter;
            unsigned int retVal = currentValue - m_enqueuedTaskCheckpoint;

            // Update the checkpoint value with the current value
            m_enqueuedTaskCheckpoint = currentValue;

            ASSERT(retVal < INT_MAX);
            return retVal;
        }

        /// <summary>
        ///     Resets the count of work being done.
        /// </summary>
        /// <remarks>
        ///     This function is using modulo 2 behavior of unsigned ints to avoid overflow and
        ///     reset problems. For more detail look at the ExternalStatistics class in externalcontextbase.h.
        /// </remarks>
        /// <returns>
        ///     Previous value of the counter.
        /// </returns>
        unsigned int GetDequeuedTaskCount()
        {
            unsigned int currentValue = m_dequeuedTaskCounter;
            unsigned int retVal = currentValue - m_dequeuedTaskCheckpoint;

            // Update the checkpoint value with the current value
            m_dequeuedTaskCheckpoint = currentValue;

            ASSERT(retVal < INT_MAX);
            return retVal;
        }

        /// <summary>
        ///     Send a virtual processor ETW event
        /// </summary>
        void TraceVirtualProcessorEvent(ConcRT_EventType eventType, UCHAR level, DWORD schedulerId, DWORD vprocId)
        {
            if (g_TraceOn && level <= g_EnableLevel)
                ThrowVirtualProcessorEvent(eventType, level, schedulerId, vprocId);
        }

        /// <summary>
        ///     Send a virtual processor ETW event
        /// </summary>
        static void ThrowVirtualProcessorEvent(ConcRT_EventType eventType, UCHAR level, DWORD schedulerId, DWORD vprocId);
    };
} // namespace details
} // namespace Concurrency

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -