ReactOS 0.4.17-dev-1037-g720d112
SmMachine< Machine, Event > Class Template Reference

Run to completion engine. The first thread to post into an idle machine drains the queue; everyone else just enqueues. Handlers, entries and hooks run without the lock held. More...

#include <smengine.h>

Collaboration diagram for SmMachine< Machine, Event >:

Public Types

typedef SmState< Machine, Event > State
 

Public Member Functions

VOID SmInitialize (_In_ const State *Initial)
 
BOOLEAN SmPost (_In_ Event Ev)
 
VOID SmContinueOnPassive ()
 
const State * SmCurrent () const
 
ULONG SmDepth () const
 
const State * SmFrame (_In_ ULONG Index) const
 
BOOLEAN SmIsIn (_In_ const State *Ancestor) const
 
BOOLEAN SmIsPaused () const
 
BOOLEAN SmIsWaitingForTimer () const
 
ULONG SmUnexpectedCount () const
 

Protected Member Functions

VOID SmBeginPause ()
 
VOID SmDiscardQueued (_In_ Event Ev)
 
BOOLEAN SmAccepts (_In_ Event Ev)
 
VOID SmReference ()
 
VOID SmDereference ()
 
VOID SmQueuePassive ()
 
VOID SmOnDequeue (_In_ Event Ev)
 
VOID SmStateChanged ()
 
BOOLEAN SmCancelTimer ()
 

Static Protected Member Functions

static SM_RESULT SmMakeResult (_In_ SM_RESULT_KIND Kind, _In_ USHORT Ev, _In_opt_ const VOID *Target)
 
static SM_RESULT SmHandled ()
 
static SM_RESULT SmUnhandled ()
 
static SM_RESULT SmTransition (_In_ const State *Target)
 
static SM_RESULT SmPaused ()
 
static SM_RESULT SmCall (_In_ const State *Start)
 
static SM_RESULT SmReturn (_In_ Event Ev)
 

Static Protected Attributes

static const BOOLEAN SmCompletionsFirst = TRUE
 
static const USHORT SmTimerEventId = SM_NO_EVENT
 

Private Member Functions

Machine * Self ()
 
const State * EffectiveState () const
 
BOOLEAN IsQueued (_In_ Event Ev) const
 
BOOLEAN RemoveQueued (_In_ Event Ev)
 
BOOLEAN Dequeue (_Out_ Event *Ev)
 
VOID Purge (_In_ const State *Entered, _Inout_ KIRQL *Irql)
 
VOID Trace (_In_ SM_TRACE_KIND Kind, _In_ USHORT Ev)
 
SM_RESULT Dispatch (_In_ Event Ev)
 
BOOLEAN Run (_In_ KIRQL CallerIrql, _In_ USHORT LastEvent, _In_ SM_RESULT Result, _In_opt_ const State *Entered)
 Applies Result and keeps draining. Called without the lock. Entered is the state whose entry produced Result, if any. Returns TRUE when the machine stopped to wait for passive level or a timer and still owns the reference.
 

Static Private Member Functions

static BOOLEAN HasFlag (_In_ const State *Target, _In_ ULONG Flag)
 
static BOOLEAN Discards (_In_ const State *Target, _In_ Event Ev)
 

Private Attributes

KSPIN_LOCK m_Lock
 
const State * m_Frames [SM_MAX_DEPTH]
 
Event m_Queue [SM_QUEUE_DEPTH]
 
UCHAR m_Depth
 
UCHAR m_Count
 
BOOLEAN m_Running
 
BOOLEAN m_Paused
 
BOOLEAN m_WaitingForPassive
 
BOOLEAN m_WaitingForTimer
 
UCHAR m_TraceIndex
 
ULONG m_UnexpectedCount
 
SM_TRACE m_Trace [SM_TRACE_DEPTH]
 

Detailed Description

template<typename Machine, typename Event>
class SmMachine< Machine, Event >

Run to completion engine. The first thread to post into an idle machine drains the queue; everyone else just enqueues. Handlers, entries and hooks run without the lock held.

Machine must provide a static EventInfo[] table indexed by Event. It may hide SmAccepts, SmReference, SmDereference, SmQueuePassive, SmOnDequeue, SmStateChanged, SmCancelTimer, SmCompletionsFirst and SmTimerEventId.

Definition at line 113 of file smengine.h.

Member Typedef Documentation

◆ State

template<typename Machine , typename Event >
typedef SmState<Machine, Event> SmMachine< Machine, Event >::State

Definition at line 116 of file smengine.h.

Member Function Documentation

◆ Dequeue()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::Dequeue ( _Out_ Event *  Ev)
private

Definition at line 630 of file smengine.h.

632{
633 const State* effective = EffectiveState();
634 BOOLEAN takesRequests = HasFlag(effective, SM_STATE_TAKES_REQUESTS);
635 BOOLEAN criticalOnly = HasFlag(effective, SM_STATE_CRITICAL_ONLY);
636 ULONG pass;
637 ULONG index;
638 ULONG found = SM_QUEUE_DEPTH;
639
640 for (pass = 0; (pass < 2) && (found == SM_QUEUE_DEPTH); pass++)
641 {
642 for (index = 0; index < m_Count; index++)
643 {
644 SM_EVENT_CLASS eventClass =
645 Machine::EventInfo[static_cast<ULONG>(m_Queue[index])].Class;
646 BOOLEAN eligible;
647
648 if (eventClass == SmEventCritical)
649 eligible = TRUE;
650 else if (eventClass == SmEventRequest)
651 eligible = takesRequests && (!Machine::SmCompletionsFirst || (pass == 1));
652 else
653 eligible = !criticalOnly;
654
655 if (eligible)
656 {
657 found = index;
658 break;
659 }
660 }
661
662 if (!Machine::SmCompletionsFirst)
663 break;
664 }
665
666 if (found == SM_QUEUE_DEPTH)
667 return FALSE;
668
669 *Ev = m_Queue[found];
670 for (index = found + 1; index < m_Count; index++)
671 m_Queue[index - 1] = m_Queue[index];
672 m_Count--;
673 return TRUE;
674}
unsigned char BOOLEAN
Definition: actypes.h:127
#define index(s, c)
Definition: various.h:29
const State * EffectiveState() const
Definition: smengine.h:578
Event m_Queue[SM_QUEUE_DEPTH]
Definition: smengine.h:333
static BOOLEAN HasFlag(_In_ const State *Target, _In_ ULONG Flag)
Definition: smengine.h:540
UCHAR m_Count
Definition: smengine.h:335
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GLuint index
Definition: glext.h:6031
#define Ev
Definition: i386-dis.c:352
#define SM_STATE_TAKES_REQUESTS
Definition: smengine.h:39
enum _SM_EVENT_CLASS SM_EVENT_CLASS
#define SM_QUEUE_DEPTH
Definition: smengine.h:10
@ SmEventRequest
Definition: smengine.h:25
@ SmEventCritical
Definition: smengine.h:27
#define SM_STATE_CRITICAL_ONLY
Definition: smengine.h:41
uint32_t ULONG
Definition: typedefs.h:59
pass
Definition: typegen.h:25

◆ Discards()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::Discards ( _In_ const State *  Target,
_In_ Event  Ev 
)
staticprivate

Definition at line 557 of file smengine.h.

560{
561 const Event* list;
562
563 if (Target->Discards == NULL)
564 return FALSE;
565
566 for (list = Target->Discards; *list != Event::Count; list++)
567 {
568 if (*list == Ev)
569 return TRUE;
570 }
571
572 return FALSE;
573}
Definition: list.h:39
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define NULL
Definition: types.h:112
#define list
Definition: rosglue.h:35
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306

◆ Dispatch()

template<typename Machine , typename Event >
SM_RESULT SmMachine< Machine, Event >::Dispatch ( _In_ Event  Ev)
private

Definition at line 721 of file smengine.h.

723{
724 const State* walk;
726 ULONG frame = m_Depth;
727
728 /* Only the draining thread changes the frames, so no lock is needed here */
729 for (;;)
730 {
731 for (walk = m_Frames[frame]; walk != NULL; walk = walk->Parent)
732 {
733 if (Discards(walk, Ev))
734 return SmHandled();
735
736 if (walk->Handler == NULL)
737 continue;
738
739 result = (Self()->*walk->Handler)(Ev);
740 if (result.Kind != SmResultUnhandled)
741 {
742 result.Frame = static_cast<UCHAR>(frame);
743 return result;
744 }
745 }
746
747 if (frame == 0)
748 break;
749
750 frame--;
751 }
752
753 return SmUnhandled();
754}
const State * m_Frames[SM_MAX_DEPTH]
Definition: smengine.h:332
static BOOLEAN Discards(_In_ const State *Target, _In_ Event Ev)
Definition: smengine.h:557
static SM_RESULT SmHandled()
Definition: smengine.h:182
Machine * Self()
Definition: smengine.h:280
static SM_RESULT SmUnhandled()
Definition: smengine.h:188
UCHAR m_Depth
Definition: smengine.h:334
GLuint64EXT * result
Definition: glext.h:11304
@ SmResultUnhandled
Definition: smengine.h:47
unsigned char UCHAR
Definition: typedefs.h:53

◆ EffectiveState()

template<typename Machine , typename Event >
const SmMachine< Machine, Event >::State * SmMachine< Machine, Event >::EffectiveState
private

Definition at line 578 of file smengine.h.

579{
580 ULONG frame = m_Depth;
581
582 while ((frame > 0) && HasFlag(m_Frames[frame], SM_STATE_YIELDS_TO_CALLER))
583 frame--;
584
585 return m_Frames[frame];
586}
#define SM_STATE_YIELDS_TO_CALLER
Definition: smengine.h:42

◆ HasFlag()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::HasFlag ( _In_ const State *  Target,
_In_ ULONG  Flag 
)
staticprivate

Definition at line 540 of file smengine.h.

543{
544 const State* walk;
545
546 for (walk = Target; walk != NULL; walk = walk->Parent)
547 {
548 if (walk->Flags & Flag)
549 return TRUE;
550 }
551
552 return FALSE;
553}
Definition: xml2sdb.h:101

◆ IsQueued()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::IsQueued ( _In_ Event  Ev) const
private

Definition at line 590 of file smengine.h.

592{
593 ULONG index;
594
595 for (index = 0; index < m_Count; index++)
596 {
597 if (m_Queue[index] == Ev)
598 return TRUE;
599 }
600
601 return FALSE;
602}

◆ Purge()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::Purge ( _In_ const State *  Entered,
_Inout_ KIRQL *  Irql 
)
private

Definition at line 679 of file smengine.h.

682{
683 const State* walk;
684 const Event* list;
685
686 for (walk = Entered; walk != NULL; walk = walk->Parent)
687 {
688 if (walk->Discards == NULL)
689 continue;
690
691 for (list = walk->Discards; *list != Event::Count; list++)
692 {
693 if (!RemoveQueued(*list))
694 continue;
695
696 Trace(SmTraceDiscarded, static_cast<USHORT>(*list));
698 Self()->SmOnDequeue(*list);
700 }
701 }
702}
BOOLEAN RemoveQueued(_In_ Event Ev)
Definition: smengine.h:606
KSPIN_LOCK m_Lock
Definition: smengine.h:331
_Out_ PKIRQL Irql
Definition: csq.h:179
#define Trace(x)
Definition: inflate.c:42
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
unsigned short USHORT
Definition: pedump.c:61
@ SmTraceDiscarded
Definition: smengine.h:75

◆ RemoveQueued()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::RemoveQueued ( _In_ Event  Ev)
private

Definition at line 606 of file smengine.h.

608{
609 ULONG read;
610 ULONG write = 0;
611
612 for (read = 0; read < m_Count; read++)
613 {
614 if (m_Queue[read] != Ev)
615 {
617 write++;
618 }
619 }
620
621 if (write == m_Count)
622 return FALSE;
623
624 m_Count = static_cast<UCHAR>(write);
625 return TRUE;
626}
#define read
Definition: acwin.h:97
#define write
Definition: acwin.h:98

◆ Run()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::Run ( _In_ KIRQL  CallerIrql,
_In_ USHORT  LastEvent,
_In_ SM_RESULT  Result,
_In_opt_ const State *  Entered 
)
private

Applies Result and keeps draining. Called without the lock. Entered is the state whose entry produced Result, if any. Returns TRUE when the machine stopped to wait for passive level or a timer and still owns the reference.

Definition at line 764 of file smengine.h.

769{
770 const State* target;
771 const State* previous;
772 USHORT traced = LastEvent;
773 ULONG frame;
774 BOOLEAN canceled;
775 Event ev;
776 KIRQL irql;
777
778 for (;;)
779 {
780 /* Whoever posts the resume event owns the machine now, touch nothing */
781 if (Result.Kind == SmResultPaused)
782 return FALSE;
783
785
786 if ((Entered != NULL) && (Result.Kind != SmResultCall))
787 Purge(Entered, &irql);
788 Entered = NULL;
789
790 if (Result.Kind == SmResultReturn)
791 {
792 NT_ASSERTMSG("Return from the outermost frame", m_Depth > 0);
793 m_Depth--;
795 Purge(SmCurrent(), &irql);
796 traced = Result.Event;
798 Result = Dispatch(static_cast<Event>(Result.Event));
799 continue;
800 }
801
802 if ((Result.Kind == SmResultTransition) || (Result.Kind == SmResultCall))
803 {
804 target = static_cast<const State*>(Result.Target);
805
806 if (Result.Kind == SmResultCall)
807 {
808 NT_ASSERTMSG("State machine frames exhausted", m_Depth + 1 < SM_MAX_DEPTH);
809 m_Depth++;
811 Trace(SmTraceCalled, traced);
812 }
813 else
814 {
815 frame = (Result.Frame == SM_FRAME_INNERMOST) ? m_Depth : Result.Frame;
816 while (m_Depth > frame)
817 {
819 SM_BREAK("Caller left a frame that does not yield to it");
820 m_Depth--;
821 }
822
823 previous = m_Frames[frame];
824 m_Frames[frame] = target;
825 Trace(SmTraceEntered, traced);
826
828 Self()->SmStateChanged();
829
830 if (HasFlag(previous, SM_STATE_STOP_TIMER_ON_EXIT) &&
831 (traced != Machine::SmTimerEventId))
832 {
833 canceled = Self()->SmCancelTimer();
835
836 if (!canceled && !RemoveQueued(static_cast<Event>(Machine::SmTimerEventId)))
837 {
839 Trace(SmTraceWaitTimer, traced);
841 return TRUE;
842 }
843 }
844 else
845 {
847 }
848 }
849
851 {
853 Trace(SmTraceWaitPassive, traced);
855 Self()->SmQueuePassive();
856 return TRUE;
857 }
858
860 Entered = target;
861 Result = target->Entry ? (Self()->*target->Entry)() : SmHandled();
862 continue;
863 }
864
865 if (Result.Kind == SmResultUnhandled)
866 {
868 Trace(SmTraceUnhandled, traced);
869 SM_BREAK("State machine got an event no state handles");
870 }
871
872 if (!Dequeue(&ev))
873 {
876 return FALSE;
877 }
878
879 traced = static_cast<USHORT>(ev);
880 Trace(SmTraceDispatched, traced);
882
883 Self()->SmOnDequeue(ev);
884 Result = Dispatch(ev);
885 }
886}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
ULONG m_UnexpectedCount
Definition: smengine.h:341
BOOLEAN m_WaitingForTimer
Definition: smengine.h:339
const State * SmCurrent() const
Definition: smengine.h:130
BOOLEAN Dequeue(_Out_ Event *Ev)
Definition: smengine.h:630
VOID Purge(_In_ const State *Entered, _Inout_ KIRQL *Irql)
Definition: smengine.h:679
BOOLEAN m_Running
Definition: smengine.h:336
BOOLEAN m_WaitingForPassive
Definition: smengine.h:338
KIRQL irql
Definition: wave.h:1
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
__in MdIrp __in PMdIoCsqIrpContext __in KIRQL CallerIrql
Definition: fxirpqueue.hpp:77
#define SM_STATE_STOP_TIMER_ON_EXIT
Definition: smengine.h:43
@ SmResultPaused
Definition: smengine.h:50
@ SmResultReturn
Definition: smengine.h:52
@ SmResultTransition
Definition: smengine.h:49
@ SmResultCall
Definition: smengine.h:51
#define SM_MAX_DEPTH
Definition: smengine.h:11
#define SM_BREAK(Message)
Definition: smengine.h:18
@ SmTraceEntered
Definition: smengine.h:68
@ SmTraceWaitTimer
Definition: smengine.h:76
@ SmTraceWaitPassive
Definition: smengine.h:72
@ SmTraceDispatched
Definition: smengine.h:67
@ SmTraceCalled
Definition: smengine.h:73
@ SmTraceReturned
Definition: smengine.h:74
@ SmTraceUnhandled
Definition: smengine.h:69
#define SM_FRAME_INNERMOST
Definition: smengine.h:15
#define SM_STATE_NEEDS_PASSIVE
Definition: smengine.h:40
Definition: tools.h:99
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH * Dispatch
Definition: wsk.h:188
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3335

◆ Self()

template<typename Machine , typename Event >
Machine * SmMachine< Machine, Event >::Self ( )
inlineprivate

Definition at line 280 of file smengine.h.

281 {
282 return static_cast<Machine*>(this);
283 }

◆ SmAccepts()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::SmAccepts ( _In_ Event  Ev)
inlineprotected

Definition at line 236 of file smengine.h.

238 {
240 return TRUE;
241 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329

◆ SmBeginPause()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmBeginPause
protected

Definition at line 510 of file smengine.h.

511{
512 KIRQL irql;
513
515 m_Paused = TRUE;
518}
BOOLEAN m_Paused
Definition: smengine.h:337
@ SmTracePaused
Definition: smengine.h:70
#define SM_NO_EVENT
Definition: smengine.h:14

◆ SmCall()

template<typename Machine , typename Event >
static SM_RESULT SmMachine< Machine, Event >::SmCall ( _In_ const State *  Start)
inlinestaticprotected

Definition at line 209 of file smengine.h.

211 {
213 }
static _Out_opt_ PULONGLONG Start
static SM_RESULT SmMakeResult(_In_ SM_RESULT_KIND Kind, _In_ USHORT Ev, _In_opt_ const VOID *Target)
Definition: smengine.h:172

◆ SmCancelTimer()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::SmCancelTimer ( )
inlineprotected

Definition at line 273 of file smengine.h.

274 {
275 return TRUE;
276 }

◆ SmContinueOnPassive()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmContinueOnPassive

Definition at line 462 of file smengine.h.

463{
464 const State* current;
466 KIRQL irql;
467
469
471 {
474 SM_BREAK("Passive continuation without a state waiting for it");
475 return;
476 }
477
479 current = SmCurrent();
481
482 /* The reference taken by the drainer that queued the work item carries over */
483 result = current->Entry ? (Self()->*current->Entry)() : SmHandled();
485 Self()->SmDereference();
486}
struct tagRun Run
struct task_struct * current
Definition: linux.c:32

◆ SmCurrent()

template<typename Machine , typename Event >
const State * SmMachine< Machine, Event >::SmCurrent ( ) const
inline

Definition at line 130 of file smengine.h.

131 {
132 return m_Frames[m_Depth];
133 }

◆ SmDepth()

template<typename Machine , typename Event >
ULONG SmMachine< Machine, Event >::SmDepth ( ) const
inline

Definition at line 136 of file smengine.h.

137 {
138 return m_Depth;
139 }

◆ SmDereference()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmDereference ( )
inlineprotected

Definition at line 249 of file smengine.h.

250 {
251 }

◆ SmDiscardQueued()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmDiscardQueued ( _In_ Event  Ev)
protected

Definition at line 522 of file smengine.h.

524{
525 BOOLEAN removed;
526 KIRQL irql;
527
529 removed = RemoveQueued(Ev);
530 if (removed)
531 Trace(SmTraceDiscarded, static_cast<USHORT>(Ev));
533
534 if (removed)
535 Self()->SmOnDequeue(Ev);
536}

◆ SmFrame()

template<typename Machine , typename Event >
const State * SmMachine< Machine, Event >::SmFrame ( _In_ ULONG  Index) const
inline

Definition at line 142 of file smengine.h.

144 {
145 return m_Frames[Index];
146 }
_In_ WDFCOLLECTION _In_ ULONG Index

◆ SmHandled()

template<typename Machine , typename Event >
static SM_RESULT SmMachine< Machine, Event >::SmHandled ( )
inlinestaticprotected

Definition at line 182 of file smengine.h.

183 {
185 }
@ SmResultHandled
Definition: smengine.h:48

◆ SmInitialize()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmInitialize ( _In_ const State *  Initial)

Definition at line 349 of file smengine.h.

351{
352 NT_ASSERT(Initial->Entry == NULL);
353
355 m_Frames[0] = Initial;
356 m_Depth = 0;
357 m_Count = 0;
359 m_Paused = FALSE;
362 m_TraceIndex = 0;
364 RtlZeroMemory(m_Trace, sizeof(m_Trace));
366}
UCHAR m_TraceIndex
Definition: smengine.h:340
SM_TRACE m_Trace[SM_TRACE_DEPTH]
Definition: smengine.h:342
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define NT_ASSERT
Definition: rtlfuncs.h:3334

◆ SmIsIn()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::SmIsIn ( _In_ const State *  Ancestor) const

Definition at line 490 of file smengine.h.

492{
493 const State* walk;
494 ULONG frame;
495
496 for (frame = 0; frame <= m_Depth; frame++)
497 {
498 for (walk = m_Frames[frame]; walk != NULL; walk = walk->Parent)
499 {
500 if (walk == Ancestor)
501 return TRUE;
502 }
503 }
504
505 return FALSE;
506}

◆ SmIsPaused()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::SmIsPaused ( ) const
inline

Definition at line 153 of file smengine.h.

154 {
155 return m_Paused;
156 }

◆ SmIsWaitingForTimer()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::SmIsWaitingForTimer ( ) const
inline

Definition at line 159 of file smengine.h.

160 {
161 return m_WaitingForTimer;
162 }

◆ SmMakeResult()

◆ SmOnDequeue()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmOnDequeue ( _In_ Event  Ev)
inlineprotected

Definition at line 260 of file smengine.h.

262 {
264 }

◆ SmPaused()

template<typename Machine , typename Event >
static SM_RESULT SmMachine< Machine, Event >::SmPaused ( )
inlinestaticprotected

Definition at line 202 of file smengine.h.

203 {
205 }

◆ SmPost()

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::SmPost ( _In_ Event  Ev)

Definition at line 370 of file smengine.h.

372{
373 const SM_EVENT_INFO* info = &Machine::EventInfo[static_cast<ULONG>(Ev)];
374 const State* current;
376 KIRQL irql;
377
379
380 if (!Self()->SmAccepts(Ev) || (info->Coalesce && IsQueued(Ev)))
381 {
382 Trace(SmTraceRejected, static_cast<USHORT>(Ev));
384 return FALSE;
385 }
386
387 Trace(SmTracePosted, static_cast<USHORT>(Ev));
388
389 if (info->Replace && RemoveQueued(Ev))
390 {
392 Self()->SmOnDequeue(Ev);
394 }
395
396 if (info->Class == SmEventResume)
397 {
398 if (!m_Paused || !m_Running)
399 {
401 Trace(SmTraceUnhandled, static_cast<USHORT>(Ev));
403 SM_BREAK("Resume event posted to a machine that is not paused");
404 return TRUE;
405 }
406
407 /* The paused drainer already left, this thread takes over */
408 m_Paused = FALSE;
409 Trace(SmTraceResumed, static_cast<USHORT>(Ev));
411
412 Self()->SmReference();
413 result = Dispatch(Ev);
414 if (!Run(irql, static_cast<USHORT>(Ev), result, NULL))
415 Self()->SmDereference();
416 return TRUE;
417 }
418
420 {
421 /* The drainer stopped after entering a state, the entry runs once the timer is done */
422 if (static_cast<USHORT>(Ev) != Machine::SmTimerEventId)
423 {
424 NT_ASSERTMSG("State machine queue overflow", m_Count < SM_QUEUE_DEPTH);
425 m_Queue[m_Count] = Ev;
426 m_Count++;
428 return TRUE;
429 }
430
432 current = SmCurrent();
434
435 result = current->Entry ? (Self()->*current->Entry)() : SmHandled();
436 if (!Run(irql, static_cast<USHORT>(Ev), result, current))
437 Self()->SmDereference();
438 return TRUE;
439 }
440
441 NT_ASSERTMSG("State machine queue overflow", m_Count < SM_QUEUE_DEPTH);
442 m_Queue[m_Count] = Ev;
443 m_Count++;
444
445 if (m_Running)
446 {
448 return TRUE;
449 }
450
451 m_Running = TRUE;
453
454 Self()->SmReference();
455 if (!Run(irql, static_cast<USHORT>(Ev), SmHandled(), NULL))
456 Self()->SmDereference();
457 return TRUE;
458}
BOOLEAN SmAccepts(_In_ Event Ev)
Definition: smengine.h:236
BOOLEAN IsQueued(_In_ Event Ev) const
Definition: smengine.h:590
@ SmTraceRejected
Definition: smengine.h:66
@ SmTraceResumed
Definition: smengine.h:71
@ SmTracePosted
Definition: smengine.h:65
@ SmEventResume
Definition: smengine.h:26

◆ SmQueuePassive()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmQueuePassive ( )
inlineprotected

Definition at line 254 of file smengine.h.

255 {
256 SM_BREAK("State needs passive level but the machine has no work item");
257 }

◆ SmReference()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmReference ( )
inlineprotected

Definition at line 244 of file smengine.h.

245 {
246 }

◆ SmReturn()

template<typename Machine , typename Event >
static SM_RESULT SmMachine< Machine, Event >::SmReturn ( _In_ Event  Ev)
inlinestaticprotected

Definition at line 217 of file smengine.h.

219 {
220 return SmMakeResult(SmResultReturn, static_cast<USHORT>(Ev), NULL);
221 }

◆ SmStateChanged()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::SmStateChanged ( )
inlineprotected

Definition at line 267 of file smengine.h.

268 {
269 }

◆ SmTransition()

template<typename Machine , typename Event >
static SM_RESULT SmMachine< Machine, Event >::SmTransition ( _In_ const State *  Target)
inlinestaticprotected

Definition at line 194 of file smengine.h.

196 {
198 }

◆ SmUnexpectedCount()

template<typename Machine , typename Event >
ULONG SmMachine< Machine, Event >::SmUnexpectedCount ( ) const
inline

Definition at line 165 of file smengine.h.

166 {
167 return m_UnexpectedCount;
168 }

◆ SmUnhandled()

template<typename Machine , typename Event >
static SM_RESULT SmMachine< Machine, Event >::SmUnhandled ( )
inlinestaticprotected

Definition at line 188 of file smengine.h.

189 {
191 }

◆ Trace()

template<typename Machine , typename Event >
VOID SmMachine< Machine, Event >::Trace ( _In_ SM_TRACE_KIND  Kind,
_In_ USHORT  Ev 
)
private

Definition at line 706 of file smengine.h.

709{
711
712 entry->State = SmCurrent()->Name;
713 entry->Event = Ev;
714 entry->Kind = static_cast<UCHAR>(Kind);
715 entry->Depth = m_Depth;
717}
uint32_t entry
Definition: isohybrid.c:63
#define SM_TRACE_MASK
Definition: smengine.h:13
PCSTR Name
Definition: smengine.h:95

Member Data Documentation

◆ m_Count

template<typename Machine , typename Event >
UCHAR SmMachine< Machine, Event >::m_Count
private

Definition at line 335 of file smengine.h.

◆ m_Depth

template<typename Machine , typename Event >
UCHAR SmMachine< Machine, Event >::m_Depth
private

◆ m_Frames

template<typename Machine , typename Event >
const State* SmMachine< Machine, Event >::m_Frames[SM_MAX_DEPTH]
private

◆ m_Lock

template<typename Machine , typename Event >
KSPIN_LOCK SmMachine< Machine, Event >::m_Lock
private

Definition at line 331 of file smengine.h.

◆ m_Paused

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::m_Paused
private

Definition at line 337 of file smengine.h.

Referenced by SmMachine< Machine, Event >::SmIsPaused().

◆ m_Queue

template<typename Machine , typename Event >
Event SmMachine< Machine, Event >::m_Queue[SM_QUEUE_DEPTH]
private

Definition at line 333 of file smengine.h.

◆ m_Running

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::m_Running
private

Definition at line 336 of file smengine.h.

◆ m_Trace

template<typename Machine , typename Event >
SM_TRACE SmMachine< Machine, Event >::m_Trace[SM_TRACE_DEPTH]
private

Definition at line 342 of file smengine.h.

◆ m_TraceIndex

template<typename Machine , typename Event >
UCHAR SmMachine< Machine, Event >::m_TraceIndex
private

Definition at line 340 of file smengine.h.

◆ m_UnexpectedCount

template<typename Machine , typename Event >
ULONG SmMachine< Machine, Event >::m_UnexpectedCount
private

Definition at line 341 of file smengine.h.

Referenced by SmMachine< Machine, Event >::SmUnexpectedCount().

◆ m_WaitingForPassive

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::m_WaitingForPassive
private

Definition at line 338 of file smengine.h.

◆ m_WaitingForTimer

template<typename Machine , typename Event >
BOOLEAN SmMachine< Machine, Event >::m_WaitingForTimer
private

Definition at line 339 of file smengine.h.

Referenced by SmMachine< Machine, Event >::SmIsWaitingForTimer().

◆ SmCompletionsFirst

template<typename Machine , typename Event >
const BOOLEAN SmMachine< Machine, Event >::SmCompletionsFirst = TRUE
staticprotected

Definition at line 232 of file smengine.h.

◆ SmTimerEventId

template<typename Machine , typename Event >
const USHORT SmMachine< Machine, Event >::SmTimerEventId = SM_NO_EVENT
staticprotected

Definition at line 233 of file smengine.h.


The documentation for this class was generated from the following file: