// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// CacheLocalScheduleGroup.h
//
// Header file containing CacheLocalScheduleGroup related declarations.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#pragma once
namespace Concurrency
{
namespace details
{
class CacheLocalScheduleGroup;
class CacheLocalScheduleGroupSegment : public ScheduleGroupSegmentBase
{
public:
//
// Public Methods
//
///
/// Constructs a cache local schedule group segment
///
CacheLocalScheduleGroupSegment(ScheduleGroupBase *pOwningGroup, SchedulingRing *pOwningRing, location* pSegmentAffinity) :
ScheduleGroupSegmentBase(pOwningGroup, pOwningRing, pSegmentAffinity)
{
}
///
/// Places a chore in the mailbox associated with this schedule group segment.
///
///
/// The chore to mail.
///
///
/// The mailbox slot into which the chore was placed.
///
///
/// A mailed chore should also be placed on its regular work stealing queue. The mailing must come first and once mailed, the chore body
/// cannot be referenced until the slot is successfully claimed via a call to the ClaimSlot method.
///
Mailbox<_UnrealizedChore>::Slot MailChore(_UnrealizedChore *pChore);
///
/// Notifies virtual processors that work affinitized to them has become available in the schedule group segment.
///
virtual void NotifyAffinitizedWork();
protected:
private:
friend class SchedulerBase;
friend class CacheLocalScheduleGroup;
friend class ContextBase;
friend class ExternalContextBase;
friend class InternalContextBase;
friend class ThreadInternalContext;
friend class SchedulingNode;
friend class SchedulingRing;
friend class VirtualProcessor;
//
// Private data
//
// Each schedule group has three stores of work. It has a collection of runnable contexts,
// a FIFO queue of realized chores and a list of workqueues that hold unrealized chores.
// A collection of Runnable contexts.
SafeSQueue m_runnableContexts;
//
// Private methods
//
///
/// Puts a runnable context into the runnables collection in the schedule group.
///
void AddToRunnablesCollection(InternalContextBase *pContext);
InternalContextBase *GetRunnableContext()
{
if (m_runnableContexts.Empty())
return NULL;
InternalContextBase *pContext = m_runnableContexts.Dequeue();
#if defined(_DEBUG)
SetContextDebugBits(pContext, CTX_DEBUGBIT_REMOVEDFROMRUNNABLES);
#endif // _DEBUG
return pContext;
}
};
class CacheLocalScheduleGroup : public ScheduleGroupBase
{
public:
///
/// Constructs a new cache local schedule group.
///
CacheLocalScheduleGroup(SchedulerBase *pScheduler, location* pGroupPlacement) :
ScheduleGroupBase(pScheduler, pGroupPlacement)
{
m_kind = CacheLocalScheduling;
}
///
/// Places a chore in a mailbox associated with the schedule group which is biased towards tasks being picked up from the specified
/// location.
///
///
/// The chore to mail.
///
///
/// A pointer to a location where the chore will be mailed.
///
///
/// The mailbox slot into which the chore was placed.
///
///
/// A mailed chore should also be placed on its regular work stealing queue. The mailing must come first and once mailed, the chore body
/// cannot be referenced until the slot is successfully claimed via a call to the ClaimSlot method.
///
virtual Mailbox<_UnrealizedChore>::Slot MailChore(_UnrealizedChore * pChore,
location * pPlacement,
ScheduleGroupSegmentBase ** ppDestinationSegment);
protected:
///
/// Allocates a new cache local schedule group segment within the specified group and ring with the specified affinity.
///
///
/// The affinity for the segment.
///
///
/// The scheduling ring to which the newly allocated segment will belong.
///
///
/// A new cache local schedule group within the specified group and ring with the specified affinity.
///
virtual ScheduleGroupSegmentBase* AllocateSegment(SchedulingRing *pOwningRing, location* pSegmentAffinity)
{
return _concrt_new CacheLocalScheduleGroupSegment(this, pOwningRing, pSegmentAffinity);
}
};
} // namespace details
} // namespace Concurrency