Signed-off-by: Paul Gofman pgofman@codeweavers.com --- Sword of Legends Online calls GetTcpTable() twice (with different sort flag) every 3-4 seconds. With the move of the implementation to nsi.dll / nsiproxy.sys the performance of this function regressed and now these calls are responsible for visible delay in rendering each 3-4 seconds. I found that the majority of time is wasted for mapping pids while that mapping result is not used in this case. These two patches reduce the time for GetTcpTable() from roughly 50ms to roughly 5ms. Further improvement looks possible but are probably more ugly.
dlls/nsiproxy.sys/tcp.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/dlls/nsiproxy.sys/tcp.c b/dlls/nsiproxy.sys/tcp.c index 0cd81ae86e5..5ff3dbd2378 100644 --- a/dlls/nsiproxy.sys/tcp.c +++ b/dlls/nsiproxy.sys/tcp.c @@ -540,7 +540,7 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * memset( &key, 0, sizeof(key) ); memset( &dyn, 0, sizeof(dyn) ); memset( &stat, 0, sizeof(stat) ); - pid_map = get_pid_map( &pid_map_size ); + if (static_data) pid_map = get_pid_map( &pid_map_size );
/* skip header line */ ptr = fgets( buf, sizeof(buf), fp ); @@ -558,15 +558,17 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * key.local.Ipv4.sin_port = htons( key.local.Ipv4.sin_port ); key.remote.Ipv4.sin_port = htons( key.remote.Ipv4.sin_port );
- stat.pid = find_owning_pid( pid_map, pid_map_size, inode ); - stat.create_time = 0; /* FIXME */ - stat.mod_info = 0; /* FIXME */ - if (num < *count) { if (key_data) *key_data++ = key; if (dynamic_data) *dynamic_data++ = dyn; - if (static_data) *static_data++ = stat; + if (static_data) + { + stat.pid = find_owning_pid( pid_map, pid_map_size, inode ); + stat.create_time = 0; /* FIXME */ + stat.mod_info = 0; /* FIXME */ + *static_data++ = stat; + } } num++; } @@ -601,16 +603,17 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * addr_scopes_size ); key.remote.Ipv6.sin6_scope_id = find_ipv6_addr_scope( &key.remote.Ipv6.sin6_addr, addr_scopes, addr_scopes_size ); - - stat.pid = find_owning_pid( pid_map, pid_map_size, inode ); - stat.create_time = 0; /* FIXME */ - stat.mod_info = 0; /* FIXME */ - if (num < *count) { if (key_data) *key_data++ = key; if (dynamic_data) *dynamic_data++ = dyn; - if (static_data) *static_data++ = stat; + if (static_data) + { + stat.pid = find_owning_pid( pid_map, pid_map_size, inode ); + stat.create_time = 0; /* FIXME */ + stat.mod_info = 0; /* FIXME */ + *static_data++ = stat; + } } num++; } @@ -649,7 +652,7 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * if (len <= sizeof(struct xinpgen)) goto err;
addr_scopes = get_ipv6_addr_scope_table( &addr_scopes_size ); - pid_map = get_pid_map( &pid_map_size ); + if (class >= TCP_TABLE_OWNER_PID_LISTENER) pid_map = get_pid_map( &pid_map_size );
orig_xig = (struct xinpgen *)buf; xig = orig_xig; @@ -708,15 +711,17 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * addr_scopes_size ); }
- stat.pid = find_owning_pid( pid_map, pid_map_size, (UINT_PTR)sock->so_pcb ); - stat.create_time = 0; /* FIXME */ - stat.mod_info = 0; /* FIXME */ - if (num < *count) { if (key_data) *key_data++ = key; if (dynamic_data) *dynamic_data++ = dyn; - if (static_data) *static_data++ = stat; + if (static_data) + { + stat.pid = find_owning_pid( pid_map, pid_map_size, (UINT_PTR)sock->so_pcb ); + stat.create_time = 0; /* FIXME */ + stat.mod_info = 0; /* FIXME */ + *static_data++ = stat; + } } num++; }
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/iphlpapi/iphlpapi_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 041e712f44f..8e492601647 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -3093,13 +3093,20 @@ static DWORD get_extended_tcp_table( void *table, DWORD *size, BOOL sort, ULONG DWORD err, count, needed, i, num = 0, row_size = 0; struct nsi_tcp_conn_key *key; struct nsi_tcp_conn_dynamic *dyn; - struct nsi_tcp_conn_static *stat; + struct nsi_tcp_conn_static *stat = NULL;
if (!size) return ERROR_INVALID_PARAMETER;
- err = NsiAllocateAndGetTable( 1, &NPI_MS_TCP_MODULEID, tcp_table_id( table_class ), (void **)&key, sizeof(*key), - NULL, 0, (void **)&dyn, sizeof(*dyn), - (void **)&stat, sizeof(*stat), &count, 0 ); + + if (table_class >= TCP_TABLE_OWNER_PID_LISTENER) + err = NsiAllocateAndGetTable( 1, &NPI_MS_TCP_MODULEID, tcp_table_id( table_class ), (void **)&key, sizeof(*key), + NULL, 0, (void **)&dyn, sizeof(*dyn), + (void **)&stat, sizeof(*stat), &count, 0 ); + else + err = NsiAllocateAndGetTable( 1, &NPI_MS_TCP_MODULEID, tcp_table_id( table_class ), (void **)&key, sizeof(*key), + NULL, 0, (void **)&dyn, sizeof(*dyn), + NULL, 0, &count, 0 ); + if (err) return err;
for (i = 0; i < count; i++)
On Tue, Mar 22, 2022 at 09:54:49PM +0300, Paul Gofman wrote:
@@ -649,7 +652,7 @@ static NTSTATUS tcp_conns_enumerate_all( DWORD filter, struct nsi_tcp_conn_key * if (len <= sizeof(struct xinpgen)) goto err;
addr_scopes = get_ipv6_addr_scope_table( &addr_scopes_size );
pid_map = get_pid_map( &pid_map_size );
if (class >= TCP_TABLE_OWNER_PID_LISTENER) pid_map = get_pid_map( &pid_map_size );
Hi Paul,
This doesn't build on macOS. I've sent in v2 with a fix and also changed [2/2] a little.
Thanks, Huw.