event: Implement context switch monitor without a poller
This is much simpler and avoids the problems with requiring it to run on a thread. Change-Id: I811444c5a15d292356703beccc17e505d55d7678 Signed-off-by: Ben Walker <benjamin.walker@intel.com> Reviewed-on: https://review.gerrithub.io/c/443645 Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
3569ea154a
commit
86a21aee4e
@ -162,10 +162,11 @@ _spdk_event_queue_run_batch(struct spdk_reactor *reactor, struct spdk_thread *th
|
||||
return count;
|
||||
}
|
||||
|
||||
#define CONTEXT_SWITCH_MONITOR_PERIOD 1000000
|
||||
|
||||
static int
|
||||
get_rusage(void *arg)
|
||||
get_rusage(struct spdk_reactor *reactor)
|
||||
{
|
||||
struct spdk_reactor *reactor = arg;
|
||||
struct rusage rusage;
|
||||
|
||||
if (getrusage(RUSAGE_THREAD, &rusage) != 0) {
|
||||
@ -183,46 +184,14 @@ get_rusage(void *arg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_reactor_context_switch_monitor_start(void *arg1, void *arg2)
|
||||
{
|
||||
struct spdk_reactor *reactor = arg1;
|
||||
|
||||
if (reactor->rusage_poller == NULL) {
|
||||
getrusage(RUSAGE_THREAD, &reactor->rusage);
|
||||
reactor->rusage_poller = spdk_poller_register(get_rusage, reactor, 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_reactor_context_switch_monitor_stop(void *arg1, void *arg2)
|
||||
{
|
||||
struct spdk_reactor *reactor = arg1;
|
||||
|
||||
if (reactor->rusage_poller != NULL) {
|
||||
spdk_poller_unregister(&reactor->rusage_poller);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spdk_reactor_enable_context_switch_monitor(bool enable)
|
||||
{
|
||||
struct spdk_reactor *reactor;
|
||||
spdk_event_fn fn;
|
||||
uint32_t core;
|
||||
|
||||
if (enable != g_context_switch_monitor_enabled) {
|
||||
g_context_switch_monitor_enabled = enable;
|
||||
if (enable) {
|
||||
fn = _spdk_reactor_context_switch_monitor_start;
|
||||
} else {
|
||||
fn = _spdk_reactor_context_switch_monitor_stop;
|
||||
}
|
||||
SPDK_ENV_FOREACH_CORE(core) {
|
||||
reactor = spdk_reactor_get(core);
|
||||
spdk_event_call(spdk_event_allocate(core, fn, reactor, NULL));
|
||||
}
|
||||
}
|
||||
/* This global is being read by multiple threads, so this isn't
|
||||
* strictly thread safe. However, we're toggling between true and
|
||||
* false here, and if a thread sees the value update later than it
|
||||
* should, it's no big deal. */
|
||||
g_context_switch_monitor_enabled = enable;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -236,6 +205,7 @@ _spdk_reactor_run(void *arg)
|
||||
{
|
||||
struct spdk_reactor *reactor = arg;
|
||||
struct spdk_thread *thread;
|
||||
uint64_t last_rusage = 0;
|
||||
char thread_name[32];
|
||||
|
||||
snprintf(thread_name, sizeof(thread_name), "reactor_%u", reactor->lcore);
|
||||
@ -245,12 +215,6 @@ _spdk_reactor_run(void *arg)
|
||||
}
|
||||
SPDK_NOTICELOG("Reactor started on core %u\n", reactor->lcore);
|
||||
|
||||
if (g_context_switch_monitor_enabled) {
|
||||
spdk_set_thread(thread);
|
||||
_spdk_reactor_context_switch_monitor_start(reactor, NULL);
|
||||
spdk_set_thread(NULL);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
_spdk_event_queue_run_batch(reactor, thread);
|
||||
|
||||
@ -259,11 +223,17 @@ _spdk_reactor_run(void *arg)
|
||||
if (g_reactor_state != SPDK_REACTOR_STATE_RUNNING) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_context_switch_monitor_enabled) {
|
||||
uint64_t now = spdk_get_ticks();
|
||||
|
||||
if ((last_rusage + CONTEXT_SWITCH_MONITOR_PERIOD) < now) {
|
||||
get_rusage(reactor);
|
||||
last_rusage = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spdk_set_thread(thread);
|
||||
_spdk_reactor_context_switch_monitor_stop(reactor, NULL);
|
||||
spdk_thread_exit(thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user