2727* The context switch is managed by the threads.So the task stack does not have to be managed directly,
2828* although the stack stack is still used to hold an WinThreadState structure this is the only thing it
2929* will be ever hold.
30+ * YieldEvent used to make sure the thread does not execute before asynchronous SuspendThread() operation
31+ * actually being performed.
3032* the structure indirectly maps the task handle to a thread handle
3133*********************************************************************************************************
3234*/
@@ -35,6 +37,7 @@ typedef struct
3537 void * Param ; //Thread param
3638 void (* Entry )(void * ); //Thread entry
3739 void (* Exit )(void ); //Thread exit
40+ HANDLE YieldEvent ;
3841 HANDLE ThreadHandle ;
3942 DWORD ThreadID ;
4043}win_thread_t ;
@@ -171,6 +174,11 @@ rt_uint8_t* rt_hw_stack_init(void *pEntry,void *pParam,rt_uint8_t *pStackAddr,vo
171174 pWinThread -> ThreadHandle = NULL ;
172175 pWinThread -> ThreadID = 0 ;
173176
177+ pWinThread -> YieldEvent = CreateEvent (NULL ,
178+ FALSE,
179+ FALSE,
180+ NULL );
181+
174182 /* Create the winthread */
175183 pWinThread -> ThreadHandle = CreateThread (NULL ,
176184 0 ,
@@ -277,6 +285,19 @@ void rt_hw_context_switch(rt_uint32_t from,
277285 //trigger YIELD exception(cause contex switch)
278286 TriggerSimulateInterrupt (CPU_INTERRUPT_YIELD );
279287
288+ // make sure the event is not already signaled
289+ WinThread = (win_thread_t * )rt_interrupt_from_thread ;
290+ ResetEvent (WinThread -> YieldEvent );
291+
292+ /*
293+ * enable interrupt in advance so that scheduler can be executed.please note that interrupt
294+ * maybe disable twice before.
295+ */
296+ rt_hw_interrupt_enable (0 );
297+ rt_hw_interrupt_enable (0 );
298+
299+ // wait to suspend.
300+ WaitForSingleObject (WinThread -> YieldEvent , INFINITE );
280301} /*** rt_hw_context_switch ***/
281302
282303/*
@@ -578,6 +599,7 @@ void RegisterSimulateInterrupt(rt_uint32_t IntIndex,rt_uint32_t (*IntHandler)(vo
578599 if ((WinThreadFrom != NULL ) && (WinThreadFrom -> ThreadHandle != NULL ))
579600 {
580601 SuspendThread (WinThreadFrom -> ThreadHandle );
602+ SetEvent (WinThreadFrom -> YieldEvent );
581603 }
582604
583605 ResumeThread (WinThreadTo -> ThreadHandle );
0 commit comments