Skip to content

Commit

Permalink
SCP: NAT poll() optimizations
Browse files Browse the repository at this point in the history
- Manage poll() file descriptors more efficiently. Both Linux() poll and
  Windows WSAPoll() ignore file descriptors that are negative in the
  pollfd array. Set the pollfd.fd file descriptor to INVALID_SOCKET when
  no longer needed. Reuse the pollfd array element if have_valid_socket()
  returns false.

- sim_slirp_dispatch(): Removed, empty function no longer required.

- sim_deb: Remove code that NULLs this FILE pointer when "flushing" the
  debug output. Presumably, closing the file and re-opening it flushes
  the debug output. Synchronizing when this operation occurs with other
  code in other threads also write to sim_deb needs to be revisited. For
  the time being, just fflush(sim_deb).

  Otherwise, _sim_debug_write_all() gets stuck in an infinite loop
  writing zero bytes.
  • Loading branch information
bscottm committed Dec 23, 2024
1 parent b530e8d commit 294e970
Show file tree
Hide file tree
Showing 15 changed files with 316 additions and 218 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ option(SIMH_PACKAGE_SUFFIX
option(MAC_UNIVERSAL
"macOS universal binary flag: TRUE -> build universal binaries, FALSE -> don't."
${MAC_UNIVERSAL_OPTVAL})
option(USE_SELECT
"NAT(libslirp): Use select() as the socket polling function"
FALSE)
option(USE_POLL
"NAT(libslirp): Use poll() as the socket polling function"
FALSE)

# Places where CMake should look for dependent package configuration fragments and artifacts:
set(SIMH_PREFIX_PATH_LIST)
Expand Down
4 changes: 2 additions & 2 deletions cmake/add_simulator.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ function(build_simcore _targ)
${CMAKE_SOURCE_DIR}/libslirp/src
${CMAKE_BINARY_DIR}/libslirp/build-include
)
endif ()
endif ()

target_link_options(${lib} PRIVATE ${EXTRA_TARGET_LFLAGS})

# Make sure that the top-level directory is part of the libary's include path:
Expand Down
49 changes: 38 additions & 11 deletions cmake/cmake-builder.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ param (
##
## Supported flavors:
## ------------------
## vs2022 Visual Studio 2022 (default)
## vs2022 Visual Studio 2022
## vs2022-xp Visual Studio 2022 XP compat
## vs2022-x64 Visual Studio 2022 64-bit
## vs2022-x64 Visual Studio 2022 64-bit (default)
## vs2019 Visual Studio 2019
## vs2019-xp Visual Studio 2019 XP compat
## vs2019-x64 Visual Studio 2019 64-bit
Expand Down Expand Up @@ -166,6 +166,14 @@ param (
[Parameter(Mandatory=$false)]
[string] $sanitizer = "",

## Use select() as the NAT(libslirp) socket polling function
[Parameter(Mandatory=$false)]
[switch] $use_select = $false,

## Use WSAPoll() as the NAT(libslirp) socket polling function
[Parameter(Mandatory=$false)]
[switch] $use_poll = $false,

## Turn on maximal compiler warnings for Debug builds (e.g. "-Wall" or "/W3")
[Parameter(Mandatory=$false)]
[switch] $debugWall = $false,
Expand Down Expand Up @@ -207,7 +215,7 @@ class GeneratorInfo
## Multiple build configurations selected at compile time
$multiConfig = $false
## Single configuration selected at configuration time
$singleConfig = $true
$singleConfig = $True

$cmakeGenMap = @{
"vs2022" = [GeneratorInfo]::new("Visual Studio 17 2022", $multiConfig, $false, "", @("-A", "Win32"));
Expand Down Expand Up @@ -391,6 +399,15 @@ else
}
}

## Can only have one of use_select or use_poll
if ($use_select -and $use_poll)
{
Write-Host ""
Write-Host "!! ${scriptName}: Can only set one of -use_select, -use_poll"
Write-Host ""
exit 0
}

if (($scriptPhases -contains "generate") -or ($scriptPhases -contains "build"))
{
## Clean out the build subdirectory
Expand Down Expand Up @@ -457,16 +474,26 @@ if (($scriptPhases -contains "generate") -or ($scriptPhases -contains "build"))
{
$generateArgs += @("-DSIMH_PACKAGE_SUFFIX:Bool=${cpack_suffix}")
}
if ($use_select)
{
$generateArgs += @("-DUSE_SELECT:Bool=True")
}
if ($use_poll)
{
$generateArgs += @("-DUSE_POLL:Bool=True")
}

## Add sanitizer(s)
foreach ($santhing in $sanitizer.Split(',')) {
switch -exact ($santhing)
{
"address" {
$generateArgs += @("-DSANITIZE_ADDRESS:Bool=On")
}
default {
Write-Host "** Unknown sanitizer option: ${santhing}, ignoring"
if (![String]::IsNullOrEmpty($sanitizer)) {
foreach ($santhing in $sanitizer.Split(',')) {
switch -exact ($santhing)
{
"address" {
$generateArgs += @("-DSANITIZE_ADDRESS:Bool=On")
}
default {
Write-Host "** Unknown sanitizer option: ${santhing}, ignoring"
}
}
}
}
Expand Down
14 changes: 13 additions & 1 deletion cmake/cmake-builder.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ Configure and build simh simulators on Linux and *nix-like platforms.
memory [MSan -- memory sanitizer]
thread [TSan -- thread sanitizer]
undef [UBSan -- undefined behavior sanitizer]
--use-select Use select() as the NAT(libslirp) socket polling
function
--use-poll Use poll() as the NAT(libslirp) socket polling
function, if available.
--cpack_suffix Specify CPack's packaging suffix, e.g., "ubuntu-22.04"
to produce the "simh-4.1.0-ubuntu-22.04.deb" Debian
Expand Down Expand Up @@ -169,7 +173,7 @@ fi

longopts=clean,help,flavor:,config:,nonetwork,novideo,notest,parallel,generate,testonly
longopts=${longopts},noinstall,installonly,verbose,target:,lto,debugWall,cppcheck,cpack_suffix:
longopts=${longopts},cache,no-aio,no-aio-intrinsics,sanitizer:
longopts=${longopts},cache,no-aio,no-aio-intrinsics,sanitizer:,use-select,use-poll

ARGS=$(${getopt_prog} --longoptions $longopts --options xhf:c:pg -- "$@")
if [ $? -ne 0 ] ; then
Expand Down Expand Up @@ -313,6 +317,14 @@ while true; do
esac
shift 2
;;
--use-select)
generateArgs="${generateArgs} -DUSE_SELECT:Bool=True"
shift
;;
--use-poll)
generateArgs="${generateArgs} -DUSE_POLL:Bool=True"
shift
;;
--)
## End of options. we'll ignore.
shift
Expand Down
72 changes: 40 additions & 32 deletions cmake/os-features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -182,20 +182,6 @@ if (WITH_NETWORK)
endif (WITH_TAP)
endif (WITH_NETWORK)

## Windows: winmm (for ms timer functions), socket functions (even when networking is
## disabled. Also squelch the deprecation warnings (these warnings can be enabled
## via the -DWINAPI_DEPRECATION:Bool=On flag at configure time.)
if (WIN32)
target_link_libraries(os_features INTERFACE ws2_32 wsock32 winmm)
target_compile_definitions(os_features INTERFACE HAVE_WINMM)
if (NOT WINAPI_DEPRECATION)
target_compile_definitions(os_features INTERFACE
_CRT_NONSTDC_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
)
endif ()
endif ()

## Cygwin also wants winmm. Note: Untested but should work.
if (CYGWIN)
check_library_exists(winmm timeGetTime "" HAS_WINMM)
Expand All @@ -215,31 +201,53 @@ endif ()
set(sim_use_select 0)
set(sim_use_poll 0)

if (NOT WIN32)
check_include_file(poll.h have_poll_h)
if (have_poll_h)
set(sim_use_poll 1)
else ()
set(sim_use_select 1)
endif ()
else ()
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32")
set(check_poll 0)

check_symbol_exists(WSAPoll "winsock2.h;windows.h" have_wsa_poll)
if (have_wsa_poll)
set(sim_use_poll 1)
if (USE_SELECT)
set(sim_use_select 1)
else ()
if (NOT WIN32)
check_symbol_exists(poll "poll.h" have_poll_h)
if (have_poll_h)
set(sim_use_poll 1)
elseif (USE_POLL)
message(FATAL_ERROR "USE_POLL set, poll.h not detected. Select a different socket polling mechansim.")
else ()
set(sim_use_select 1)
endif()
else ()
set(sim_use_select 1)
endif ()
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32" "wsock32")

cmake_pop_check_state()
endif()
check_symbol_exists(WSAPoll "winsock2.h;windows.h" have_wsa_poll)
if (have_wsa_poll)
set(sim_use_poll 1)
else ()
set(sim_use_select 1)
endif ()

cmake_pop_check_state()
endif()
endif ()

target_compile_definitions(os_features INTERFACE
target_compile_definitions(os_features INTERFACE
SIM_USE_POLL=${sim_use_poll}
SIM_USE_SELECT=${sim_use_select}
)

## Windows: winmm (for ms timer functions), socket functions (even when networking is
## disabled. Also squelch the deprecation warnings (these warnings can be enabled
## via the -DWINAPI_DEPRECATION:Bool=On flag at configure time.)
if (WIN32)
target_link_libraries(os_features INTERFACE ws2_32 wsock32 winmm)
target_compile_definitions(os_features INTERFACE HAVE_WINMM)
if (NOT WINAPI_DEPRECATION)
target_compile_definitions(os_features INTERFACE
_CRT_NONSTDC_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
)
endif ()
endif ()

## Sanitizer support
find_package(Sanitizers)
33 changes: 31 additions & 2 deletions cmake/platform-quirks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,37 @@ if (WIN32)
message(STATUS "Target Windows version set to ${TARGET_WINVER}")
add_compile_definitions(WINVER=${TARGET_WINVER} _WIN32_WINNT=${TARGET_WINVER})
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DWINVER=${TARGET_WINVER}" "-D_WIN32_WINNT=${TARGET_WINVER}")
set(WINVER ${TARGET_WINVER})
else ()
file(WRITE
${CMAKE_BINARY_DIR}/CMakeTmp/testWinVer.c
"#define WINDOWS_LEAN_AND_MEAN\n"
"#include <windows.h>\n"
"#include <stdio.h>\n"
"int main(void) {\n"
"#if defined(WINVER) && WINVER >= 0x0601\n"
" return 0;\n"
"#else\n"
" return 1;\n"
"#endif\n"
"}\n"
)

try_run(RUN_WINVER COMPILE_WINVER
SOURCES ${CMAKE_BINARY_DIR}/CMakeTmp/testWinVer.c
RUN_OUTPUT_VARIABLE THE_WINVER
)

if (RUN_WINVER EQUAL 0)
message(STATUS "Windows Vista or later.")
set(WINDOWS_VISTA_PLUS TRUE)
else ()
message(STATUS "Windows version not detected: run status ${RUN_WINVER}, compile status ${COMPILE_WINVER}")
set(WINDOWS_VISTA_PLUS FALSE)
endif ()

unset(RUN_WINVER)
unset(COMPILE_WINVER)
endif ()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# The MSVC solution builds as 32-bit, but none of the *nix platforms do.
Expand Down Expand Up @@ -223,8 +254,6 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")
string(REGEX REPLACE "${opt_flag}[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
string(APPEND CMAKE_C_FLAGS_MINSIZEREL " ${opt_flag}")
endforeach ()
else ()
message(STATUS "Not changing CMAKE_C_FLAGS_RELEASE on ${CMAKE_C_COMPILER_ID}")
endif ()


Expand Down
2 changes: 1 addition & 1 deletion libslirp
Submodule libslirp updated from c607b9 to 2853aa
Loading

0 comments on commit 294e970

Please sign in to comment.