diff options
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.c | 17 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_poll.c | 49 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_poll.h | 2 |
3 files changed, 36 insertions, 32 deletions
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index d1d6696090..3097f7b7dd 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -41,8 +41,7 @@ #define ERTS_WANT_TIMER_WHEEL_API #include "erl_time.h" -#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS -#else +#ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS # include "safe_hash.h" # define DRV_EV_STATE_HTAB_SIZE 1024 #endif @@ -413,14 +412,16 @@ static void grow_drv_ev_state(int min_ix) { int i; + int old_len; int new_len; - new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(min_ix + 1); - if (new_len > max_fds) - new_len = max_fds; - erts_smp_mtx_lock(&drv_ev_state_grow_lock); - if (erts_smp_atomic_read_nob(&drv_ev_state_len) <= min_ix) { + old_len = erts_smp_atomic_read_nob(&drv_ev_state_len); + if (min_ix >= old_len) { + new_len = erts_poll_new_table_len(old_len, min_ix + 1); + if (new_len > max_fds) + new_len = max_fds; + for (i=0; i<DRV_EV_STATE_LOCK_CNT; i++) { /* lock all fd's */ erts_smp_mtx_lock(&drv_ev_state_locks[i].lck); } @@ -430,7 +431,7 @@ grow_drv_ev_state(int min_ix) sizeof(ErtsDrvEventState)*new_len) : erts_alloc(ERTS_ALC_T_DRV_EV_STATE, sizeof(ErtsDrvEventState)*new_len)); - for (i = erts_smp_atomic_read_nob(&drv_ev_state_len); i < new_len; i++) { + for (i = old_len; i < new_len; i++) { drv_ev_state[i].fd = (ErtsSysFdType) i; drv_ev_state[i].driver.select = NULL; #if ERTS_CIO_HAVE_DRV_EVENT diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index 71c4239902..68d3c30bd4 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -153,9 +153,6 @@ int ERTS_SELECT(int nfds, ERTS_fd_set *readfds, ERTS_fd_set *writefds, #define ERTS_POLL_COALESCE_KP_RES (ERTS_POLL_USE_KQUEUE || ERTS_POLL_USE_EPOLL) -#define ERTS_EV_TABLE_MIN_LENGTH 1024 -#define ERTS_EV_TABLE_EXP_THRESHOLD (2048*1024) - #ifdef ERTS_POLL_NEED_ASYNC_INTERRUPT_SUPPORT # define ERTS_POLL_ASYNC_INTERRUPT_SUPPORT 1 #else @@ -703,27 +700,33 @@ free_update_requests_block(ErtsPollSet ps, * --- Growing poll set structures ------------------------------------------- */ -int -ERTS_POLL_EXPORT(erts_poll_get_table_len) (int new_len) +#ifndef ERTS_KERNEL_POLL_VERSION /* only one shared implementation */ + +#define ERTS_FD_TABLE_MIN_LENGTH 1024 +#define ERTS_FD_TABLE_EXP_THRESHOLD (2048*1024) + +int erts_poll_new_table_len (int old_len, int need_len) { - if (new_len < ERTS_EV_TABLE_MIN_LENGTH) { - new_len = ERTS_EV_TABLE_MIN_LENGTH; - } else if (new_len < ERTS_EV_TABLE_EXP_THRESHOLD) { - /* find next power of 2 */ - --new_len; - new_len |= new_len >> 1; - new_len |= new_len >> 2; - new_len |= new_len >> 4; - new_len |= new_len >> 8; - new_len |= new_len >> 16; - ++new_len; - } else { - /* grow incrementally */ - new_len += ERTS_EV_TABLE_EXP_THRESHOLD; + int new_len; + + ASSERT(need_len > old_len); + if (need_len < ERTS_FD_TABLE_MIN_LENGTH) { + new_len = ERTS_FD_TABLE_MIN_LENGTH; } + else { + new_len = old_len; + do { + if (new_len < ERTS_FD_TABLE_EXP_THRESHOLD) + new_len *= 2; + else + new_len += ERTS_FD_TABLE_EXP_THRESHOLD; + + } while (new_len < need_len); + } + ASSERT(new_len >= need_len); return new_len; } - +#endif #if ERTS_POLL_USE_KERNEL_POLL static void @@ -737,7 +740,7 @@ grow_res_events(ErtsPollSet ps, int new_len) #elif ERTS_POLL_USE_KQUEUE struct kevent #endif - ) * ERTS_POLL_EXPORT(erts_poll_get_table_len)(new_len); + ) * erts_poll_new_table_len(ps->res_events_len, new_len); /* We do not need to save previously stored data */ if (ps->res_events) erts_free(ERTS_ALC_T_POLL_RES_EVS, ps->res_events); @@ -751,7 +754,7 @@ static void grow_poll_fds(ErtsPollSet ps, int min_ix) { int i; - int new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(min_ix + 1); + int new_len = erts_poll_new_table_len(ps->poll_fds_len, min_ix + 1); if (new_len > max_fds) new_len = max_fds; ps->poll_fds = (ps->poll_fds_len @@ -800,7 +803,7 @@ static void grow_fds_status(ErtsPollSet ps, int min_fd) { int i; - int new_len = ERTS_POLL_EXPORT(erts_poll_get_table_len)(min_fd + 1); + int new_len = erts_poll_new_table_len(ps->fds_status_len, min_fd + 1); ASSERT(min_fd < max_fds); if (new_len > max_fds) new_len = max_fds; diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h index ae2d063805..ad8f714d6e 100644 --- a/erts/emulator/sys/common/erl_poll.h +++ b/erts/emulator/sys/common/erl_poll.h @@ -275,6 +275,6 @@ void ERTS_POLL_EXPORT(erts_poll_get_selected_events)(ErtsPollSet, ErtsPollEvents [], int); -int ERTS_POLL_EXPORT(erts_poll_get_table_len)(int); +int erts_poll_new_table_len(int old_len, int need_len); #endif /* #ifndef ERL_POLL_H__ */ |