-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMonitor.cpp
More file actions
57 lines (51 loc) · 1.33 KB
/
Copy pathMonitor.cpp
File metadata and controls
57 lines (51 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "Monitor.h"
#include "Thread.h"
extern "C" void __stdcall force_yield(Thread* t);
Monitor::Monitor(Scheduler* scheduler, DWORD thread_id) :
scheduler_(scheduler), thread_(OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT, FALSE, thread_id))
{
}
Monitor::~Monitor()
{
enable_ = false;
WaitForSingleObject(thread_, INFINITE);
CloseHandle(thread_);
}
void Monitor::Start()
{
enable_ = true;
union
{
LPTHREAD_START_ROUTINE r;
decltype(&Monitor::MonitorThread) p;
} u;
u.p = &Monitor::MonitorThread;
CloseHandle(CreateThread(nullptr, 0, u.r, this, 0, nullptr));
}
void __stdcall Monitor::MonitorThread()
{
std::uint32_t count = 0;
while (enable_)
{
Sleep(100);
if (scheduler_->status == ThreadStatus::READY && scheduler_->switch_count_ == count)
{
SuspendThread(thread_);
if (scheduler_->status == ThreadStatus::READY && scheduler_->switch_count_ == count)
{
auto current = scheduler_->next;
CONTEXT context = { CONTEXT_CONTROL };
GetThreadContext(thread_, &context);
auto esp = (std::uint32_t*)context.Esp;
*--esp = (std::uint32_t)current;
*--esp = context.Eip;
context.Esp = (DWORD)esp;
context.Eip = (DWORD)&force_yield;
context.ContextFlags = CONTEXT_CONTROL;
SetThreadContext(thread_, &context);
}
ResumeThread(thread_);
}
count = scheduler_->switch_count_;
}
}