Skip to content

Commit c89cbee

Browse files
potatosaladsverker
authored andcommitted
[erts] Scheduler pollset migration only when single process enif_select
1 parent 3431636 commit c89cbee

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

erts/emulator/sys/common/erl_check_io.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ typedef struct {
200200
EventStateFlags flags;
201201
int count; /* Number of times this fd has triggered
202202
without being deselected. */
203+
Eterm last_select_pid; /* Last process that called enif_select */
203204
} ErtsDrvEventState;
204205

205206
struct drv_ev_state_shared {
@@ -290,6 +291,7 @@ static ERTS_INLINE int grow_drv_ev_state(ErtsSysFdType fd) {
290291
sizeof(ErtsDrvEventState) * (new_len - old_len));
291292
for (i = old_len; i < new_len; i++) {
292293
drv_ev_state.v[i].fd = (ErtsSysFdType) i;
294+
drv_ev_state.v[i].last_select_pid = NIL;
293295
}
294296
erts_atomic_set_nob(&drv_ev_state.len, new_len);
295297
for (i=0; i<ERTS_CHECK_IO_DRV_EV_STATE_LOCK_CNT; i++) {
@@ -333,6 +335,8 @@ static ERTS_INLINE ErtsDrvEventState* new_drv_ev_state(ErtsDrvEventState *state,
333335
tmpl.active_events = 0;
334336
tmpl.type = ERTS_EV_TYPE_NONE;
335337
tmpl.flags = 0;
338+
tmpl.count = 0;
339+
tmpl.last_select_pid = NIL;
336340

337341
return (ErtsDrvEventState *) safe_hash_put(&drv_ev_state.tab, (void *) &tmpl);
338342
}
@@ -922,6 +926,7 @@ deselect(ErtsDrvEventState *state, int mode)
922926
state->type = ERTS_EV_TYPE_NONE;
923927
state->flags = ERTS_EV_FLAG_CLEAR;
924928
state->count = 0;
929+
state->last_select_pid = NIL;
925930
} else {
926931
ErtsPollEvents new_events =
927932
erts_io_control(state, ERTS_POLL_OP_MOD, state->active_events);
@@ -1248,6 +1253,7 @@ enif_select_x(ErlNifEnv* env,
12481253
ErtsDrvSelectDataState *free_select = NULL;
12491254
ErtsNifSelectDataState *free_nif = NULL;
12501255
ErtsPollEvents new_events = 0;
1256+
const Eterm recipient = pid ? pid->pid : env->proc->common.id;
12511257
#ifdef DEBUG_PRINT_MODE
12521258
char tmp_buff[255];
12531259
#endif
@@ -1340,15 +1346,24 @@ enif_select_x(ErlNifEnv* env,
13401346
old_events = state->events;
13411347

13421348
if (on) {
1349+
ASSERT(is_internal_pid(recipient));
1350+
13431351
if (state->type == ERTS_EV_TYPE_NONE)
13441352
ctl_op = ERTS_POLL_OP_ADD;
13451353
#if ERTS_POLL_USE_SCHEDULER_POLLING
1346-
else {
1347-
if (!(state->flags & ERTS_EV_FLAG_SCHEDULER) &&
1348-
!(state->flags & ERTS_EV_FLAG_FALLBACK) &&
1349-
(ctl_events & ERTS_POLL_EV_IN)) {
1350-
if (erts_sched_poll_enabled() && (state->flags & ERTS_EV_FLAG_NIF_SELECT) &&
1351-
state->count++ > 10) {
1354+
else if (ctl_events & ERTS_POLL_EV_IN) {
1355+
if ((state->flags & (ERTS_EV_FLAG_SCHEDULER |
1356+
ERTS_EV_FLAG_FALLBACK |
1357+
ERTS_EV_FLAG_NIF_SELECT)) == ERTS_EV_FLAG_NIF_SELECT
1358+
&& erts_sched_poll_enabled()) {
1359+
/* Check if this is a different process than last time.
1360+
* If so, reset the counter to prevent scheduler pollset migration
1361+
* in multi-process scenarios (e.g., multiple socket:accept callers). */
1362+
if (state->last_select_pid != recipient) {
1363+
state->count = 0;
1364+
state->last_select_pid = recipient;
1365+
}
1366+
else if (++(state->count) > 10) {
13521367
int wake_poller = 0;
13531368
DEBUG_PRINT_FD("moving to scheduler ps", state);
13541369
new_events = erts_poll_control(get_scheduler_pollset(), fd, ERTS_POLL_OP_ADD,
@@ -1359,7 +1374,7 @@ enif_select_x(ErlNifEnv* env,
13591374
old_events = state->events;
13601375
}
13611376
}
1362-
if (ctl_events & ERTS_POLL_EV_IN) {
1377+
{
13631378
ErtsSchedulerData *esdp = erts_get_scheduler_data();
13641379
erts_io_clear_nif_select(fd, state);
13651380
/* Clear the marker in scheduler data so that the scheduler
@@ -1408,6 +1423,8 @@ enif_select_x(ErlNifEnv* env,
14081423
if (state->type == ERTS_EV_TYPE_NIF && !old_events) {
14091424
state->type = ERTS_EV_TYPE_NONE;
14101425
state->flags = 0;
1426+
state->count = 0;
1427+
state->last_select_pid = NIL;
14111428
state->driver.nif->in.pid = NIL;
14121429
state->driver.nif->out.pid = NIL;
14131430
state->driver.nif->err.pid = NIL;
@@ -1421,8 +1438,6 @@ enif_select_x(ErlNifEnv* env,
14211438
|| state->type == ERTS_EV_TYPE_NONE);
14221439

14231440
if (on) {
1424-
const Eterm recipient = pid ? pid->pid : env->proc->common.id;
1425-
ASSERT(is_internal_pid(recipient));
14261441
if (!state->driver.nif)
14271442
state->driver.nif = alloc_nif_select_data();
14281443
if (state->type == ERTS_EV_TYPE_NONE) {
@@ -1497,6 +1512,7 @@ enif_select_x(ErlNifEnv* env,
14971512
ret |= ERL_NIF_SELECT_STOP_SCHEDULED;
14981513
}
14991514
state->count = 0;
1515+
state->last_select_pid = NIL;
15001516
state->flags &= ~ERTS_EV_FLAG_WANT_ERROR;
15011517
}
15021518
else
@@ -1777,6 +1793,8 @@ steal_pending_stop_use(erts_dsprintf_buf_t *dsbufp, ErlDrvPort ix,
17771793
}
17781794
state->type = ERTS_EV_TYPE_NONE;
17791795
state->flags = 0;
1796+
state->count = 0;
1797+
state->last_select_pid = NIL;
17801798
state->driver.stop.drv_ptr = NULL;
17811799
}
17821800
else {
@@ -1816,6 +1834,8 @@ steal_pending_stop_nif(erts_dsprintf_buf_t *dsbufp, ErtsResource* resource,
18161834
enif_release_resource(state->driver.stop.resource->data);
18171835
state->type = ERTS_EV_TYPE_NONE;
18181836
state->flags = 0;
1837+
state->count = 0;
1838+
state->last_select_pid = NIL;
18191839
state->driver.stop.resource = NULL;
18201840
}
18211841
else {
@@ -2014,6 +2034,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
20142034
erts_poll_control(get_scheduler_pollset(), fd, ERTS_POLL_OP_DEL, 0, &wake_poller);
20152035
state->flags &= ~(ERTS_EV_FLAG_SCHEDULER|ERTS_EV_FLAG_IN_SCHEDULER);
20162036
state->count = 0;
2037+
state->last_select_pid = NIL;
20172038
}
20182039
#endif
20192040
} else {
@@ -2034,6 +2055,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only
20342055
state->flags &= ~(ERTS_EV_FLAG_IN_SCHEDULER|ERTS_EV_FLAG_SCHEDULER);
20352056
state->active_events &= ~ERTS_POLL_EV_IN;
20362057
state->count = 0;
2058+
state->last_select_pid = NIL;
20372059
}
20382060
} else
20392061
#endif

0 commit comments

Comments
 (0)