Skip to content

Commit

Permalink
Added linux scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
danlapid committed Nov 30, 2022
1 parent 10bbcdb commit 4fbba52
Show file tree
Hide file tree
Showing 7 changed files with 459 additions and 12 deletions.
113 changes: 113 additions & 0 deletions include/cppcoro/detail/linux.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Microsoft
// Licenced under MIT license. See LICENSE.txt for details.
///////////////////////////////////////////////////////////////////////////////
#ifndef CPPCORO_DETAIL_LINUX_HPP_INCLUDED
#define CPPCORO_DETAIL_LINUX_HPP_INCLUDED

#include <fcntl.h>
#include <linux/limits.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <utility>

namespace cppcoro
{
namespace detail
{
namespace linux
{
using fd_t = int;

enum message_type
{
CALLBACK_TYPE,
RESUME_TYPE
};

class safe_fd
{
public:
safe_fd()
: m_fd(-1)
{
}

explicit safe_fd(fd_t fd)
: m_fd(fd)
{
}

safe_fd(const safe_fd& other) = delete;

safe_fd(safe_fd&& other) noexcept
: m_fd(other.m_fd)
{
other.m_fd = -1;
}

~safe_fd() { close(); }

safe_fd& operator=(safe_fd fd) noexcept
{
swap(fd);
return *this;
}

constexpr fd_t fd() const { return m_fd; }

/// Calls close() and sets the fd to -1.
void close() noexcept;

void swap(safe_fd& other) noexcept { std::swap(m_fd, other.m_fd); }

bool operator==(const safe_fd& other) const { return m_fd == other.m_fd; }

bool operator!=(const safe_fd& other) const { return m_fd != other.m_fd; }

bool operator==(fd_t fd) const { return m_fd == fd; }

bool operator!=(fd_t fd) const { return m_fd != fd; }

private:
fd_t m_fd;
};

struct message
{
enum message_type m_type;
void* m_ptr;
};

struct io_state : linux::message
{
using callback_type = void(io_state* state);
callback_type* m_callback;
};

class message_queue
{
private:
int m_pipefd[2];
safe_fd m_epollfd;
struct epoll_event m_ev;

public:
message_queue();
~message_queue();
bool enqueue_message(void* message, message_type type);
bool dequeue_message(void*& message, message_type& type, bool wait);
};

safe_fd create_event_fd();
safe_fd create_timer_fd();
safe_fd create_epoll_fd();
} // namespace linux
} // namespace detail
} // namespace cppcoro

#endif
5 changes: 5 additions & 0 deletions include/cppcoro/io_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#if CPPCORO_OS_WINNT
# include <cppcoro/detail/win32.hpp>
#elif CPPCORO_OS_LINUX
# include <cppcoro/detail/linux.hpp>
#endif

#include <optional>
Expand Down Expand Up @@ -172,6 +174,9 @@ namespace cppcoro

std::atomic<bool> m_winsockInitialised;
std::mutex m_winsockInitialisationMutex;

#elif CPPCORO_OS_LINUX
detail::linux::message_queue m_mq;
#endif

// Head of a linked-list of schedule operations that are
Expand Down
3 changes: 2 additions & 1 deletion include/cppcoro/resume_on.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,12 @@ namespace cppcoro
template<typename SCHEDULER, typename T>
async_generator<T> resume_on(SCHEDULER& scheduler, async_generator<T> source)
{
for (auto iter = co_await source.begin(); iter != source.end(); co_await ++iter)
for (detail::async_generator_iterator<T> iter = co_await source.begin(); iter != source.end();)
{
auto& value = *iter;
co_await scheduler.schedule();
co_yield value;
co_await ++iter; // moved due to error: insufficient contextual information to determine type on old compilers
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ if(WIN32)
# TODO remove this when experimental/non-experimental include are fixed
list(APPEND compile_definition _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING=1)
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(linuxDetailIncludes
linux.hpp
)
list(TRANSFORM linuxDetailIncludes PREPEND "${PROJECT_SOURCE_DIR}/include/cppcoro/detail/")
list(APPEND detailIncludes ${linuxDetailIncludes})

list(APPEND sources
linux.cpp
io_service.cpp
)
endif()

add_library(cppcoro
Expand Down
Loading

0 comments on commit 4fbba52

Please sign in to comment.