fcontext can't work in mips64
pkngpkng opened this issue · 3 comments
pkngpkng commented
- source
#include <boost/fiber/all.hpp>
#include <chrono>
#include <functional>
#include <memory>
#include <thread>
class ThreadExecutor {
public:
ThreadExecutor()
: m_channel(std::make_unique<
boost::fibers::buffered_channel<std::function<void()>>>(
s_stackMaxCount)) {
std::promise<void> result;
m_thread = std::make_unique<std::thread>([this, &result] {
auto allocator = boost::fibers::pooled_fixedsize_stack(s_stackSize);
result.set_value();
std::function<void()> task;
while (boost::fibers::channel_op_status::closed != m_channel->pop(task)) {
--m_count;
boost::fibers::fiber{
std::allocator_arg, allocator,
[task = std::move(task), stackSize = s_stackSize]() { task(); }}
.detach();
}
});
result.get_future().get();
}
~ThreadExecutor() noexcept {
if (!m_channel->is_closed()) {
m_channel->close();
}
if (m_thread->joinable()) {
m_thread->join();
}
}
void Stop() {
if (!m_channel->is_closed()) {
m_channel->close();
}
}
void Join() {
if (m_thread->joinable()) {
m_thread->join();
}
}
void PostTask(const std::function<void()> &task) {
const auto ret = m_channel->try_push(task);
switch (ret) {
case boost::fibers::channel_op_status::success:
/* likely path */
++m_count;
break;
case boost::fibers::channel_op_status::full:
break;
case boost::fibers::channel_op_status::closed:
break;
default:
return;
}
return;
}
private:
const size_t s_stackSize = 256 * 1024;
const size_t s_stackMaxCount = 1024;
std::unique_ptr<boost::fibers::buffered_channel<std::function<void()>>>
m_channel;
std::atomic_int m_count;
std::unique_ptr<std::thread> m_thread;
};
int main() {
ThreadExecutor executor;
std::promise<void> p1;
std::promise<void> p2;
printf("fiber task post \r\n");
executor.PostTask([&] {
printf("fiber task1 start \r\n");
boost::fibers::promise<void> promise;
std::thread t([&] {
printf("std thread1 task start \r\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
printf("std thread1 task stop \r\n");
promise.set_value();
});
printf("fiber task1 sleep \r\n");
promise.get_future().get();
printf("fiber task1 stop \r\n");
p1.set_value();
});
executor.PostTask([&] {
printf("fiber task2 start \r\n");
boost::fibers::promise<void> promise;
std::thread t([&] {
printf("std thread task2 start \r\n");
std::this_thread::sleep_for(std::chrono::seconds(5));
printf("std thread task2 stop \r\n");
promise.set_value();
});
printf("fiber task2 sleep \r\n");
promise.get_future().get();
printf("fiber task2 stop \r\n");
p2.set_value();
});
p1.get_future().get();
p2.get_future().get();
return 0;
}
- result
root@debian-mips64el:~# ./test_fiber
fiber task post
fiber task1 start
std thread1 task start
fiber task1 sleep
fiber task2 start
fiber task2 sleep
[ 3716.428377] do_page_fault(): sending SIGSEGV to test_fiber for invalid read access from 0000000000000010
[ 3716.436963] epc = 0000000000000011 in test_fiber[aaab270000+51000]
[ 3716.439123] ra = 0000000000000011 in test_fiber[aaab270000+51000]
std thread task2 start
Segmentation fault
It will crash at promise.get_future().get();
returns;
olk commented
MIPS64 support was provided by other developers - I do not have access to this platform.
It would be nice if you could provide a fix via pull-request.
olk commented
should work now, see regression tests for mips64el on buster