Skip to content

Commit 76b6d7f

Browse files
committed
fix scheduler bug in simulator.
1 parent c924330 commit 76b6d7f

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

libcpu/sim/win32/cpu_port.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
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);

libcpu/sim/win32/cpu_port.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
* CPU INTERRUPT PRIORITY
1818
*********************************************************************************************************
1919
*/
20-
#define CPU_INTERRUPT_YIELD 0x00
21-
#define CPU_INTERRUPT_TICK 0x01
20+
#define CPU_INTERRUPT_YIELD 0x01 // should be set to the lowest priority.
21+
#define CPU_INTERRUPT_TICK 0x00
2222

2323

2424

0 commit comments

Comments
 (0)