Skip to content

Commit

Permalink
Fixed not scanning registers on Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
shin1m committed Aug 26, 2023
1 parent b11c626 commit 83c3f09
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 50 deletions.
20 changes: 16 additions & 4 deletions include/xemmai/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,19 @@ class t_engine
while (sem_wait(&v_epoch__received) == -1) if (errno != EINTR) throw std::system_error(errno, std::generic_category());
}
#endif
void f_epoch_increment(t_object**& a_p0, t_object**& a_p1, t_object** a_q1, t_object**& a_decrements)
{
for (; a_p1 < a_q1; ++a_p1) {
auto p = *a_p0++;
auto q = *a_p1;
if (p == q) continue;
p = f_object__find(p);
if (p == q) continue;
if (p) p->f_increment();
if (q) *a_decrements++ = q;
*a_p1 = p;
}
}
void f_collector();
void f_debug_stop_and_wait(std::unique_lock<std::mutex>& a_lock);
void f_debug_enter_and_notify()
Expand Down Expand Up @@ -321,10 +334,9 @@ inline void t_thread::t_internal::f_epoch_suspend()
#endif
#ifdef _WIN32
SuspendThread(v_handle);
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(v_handle, &context);
auto sp = reinterpret_cast<t_object**>(context.Rsp);
v_context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
GetThreadContext(v_handle, &v_context);
auto sp = reinterpret_cast<t_object**>(v_context.Rsp);
MEMORY_BASIC_INFORMATION mbi;
for (auto p = sp;;) {
VirtualQuery(p, &mbi, sizeof(mbi));
Expand Down
7 changes: 5 additions & 2 deletions include/xemmai/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ class t_object
friend class t_engine;
friend class t_with_lock_for_read;
friend class t_with_lock_for_write;
#ifdef _WIN32
friend struct t_thread;

static inline XEMMAI__PORTABLE__THREAD struct t_roots
#else

static inline XEMMAI__PORTABLE__THREAD struct
#ifdef _WIN32
t_roots
#endif
{
t_object* v_next;
Expand Down
2 changes: 2 additions & 0 deletions include/xemmai/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ struct t_thread
#endif
#ifdef _WIN32
HANDLE v_handle = NULL;
CONTEXT v_context_last{};
CONTEXT v_context;
#endif
t_object* volatile* v_reviving = nullptr;

Expand Down
10 changes: 1 addition & 9 deletions include/xemmai/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,17 @@ class t_slot
static inline XEMMAI__PORTABLE__THREAD t_object* volatile* v_next;

#ifdef _WIN32
static void f__push(t_object* a_object)
void f__push(t_object* a_object)
#else
XEMMAI__PORTABLE__ALWAYS_INLINE static void f_push(t_object* a_object)
#endif
{
#ifdef _WIN32
auto p = v_instance->v_head;
#else
auto p = v_head;
#endif
*p = a_object;
if (p == v_next)
v_instance->f_next();
else
#ifdef _WIN32
[[likely]] v_instance->v_head = p + 1;
#else
[[likely]] v_head = p + 1;
#endif
}

t_object* volatile v_objects[V_SIZE];
Expand Down
4 changes: 2 additions & 2 deletions src/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,12 @@ void t_engine::f_debug_continue(t_thread* a_stepping)
#ifdef _WIN32
void t_slot::t_increments::f_push(t_object* a_object)
{
f__push(a_object);
v_instance->f__push(a_object);
}

void t_slot::t_decrements::f_push(t_object* a_object)
{
f__push(a_object);
v_instance->f__push(a_object);
}

t_object* t_engine::f_allocate(size_t a_size)
Expand Down
45 changes: 12 additions & 33 deletions src/fiber.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,57 +81,36 @@ void t_fiber::t_internal::f_epoch_copy()

void t_fiber::t_internal::f_epoch_scan()
{
auto m = v_estack_used - v_estack.get();
auto used0 = v_estack_buffer.get() + m;
auto used1 = v_estack_last_head + m;
auto used1 = v_estack_last_head + (v_estack_used - v_estack.get());
auto used2 = v_estack_last_used;
v_estack_last_used = used1;
v_estack_decrements = v_estack_buffer.get();
auto n = v_stack_bottom - v_stack_top;
auto top0 = v_stack_copy - n;
auto top1 = v_stack_last_bottom - n;
auto top2 = v_stack_last_top;
v_stack_last_top = top1;
v_stack_decrements = v_stack_last_bottom;
std::lock_guard lock(f_engine()->v_object__heap.f_mutex());
auto p0 = v_estack_buffer.get();
auto p0 = v_estack_decrements = v_estack_buffer.get();
auto p1 = v_estack_last_head;
for (auto used = std::min(used1, used2); p1 < used; ++p1) {
auto p = *p0++;
auto q = *p1;
if (p == q) continue;
p = f_engine()->f_object__find(p);
if (p == q) continue;
if (p) p->f_increment();
if (q) *v_estack_decrements++ = q;
*p1 = p;
}
if (used1 > used2)
f_engine()->f_epoch_increment(p0, p1, std::min(used1, used2), v_estack_decrements);
auto increment = [&](auto& p0, auto& p1, auto p2)
{
do {
auto p = f_engine()->f_object__find(*p0++);
if (p) p->f_increment();
*p1++ = p;
} while (p1 < used1);
} while (p1 < p2);
};
if (used1 > used2)
increment(p0, p1, used1);
else
for (; p1 < used2; ++p1) if (*p1) *v_estack_decrements++ = *p1;
v_stack_decrements = v_stack_last_bottom;
if (top1 < top2)
do {
auto p = f_engine()->f_object__find(*top0++);
if (p) p->f_increment();
*top1++ = p;
} while (top1 < top2);
increment(top0, top1, top2);
else
for (; top2 < top1; ++top2) if (*top2) *v_stack_decrements++ = *top2;
for (; top0 < v_stack_copy; ++top1) {
auto p = *top0++;
auto q = *top1;
if (p == q) continue;
p = f_engine()->f_object__find(p);
if (p == q) continue;
if (p) p->f_increment();
if (q) *v_stack_decrements++ = q;
*top1 = p;
}
f_engine()->f_epoch_increment(top0, top1, v_stack_last_bottom, v_stack_decrements);
}

void t_fiber::t_internal::f_epoch_decrement()
Expand Down
15 changes: 15 additions & 0 deletions src/thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,24 @@ void t_thread::t_internal::f_epoch()
if (v_done > 0) {
++v_done;
for (auto p = v_fibers; p; p = p->v_next) p->f_epoch_copy();
#ifdef _WIN32
v_context = {};
#endif
} else {
f_epoch_suspend();
for (auto p = v_fibers; p; p = p->v_next) p->f_epoch_copy();
f_epoch_resume();
}
for (auto p = v_fibers; p; p = p->v_next) p->f_epoch_scan();
#ifdef _WIN32
auto decrements = reinterpret_cast<t_object**>(&v_context);
{
std::lock_guard lock(f_engine()->v_object__heap.f_mutex());
auto p0 = decrements;
auto p1 = reinterpret_cast<t_object**>(&v_context_last);
f_engine()->f_epoch_increment(p0, p1, reinterpret_cast<t_object**>(&v_context_last + 1), decrements);
}
#endif
v_increments.f_flush();
for (auto p = &v_fibers; *p;) {
auto q = *p;
Expand All @@ -54,6 +66,9 @@ void t_thread::t_internal::f_epoch()
delete q;
}
}
#ifdef _WIN32
for (auto p = reinterpret_cast<t_object**>(&v_context); p != decrements; ++p) (*p)->f_decrement();
#endif
v_decrements.f_flush();
}

Expand Down

0 comments on commit 83c3f09

Please sign in to comment.