Kernel: Use HashMap for fd->epoll_event mapping
I don't know why it was a static array :D
This commit is contained in:
@@ -1,12 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <BAN/Array.h>
|
|
||||||
#include <BAN/CircularQueue.h>
|
|
||||||
#include <BAN/HashMap.h>
|
#include <BAN/HashMap.h>
|
||||||
#include <BAN/HashSet.h>
|
|
||||||
#include <kernel/FS/Inode.h>
|
#include <kernel/FS/Inode.h>
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
@@ -63,38 +59,41 @@ namespace Kernel
|
|||||||
|
|
||||||
struct ListenEventList
|
struct ListenEventList
|
||||||
{
|
{
|
||||||
BAN::Array<epoll_event, OPEN_MAX> events;
|
ListenEventList() = default;
|
||||||
uint32_t bitmap[(OPEN_MAX + 31) / 32] {};
|
|
||||||
|
ListenEventList(const ListenEventList&) = delete;
|
||||||
|
ListenEventList& operator=(const ListenEventList&) = delete;
|
||||||
|
|
||||||
|
ListenEventList(ListenEventList&& other)
|
||||||
|
: events(BAN::move(other.events))
|
||||||
|
{}
|
||||||
|
ListenEventList& operator=(ListenEventList&& other)
|
||||||
|
{
|
||||||
|
events = BAN::move(other.events);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::HashMap<int, epoll_event> events;
|
||||||
|
|
||||||
bool has_fd(int fd) const
|
bool has_fd(int fd) const
|
||||||
{
|
{
|
||||||
// For some reason having (fd < 0 || ...) makes GCC 15.1.0
|
return events.contains(fd);
|
||||||
// think bitmap access can be out of bounds...
|
|
||||||
if (static_cast<size_t>(fd) >= events.size())
|
|
||||||
return false;
|
|
||||||
return bitmap[fd / 32] & (1u << (fd % 32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const
|
bool empty() const
|
||||||
{
|
{
|
||||||
for (auto val : bitmap)
|
return events.empty();
|
||||||
if (val != 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_fd(int fd, epoll_event event)
|
BAN::ErrorOr<void> add_fd(int fd, epoll_event event)
|
||||||
{
|
{
|
||||||
ASSERT(!has_fd(fd));
|
TRY(events.insert(fd, event));
|
||||||
bitmap[fd / 32] |= (1u << (fd % 32));
|
return {};
|
||||||
events[fd] = event;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_fd(int fd)
|
void remove_fd(int fd)
|
||||||
{
|
{
|
||||||
ASSERT(has_fd(fd));
|
events.remove(fd);
|
||||||
bitmap[fd / 32] &= ~(1u << (fd % 32));
|
|
||||||
events[fd] = {};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Kernel
|
|||||||
|
|
||||||
Epoll::~Epoll()
|
Epoll::~Epoll()
|
||||||
{
|
{
|
||||||
for (auto [inode, _] : m_listening_events)
|
for (auto& [inode, _] : m_listening_events)
|
||||||
inode->del_epoll(this);
|
inode->del_epoll(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ namespace Kernel
|
|||||||
|
|
||||||
if (!contains_inode)
|
if (!contains_inode)
|
||||||
TRY(inode->add_epoll(this));
|
TRY(inode->add_epoll(this));
|
||||||
it->value.add_fd(fd, event);
|
TRY(it->value.add_fd(fd, event));
|
||||||
|
|
||||||
SpinLockGuard _(m_ready_lock);
|
SpinLockGuard _(m_ready_lock);
|
||||||
auto ready_it = m_ready_events.find(inode);
|
auto ready_it = m_ready_events.find(inode);
|
||||||
@@ -144,9 +144,8 @@ namespace Kernel
|
|||||||
|
|
||||||
{
|
{
|
||||||
uint32_t listen_mask = EPOLLHUP | EPOLLERR;
|
uint32_t listen_mask = EPOLLHUP | EPOLLERR;
|
||||||
for (size_t fd = 0; fd < listen.events.size(); fd++)
|
for (const auto& [_, events] : listen.events)
|
||||||
if (listen.has_fd(fd))
|
listen_mask |= events.events;
|
||||||
listen_mask |= listen.events[fd].events;
|
|
||||||
events &= listen_mask;
|
events &= listen_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,11 +170,10 @@ namespace Kernel
|
|||||||
|
|
||||||
#undef REMOVE_IT
|
#undef REMOVE_IT
|
||||||
|
|
||||||
for (size_t fd = 0; fd < listen.events.size() && event_count < event_span.size(); fd++)
|
for (auto& [_, listen_event] : listen.events)
|
||||||
{
|
{
|
||||||
if (!listen.has_fd(fd))
|
if (event_count >= event_span.size())
|
||||||
continue;
|
break;
|
||||||
auto& listen_event = listen.events[fd];
|
|
||||||
|
|
||||||
const auto new_events = (listen_event.events | EPOLLHUP | EPOLLERR) & events;
|
const auto new_events = (listen_event.events | EPOLLHUP | EPOLLERR) & events;
|
||||||
if (new_events == 0)
|
if (new_events == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user