Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
41bc17a2
Commit
41bc17a2
authored
4 years ago
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event/SocketMonitor: add `ready_flags`
By making each SocketMonitor keep track of its ready flags, this removes a lot of overhead from EventLoop::RemoveFD().
parent
41c0bbab
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
55 additions
and
44 deletions
+55
-44
Loop.cxx
src/event/Loop.cxx
+15
-16
Loop.hxx
src/event/Loop.hxx
+15
-3
PollGroupEpoll.hxx
src/event/PollGroupEpoll.hxx
+0
-10
PollResultGeneric.hxx
src/event/PollResultGeneric.hxx
+0
-10
SocketMonitor.cxx
src/event/SocketMonitor.cxx
+4
-3
SocketMonitor.hxx
src/event/SocketMonitor.hxx
+21
-2
No files found.
src/event/Loop.cxx
View file @
41bc17a2
...
...
@@ -87,20 +87,18 @@ EventLoop::Break() noexcept
}
bool
EventLoop
::
Abandon
(
int
_fd
,
SocketMonitor
&
m
)
noexcept
EventLoop
::
Abandon
(
int
_fd
)
noexcept
{
assert
(
!
IsAlive
()
||
IsInside
());
poll_result
.
Clear
(
&
m
);
return
poll_group
.
Abandon
(
_fd
);
}
bool
EventLoop
::
RemoveFD
(
int
_fd
,
SocketMonitor
&
m
)
noexcept
EventLoop
::
RemoveFD
(
int
_fd
)
noexcept
{
assert
(
!
IsAlive
()
||
IsInside
());
poll_result
.
Clear
(
&
m
);
return
poll_group
.
Remove
(
_fd
);
}
...
...
@@ -230,8 +228,16 @@ EventLoop::Run() noexcept
/* wait for new event */
PollResult
poll_result
;
poll_group
.
ReadEvents
(
poll_result
,
ExportTimeoutMS
(
timeout
));
ready_sockets
.
clear
();
for
(
size_t
i
=
0
;
i
<
poll_result
.
GetSize
();
++
i
)
{
auto
&
sm
=
*
(
SocketMonitor
*
)
poll_result
.
GetObject
(
i
);
sm
.
SetReadyFlags
(
poll_result
.
GetEvents
(
i
));
ready_sockets
.
push_back
(
sm
);
}
now
=
std
::
chrono
::
steady_clock
::
now
();
{
...
...
@@ -240,19 +246,12 @@ EventLoop::Run() noexcept
}
/* invoke sockets */
for
(
size_t
i
=
0
;
i
<
poll_result
.
GetSize
();
++
i
)
{
auto
events
=
poll_result
.
GetEvents
(
i
);
if
(
events
!=
0
)
{
if
(
quit
)
break
;
auto
m
=
(
SocketMonitor
*
)
poll_result
.
GetObject
(
i
);
m
->
Dispatch
(
events
);
}
}
poll_result
.
Reset
();
while
(
!
ready_sockets
.
empty
()
&&
!
quit
)
{
auto
&
sm
=
ready_sockets
.
front
();
ready_sockets
.
pop_front
();
sm
.
Dispatch
();
}
}
while
(
!
quit
);
#ifndef NDEBUG
...
...
This diff is collapsed.
Click to expand it.
src/event/Loop.hxx
View file @
41bc17a2
...
...
@@ -88,6 +88,19 @@ class EventLoop final : SocketMonitor
boost
::
intrusive
::
constant_time_size
<
false
>>
;
DeferredList
deferred
;
using
ReadySocketList
=
boost
::
intrusive
::
list
<
SocketMonitor
,
boost
::
intrusive
::
member_hook
<
SocketMonitor
,
SocketMonitor
::
ReadyListHook
,
&
SocketMonitor
::
ready_siblings
>
,
boost
::
intrusive
::
constant_time_size
<
false
>>
;
/**
* A linked list of #SocketMonitor instances which have a
* non-zero "ready_flags" field, and need to be dispatched.
*/
ReadySocketList
ready_sockets
;
#ifdef HAVE_URING
std
::
unique_ptr
<
Uring
::
Manager
>
uring
;
#endif
...
...
@@ -123,7 +136,6 @@ class EventLoop final : SocketMonitor
#endif
PollGroup
poll_group
;
PollResult
poll_result
;
/**
* A reference to the thread that is currently inside Run().
...
...
@@ -178,9 +190,9 @@ public:
* has been closed. This is like RemoveFD(), but does not
* attempt to use #EPOLL_CTL_DEL.
*/
bool
Abandon
(
int
fd
,
SocketMonitor
&
m
)
noexcept
;
bool
Abandon
(
int
fd
)
noexcept
;
bool
RemoveFD
(
int
fd
,
SocketMonitor
&
m
)
noexcept
;
bool
RemoveFD
(
int
fd
)
noexcept
;
void
AddIdle
(
IdleMonitor
&
i
)
noexcept
;
void
RemoveIdle
(
IdleMonitor
&
i
)
noexcept
;
...
...
This diff is collapsed.
Click to expand it.
src/event/PollGroupEpoll.hxx
View file @
41bc17a2
...
...
@@ -45,16 +45,6 @@ public:
void
*
GetObject
(
size_t
i
)
const
noexcept
{
return
events
[
i
].
data
.
ptr
;
}
void
Reset
()
noexcept
{
n_events
=
0
;
}
void
Clear
(
void
*
obj
)
noexcept
{
for
(
size_t
i
=
0
;
i
<
n_events
;
++
i
)
if
(
events
[
i
].
data
.
ptr
==
obj
)
events
[
i
].
events
=
0
;
}
};
class
PollGroupEpoll
...
...
This diff is collapsed.
Click to expand it.
src/event/PollResultGeneric.hxx
View file @
41bc17a2
...
...
@@ -57,16 +57,6 @@ public:
return
items
[
i
].
obj
;
}
void
Reset
()
noexcept
{
items
.
clear
();
}
void
Clear
(
void
*
obj
)
noexcept
{
for
(
auto
i
=
items
.
begin
();
i
!=
items
.
end
();
++
i
)
if
(
i
->
obj
==
obj
)
i
->
events
=
0
;
}
void
Add
(
unsigned
events
,
void
*
obj
)
noexcept
{
items
.
emplace_back
(
events
,
obj
);
}
...
...
This diff is collapsed.
Click to expand it.
src/event/SocketMonitor.cxx
View file @
41bc17a2
...
...
@@ -28,9 +28,10 @@
#endif
void
SocketMonitor
::
Dispatch
(
unsigned
flags
)
noexcept
SocketMonitor
::
Dispatch
()
noexcept
{
flags
&=
GetScheduledFlags
()
|
IMPLICIT_FLAGS
;
const
unsigned
flags
=
std
::
exchange
(
ready_flags
,
0
)
&
(
GetScheduledFlags
()
|
IMPLICIT_FLAGS
);
if
(
flags
!=
0
)
OnSocketReady
(
flags
);
...
...
@@ -79,7 +80,7 @@ SocketMonitor::Schedule(unsigned flags) noexcept
if
(
scheduled_flags
==
0
)
success
=
loop
.
AddFD
(
fd
.
Get
(),
flags
,
*
this
);
else
if
(
flags
==
0
)
success
=
loop
.
RemoveFD
(
fd
.
Get
()
,
*
this
);
success
=
loop
.
RemoveFD
(
fd
.
Get
());
else
success
=
loop
.
ModifyFD
(
fd
.
Get
(),
flags
,
*
this
);
...
...
This diff is collapsed.
Click to expand it.
src/event/SocketMonitor.hxx
View file @
41bc17a2
...
...
@@ -23,6 +23,8 @@
#include "PollGroup.hxx"
#include "net/SocketDescriptor.hxx"
#include <boost/intrusive/list_hook.hpp>
#include <cassert>
#include <cstddef>
#include <type_traits>
...
...
@@ -43,14 +45,27 @@ class EventLoop;
* as thread-safe.
*/
class
SocketMonitor
{
friend
class
EventLoop
;
using
ReadyListHook
=
boost
::
intrusive
::
list_member_hook
<
boost
::
intrusive
::
link_mode
<
boost
::
intrusive
::
auto_unlink
>>
;
ReadyListHook
ready_siblings
;
SocketDescriptor
fd
=
SocketDescriptor
::
Undefined
();
EventLoop
&
loop
;
/**
* A bit mask of events that is currently registered in the EventLoop.
* A bit mask of events that is currently registered in the
* #EventLoop.
*/
unsigned
scheduled_flags
=
0
;
/**
* A bit mask of events which have been reported as "ready" by
* epoll_wait(). If non-zero, then the #EventLoop will call
* Dispatch() soon.
*/
unsigned
ready_flags
=
0
;
public
:
static
constexpr
unsigned
READ
=
PollGroup
::
READ
;
static
constexpr
unsigned
WRITE
=
PollGroup
::
WRITE
;
...
...
@@ -103,6 +118,10 @@ public:
return
scheduled_flags
;
}
void
SetReadyFlags
(
unsigned
flags
)
noexcept
{
ready_flags
=
flags
;
}
/**
* @return true on success, false on error (with errno set if
* USE_EPOLL is defined)
...
...
@@ -136,7 +155,7 @@ protected:
virtual
bool
OnSocketReady
(
unsigned
flags
)
noexcept
=
0
;
public
:
void
Dispatch
(
unsigned
flags
)
noexcept
;
void
Dispatch
()
noexcept
;
};
#endif
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment