diff --git a/CMakeLists.txt b/CMakeLists.txt index 9de5bfd89..33f7e691d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,9 +179,9 @@ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/lib/irrlichtmt") message(STATUS "Using user-provided IrrlichtMt at subdirectory 'lib/irrlichtmt'") if(BUILD_CLIENT) # tell IrrlichtMt to create a static library - set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library" FORCE) + #set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared library" FORCE) add_subdirectory(lib/irrlichtmt EXCLUDE_FROM_ALL) - unset(BUILD_SHARED_LIBS CACHE) + #unset(BUILD_SHARED_LIBS CACHE) if(NOT TARGET IrrlichtMt) message(FATAL_ERROR "IrrlichtMt project is missing a CMake target?!") diff --git a/games/default b/games/default index 004541565..0be0e0c08 160000 --- a/games/default +++ b/games/default @@ -1 +1 @@ -Subproject commit 004541565e65c62627b90c020eccb3245d4a509a +Subproject commit 0be0e0c08d7ac9b6e94682acdb54795825bee209 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 757fae163..718314909 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -102,22 +102,32 @@ if(NOT MSVC) if(ENABLE_GPERF OR ENABLE_TCMALLOC) set(CMAKE_POSITION_INDEPENDENT_CODE ON) + if (NOT BUILD_SHARED_LIBS) + list(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES) + endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug") find_library(TCMALLOC_LIBRARY NAMES tcmalloc_debug tcmalloc) else() find_library(TCMALLOC_LIBRARY NAMES tcmalloc tcmalloc_and_profiler) endif() + if(ENABLE_GPERF) find_library(PROFILER_LIBRARY NAMES profiler tcmalloc_and_profiler) endif() + if (NOT BUILD_SHARED_LIBS) + list(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES) + endif() + if (PROFILER_LIBRARY) + # set(PLATFORM_LIBS ${PLATFORM_LIBS} -Wl,--no-as-needed ${PROFILER_LIBRARY} -Wl,--as-needed) set(PLATFORM_LIBS ${PLATFORM_LIBS} ${PROFILER_LIBRARY}) endif() if (TCMALLOC_LIBRARY) - set(PLATFORM_LIBS ${PLATFORM_LIBS} ${TCMALLOC_LIBRARY}) + set(PLATFORM_LIBS ${PLATFORM_LIBS} ${TCMALLOC_LIBRARY}) set(OTHER_FLAGS "${OTHER_FLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free") endif() @@ -377,6 +387,7 @@ if(ENABLE_LEVELDB) set(SNAPPY_BUILD_TESTS 0 CACHE INTERNAL "") set(SNAPPY_BUILD_BENCHMARKS 0 CACHE INTERNAL "") set(SNAPPY_INSTALL 0 CACHE INTERNAL "") + set(HAVE_TCMALLOC 0 CACHE INTERNAL "") add_subdirectory(${PROJECT_SOURCE_DIR}/external/snappy) set(SNAPPY_LIBRARY snappy) @@ -712,7 +723,8 @@ endif() #add_subdirectory(external/TinyTIFF/src) #set(TINYTIFF_LIRARY TinyTIFF) -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/external/libtiff/CMakeLists.txt) +option(ENABLE_TIFF "Enable tiff (feotiff for mapgen earth)" 1) +if(ENABLE_TIFF AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/external/libtiff/CMakeLists.txt) set(tiff-tools 0 CACHE INTERNAL "") set(tiff-tests 0 CACHE INTERNAL "") set(tiff-docs 0 CACHE INTERNAL "") diff --git a/src/client/activeobjectmgr.cpp b/src/client/activeobjectmgr.cpp index 3bd4acc97..bcaa7c5ee 100644 --- a/src/client/activeobjectmgr.cpp +++ b/src/client/activeobjectmgr.cpp @@ -95,12 +95,13 @@ void ActiveObjectMgr::removeObject(u16 id) return; } + m_active_objects_deleted.emplace_back(obj); + //std::unique_ptr obj = std::move(it->second); m_active_objects.erase(id); obj->removeFromScene(true); - m_active_objects_deleted.emplace_back(std::move(obj)); } // clang-format on diff --git a/src/client/client.cpp b/src/client/client.cpp index e99b6208e..5bb09c402 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -605,12 +605,12 @@ void Client::step(float dtime) TimeTaker timer_step("Client: Replace updated meshes"); int num_processed_meshes = 0; - auto end_ms = porting::getTimeMs() + 10; + auto end_ms = porting::getTimeMs() + 5; std::vector blocks_to_ack; auto qsize = m_mesh_update_manager->m_queue_out.size(); if (qsize > 1000) - end_ms += 100; + end_ms += 30; bool force_update_shadows = false; MeshUpdateResult r; @@ -1719,13 +1719,15 @@ void Client::addNode(v3pos_t p, MapNode n, bool remove_metadata, int fast) catch(InvalidPositionException &e) { } - if (p.getDistanceFrom(floatToInt(m_env.getLocalPlayer()->getPosition(), BS)) > MAP_BLOCKSIZE*2) + const auto disance = p.getDistanceFrom(floatToInt(m_env.getLocalPlayer()->getPosition(), BS)); + if (disance > MAP_BLOCKSIZE*2) return; - addUpdateMeshTaskForNode(p, true); + addUpdateMeshTaskForNode(p, true, disance <= MAP_BLOCKSIZE); + modified_blocks.erase(getNodeBlockPos(p)); for (const auto &modified_block : modified_blocks) { - addUpdateMeshTaskWithEdge(modified_block.first, false, true); + addUpdateMeshTaskWithEdge(modified_block.first, false, false); } } diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index 07aa95d80..a55ffb06c 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -69,6 +69,10 @@ void MapDrawControl::fm_init() { g_settings->getS32NoEx("farmesh", farmesh); g_settings->getS32NoEx("lodmesh", lodmesh); + static const auto headless_optimize = g_settings->getBool("headless_optimize"); + if (headless_optimize) + lodmesh = 0; + fov_want = fov = g_settings->getFloat("fov"); } @@ -901,16 +905,21 @@ void ClientMap::updateDrawListFm(float dtime, unsigned int max_cycle_ms) Ignore if mesh doesn't exist */ { - if((!mesh && smesh_size < 0) || mesh_step != mesh->lod_step) { + if ((!mesh && smesh_size < 0) || mesh_step != mesh->lod_step) { blocks_in_range_without_mesh++; if (m_mesh_queued < maxq || range <= 1) { + const auto bts = block->getTimestamp(); + if (block->mesh_requested_timestamp < bts) { + block->mesh_requested_timestamp = bts; m_client->addUpdateMeshTask(bp, false); ++m_mesh_queued; + } } if (!mesh) continue; } - if(mesh_step == mesh->lod_step && block->getTimestamp() <= mesh->timestamp && !smesh_size) { + if (mesh_step == mesh->lod_step && + block->getTimestamp() <= mesh->timestamp && !smesh_size) { ++blocks_in_range_without_mesh; continue; } @@ -1025,10 +1034,17 @@ void ClientMap::updateDrawListFm(float dtime, unsigned int max_cycle_ms) continue; */ - if (mesh_step != mesh->lod_step && smesh_size < 0 && (m_mesh_queued < maxq*1.2 || range <= 2)) { + if (mesh_step != mesh->lod_step && smesh_size < 0 && + (m_mesh_queued < maxq * 1.2 || range <= 2)) { m_client->addUpdateMeshTask(bp); ++m_mesh_queued; - } else if (block->getTimestamp() > mesh->timestamp + (smesh_size ? 0 : range >= 1 ? 60 : 5) && (m_mesh_queued < maxq*1.5 || range <= 2)) { + } else if (const auto bts = block->getTimestamp(); + bts != BLOCK_TIMESTAMP_UNDEFINED && + block->getTimestamp() > mesh->timestamp + (smesh_size ? 0 + : range >= 1 + ? 60 + : 5) && + (m_mesh_queued < maxq * 1.5 || range <= 2)) { if (mesh_step > 1) m_client->addUpdateMeshTask(bp); else diff --git a/src/client/fm_farmesh.cpp b/src/client/fm_farmesh.cpp index 33ce3e20e..77549973f 100644 --- a/src/client/fm_farmesh.cpp +++ b/src/client/fm_farmesh.cpp @@ -84,7 +84,6 @@ void FarMesh::makeFarBlock(const v3bpos_t &blockpos) const auto lock = std::lock_guard(block->far_mutex); if (!block->getFarMesh(step)) { MeshMakeData mdat(m_client, false, 0, step, &farcontainer); - mdat.block = block.get(); mdat.m_blockpos = blockpos_actual; auto mbmsh = std::make_shared(&mdat, m_camera_offset); block->setFarMesh(mbmsh, m_client->m_uptime); diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 4947d9a4b..a518cfe48 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -62,23 +62,6 @@ MeshMakeData::MeshMakeData(Client *client, bool use_shaders, fscale(pow(2, far_step + lod_step)) {} -bool MeshMakeData::fill_data() -{ - if (filled) - return filled; - - if (!block) - block = m_client->m_env.getClientMap().getBlockNoCreateNoEx(m_blockpos); - - if (!block) - return filled; - filled = true; - timestamp = block->getTimestamp(); - - return filled; -} - - void MeshMakeData::fillBlockDataBegin(const v3bpos_t &blockpos) { m_blockpos = blockpos; @@ -697,10 +680,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3pos_t camera_offset): m_enable_shaders = data->m_use_shaders; m_enable_vbo = g_settings->getBool("enable_vbo"); - if (!data->fill_data()) { - return; - } - v3bpos_t bp = data->m_blockpos; // Only generate minimap mapblocks at even coordinates. if (fscale<=1) // || !data->block->getMesh()) diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index a9363f643..a7670317f 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -63,13 +63,7 @@ struct MeshMakeData int range = 1; bool no_draw = false; unsigned int timestamp = 0; - MapBlock * block = nullptr; - //Map & map; - //MapDrawControl& draw_control; bool debug = false; - bool filled = false; - void fill(MapBlock *block_); - bool fill_data(); explicit MeshMakeData(Client *client, bool use_shaders , int lod_step = 0 diff --git a/src/client/mesh_generator_thread.cpp b/src/client/mesh_generator_thread.cpp index a17cc1ce9..4b58cfd39 100644 --- a/src/client/mesh_generator_thread.cpp +++ b/src/client/mesh_generator_thread.cpp @@ -210,6 +210,11 @@ void MeshUpdateQueue::fillDataFromMapBlocks(QueuedMeshUpdate *q) if (block) { auto lock = block->lock_shared_rec(); data->fillBlockData(pos, block->getData()); + + if (const auto bts = block->getTimestamp(); + bts != BLOCK_TIMESTAMP_UNDEFINED) { + data->timestamp = std::max(data->timestamp, bts); + } } else { data->fillBlockData(pos, block_placeholder.data); } @@ -264,6 +269,7 @@ void MeshUpdateWorkerThread::doUpdate() MeshUpdateManager::MeshUpdateManager(Client *client): m_queue_in(client) + , m_queue_in_urgent(client) { int number_of_threads = rangelim(g_settings->getS32("mesh_generation_threads"), 0, 8); @@ -277,6 +283,8 @@ MeshUpdateManager::MeshUpdateManager(Client *client): for (int i = 0; i < number_of_threads; i++) m_workers.push_back(std::make_unique(&m_queue_in, this, &m_camera_offset)); + + m_workers.push_back(std::make_unique(&m_queue_in_urgent, this, &m_camera_offset)); } void MeshUpdateManager::updateBlock(Map *map, v3bpos_t p, bool ack_block_to_server, @@ -285,7 +293,7 @@ void MeshUpdateManager::updateBlock(Map *map, v3bpos_t p, bool ack_block_to_serv static thread_local const bool many_neighbors = g_settings->getBool("smooth_lighting") && !g_settings->getFlag("performance_tradeoffs"); - if (!m_queue_in.addBlock(map, p, ack_block_to_server, urgent)) { + if (!(urgent ? m_queue_in_urgent : m_queue_in).addBlock(map, p, ack_block_to_server, urgent)) { warningstream << "Update requested for non-existent block at (" << p.X << ", " << p.Y << ", " << p.Z << ")" << std::endl; return; diff --git a/src/client/mesh_generator_thread.h b/src/client/mesh_generator_thread.h index f28188fb9..38dad7b86 100644 --- a/src/client/mesh_generator_thread.h +++ b/src/client/mesh_generator_thread.h @@ -155,6 +155,7 @@ class MeshUpdateManager MeshUpdateQueue m_queue_in; + MeshUpdateQueue m_queue_in_urgent; public: MutexedQueue m_queue_out; diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index 908ac3f44..27e232b86 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -15,6 +15,7 @@ #cmakedefine01 MINETEST_TRANSPORT #cmakedefine01 STATIC_BUILD #cmakedefine01 USE_ENET +#cmakedefine01 USE_GPERF #cmakedefine01 USE_ICONV #cmakedefine01 USE_IPV4_DEFAULT #cmakedefine01 USE_MANDELBULBER diff --git a/src/external/msgpack-c b/src/external/msgpack-c index 8c602e857..44c0f705c 160000 --- a/src/external/msgpack-c +++ b/src/external/msgpack-c @@ -1 +1 @@ -Subproject commit 8c602e8579c7e7d65d6f9c6703c9699db3fb0488 +Subproject commit 44c0f705c9a60217d7e07de844fb13ce4c1c1e6e diff --git a/src/external/snappy b/src/external/snappy index 23b328682..2c94e1114 160000 --- a/src/external/snappy +++ b/src/external/snappy @@ -1 +1 @@ -Subproject commit 23b3286820105438c5dbb9bc22f1bb85c5812c8a +Subproject commit 2c94e11145f0b7b184b831577c93e5a41c4c0346 diff --git a/src/mapblock.h b/src/mapblock.h index 0db6b9aff..f0fbcf908 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -540,6 +540,7 @@ class MapBlock MapBlock::mesh_type getFarMesh(int step); void setFarMesh(const MapBlock::mesh_type & rmesh, uint32_t time); std::mutex far_mutex; + u32 mesh_requested_timestamp = 0; #endif //=== diff --git a/src/server.cpp b/src/server.cpp index ed675f73d..a0de314b1 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -641,9 +641,6 @@ void Server::start() std::cerr << line << std::endl; } - - -// == fm: actionstream << "\033[1mfree\033[1;33mminer \033[1;36mv" << g_version_hash << "\033[0m \t" #if ENABLE_THREADS @@ -652,6 +649,24 @@ void Server::start() #ifndef NDEBUG << " debug \t" #endif +#if USE_GPERF + << " gperf \t" +#endif +#if defined(__has_feature) +#if __has_feature(address_sanitizer) + << " asan \t" +#endif +#endif +#if defined(__has_feature) +#if __has_feature(thread_sanitizer) + << " tsan \t" +#endif +#endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + << " msan \t" +#endif +#endif #if USE_MULTI << " multi: \t" #endif diff --git a/src/version.cpp b/src/version.cpp index bea198fb6..ec7166ead 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -54,6 +54,9 @@ const char *g_build_info = #if ENABLE_THREADS "\n" "ENABLE_THREADS" #endif +#if USE_GPERF + "\n" "USE_GPERF" +#endif #if USE_MULTI "\n" "USE_MULTI" #endif diff --git a/textures/base/pack/menu_header.png b/textures/base/pack/menu_header.png deleted file mode 100644 index 49b9f6ea9..000000000 Binary files a/textures/base/pack/menu_header.png and /dev/null differ diff --git a/util/autotest/auto.pl b/util/autotest/auto.pl index 6842831a2..dab6af537 100755 --- a/util/autotest/auto.pl +++ b/util/autotest/auto.pl @@ -46,6 +46,7 @@ $0 ---cmake_clang=1 -DENABLE_WEBSOCKET=0 -DHAVE_TCMALLOC=0 tsan bot $0 ---cmake_clang=1 -DENABLE_WEBSOCKET=0 asan bot $0 ---cmake_clang=1 -DENABLE_WEBSOCKET=0 ---cmake_leveldb=0 usan bot +$0 ---cmake_clang=1 -DENABLE_TIFF=0 gperf bot # debug touchscreen gui. use irrlicht branch ogl-es with touchscreen patch /build/android/irrlicht-touchcount.patch $0 ---build_name="_touch_asan" ---cmake_touch=1 -touchscreen=0 asan play @@ -59,6 +60,9 @@ VERBOSE=1 $0 ---cmake_sctp=1 ---cmake_clang=1 ---cmake_add="-DSCTP_DEBUG=1" gdb server VERBOSE=1 $0 ---cmake_sctp=1 ---cmake_clang=1 --address=localhost --port=60001 ---cmake_add="-DSCTP_DEBUG=1" gdb bot +# build debug +$0 ---verbose -DCMAKE_VERBOSE_MAKEFILE=1 build + #if you have installed Intel(R) VTune(TM) Amplifier $0 ---vtune_gui=1 play_vtune $0 --autoexit=60 ---vtune_gui=1 bot_vtune @@ -177,7 +181,6 @@ () # verbose => 1, vtune_amplifier => '~/intel/vtune_amplifier_xe/bin64/', vtune_collect => 'hotspots', # for full list: ~/intel/vtune_amplifier_xe/bin64/amplxe-cl -help collect - #world => $script_path . 'world', world_clear => 0, # remove old world before start client }; @@ -279,9 +282,9 @@ () mg_params => {"layers" => [{"name" => "default:torch"}, {"name" => "default:glass"}]}, }, world_rooms => { - '--world' => $script_path . 'world_rooms', - mg_name => 'math', - mg_math => {"generator" => "rooms"}, + '--world' => $script_path . 'world_rooms', + mg_name => 'math', + mg_math => {"generator" => "rooms"}, }, mg_math_tglag => { '--world' => $script_path . 'world_math_tglad', @@ -363,23 +366,24 @@ () (map { $g->{build_names}{$_} } sort keys %{$g->{build_names}}); }, env => sub { - join ' ', $config->{env}, map { $config->{envs}{$_} } sort keys %{$config->{envs}}; + 'env ' . join ' ', $config->{env}, map { $config->{envs}{$_} } sort keys %{$config->{envs}}; }, build_dir => sub { "$config->{root_prefix}$config->{build_prefix}" . $commands->{build_name}() }, executable => sub { $commands->{build_dir}() . "/" . $config->{executable_name} }, world_name => sub { return $config->{world} if defined $config->{world}; - my $name = 'world'; - $name .= '_' . $options->{opt}{mg_name} if $options->{opt}{mg_name}; - $name .= '_' .$config->{config_pass}{mg_math}{generator} if $config->{config_pass}{mg_math}{generator}; - $config->{world} = $script_path . $name; - $config->{world} = $config->{logdir} . '/' . $name if $config->{world_local}; - $config->{world}; + my $name = 'world'; + $name .= '_' . $options->{opt}{mg_name} if $options->{opt}{mg_name}; + $name .= '_' . $config->{config_pass}{mg_math}{generator} if $config->{config_pass}{mg_math}{generator}; + $config->{world} = $script_path . $name; + $config->{world} = $config->{logdir} . '/' . $name if $config->{world_local}; + $config->{world}; }, init => sub { init_config(); 0 }, '---' => 'init', cmake_prepare => sub { + $config->{cmake_clang} //= 1 if $config->{clang_version}; $config->{clang_version} = $config->{cmake_clang} if $config->{cmake_clang} and $config->{cmake_clang} ne '1'; $config->{cmake_libcxx} //= 1 if $config->{cmake_clang}; $g->{build_names}{x_clang} = $config->{clang_version} if $config->{cmake_clang}; @@ -391,7 +395,7 @@ () file_append( "$config->{logdir}/run.sh", join "\n", - qq{# } . join(' ', $0, map{/[\s"]/ ? "'" . $_ . "'" : $_} @ARGV), + qq{# } . join(' ', $0, map { /[\s"]/ ? "'" . $_ . "'" : $_ } @ARGV), qq{cd "$build_dir"}, "" ); @@ -444,27 +448,30 @@ () local $config->{make_add} = $config->{make_add}; $config->{make_add} .= " V=1 VERBOSE=1 " if $config->{make_verbose}; #sy qq{nice make -j $config->{makej} $config->{make_add} $config->{tee} $config->{logdir}/autotest.$g->{task_name}.make.log}; - return sytee qq{nice cmake --build . -- -j $config->{makej}}, qq{$config->{logdir}/autotest.$g->{task_name}.make.log}; + return sytee qq{$config->{make_add} nice cmake --build . -- -j $config->{makej}}, + qq{$config->{logdir}/autotest.$g->{task_name}.make.log}; }, run_single => sub { sy qq{rm -rf ${root_path}cache/media/* } if $config->{cache_clear} and $root_path; - $commands->{world_name}(); - sy qq{rm -rf $config->{world} } if $config->{world_clear} and $config->{world}; + $commands->{world_name}(); + sy qq{rm -rf $config->{world} } if $config->{world_clear} and $config->{world}; return - sytee $commands->{env}() - . qq{ $config->{runner} @_ } - . $commands->{executable}() - . qq{ $config->{go} --logfile $config->{logdir}/autotest.$g->{task_name}.game.log } - . options_make([qw(gameid world address port config autoexit verbose trace)]) - . qq{$config->{run_add} }, qq{$config->{logdir}/autotest.$g->{task_name}.out.log}; + sytee $config->{runner}, + $commands->{env}(), + qq{@_}, + $commands->{executable}(), + qq{$config->{go} --logfile $config->{logdir}/autotest.$g->{task_name}.game.log}, + options_make([qw(gameid world address port config autoexit verbose trace)]), + qq{$config->{run_add} }, qq{$config->{logdir}/autotest.$g->{task_name}.out.log}; 0; }, run_test => sub { - sy $commands->{env}() - . qq{ $config->{runner} @_ } - . $commands->{executable}() - . qq{ --run-unittests --logfile $config->{logdir}/autotest.$g->{task_name}.test.log } - . options_make([qw(verbose trace)]); + sy $config->{runner}, + $commands->{env}(), + qq{@_}, + $commands->{executable}(), + qq{--run-unittests --logfile $config->{logdir}/autotest.$g->{task_name}.test.log}, + options_make([qw(verbose trace)]); }, set_bot => {'----bot' => 1, '----bot_random' => 1,}, run_bot => ['set_bot', 'set_client', 'run_single'], @@ -484,17 +491,19 @@ () }, run_server_simple => sub { my $fork = $config->{server_bg} ? '&' : ''; - sytee $commands->{env}() . qq{ $config->{runner} @_ } . $commands->{executable}() . qq{ $fork}, + sytee $config->{runner}, $commands->{env}(), qq{@_}, $commands->{executable}(), $fork, qq{$config->{logdir}/autotest.$g->{task_name}.server.out.log}; }, run_server => sub { - my $cmd = - $commands->{env}() - . qq{ $config->{runner} @_ } - . $commands->{executable}() - . qq{ --logfile $config->{logdir}/autotest.$g->{task_name}.game.log } - . options_make([qw(gameid world port config autoexit verbose)]) - . qq{ $config->{run_add}}; + my $cmd = join ' ', + $config->{runner}, + $commands->{env}(), + qq{@_}, + $commands->{executable}(), + qq{--logfile $config->{logdir}/autotest.$g->{task_name}.game.log}, + options_make([qw(gameid world port config autoexit verbose)]), + qq{$config->{run_add}}; + if ($config->{server_bg}) { return sf $cmd . qq{ $config->{tee} $config->{logdir}/autotest.$g->{task_name}.server.out.log}; } else { @@ -508,12 +517,14 @@ () local $config->{address} = '::1' if not $config->{address}; for ($config->{clients_start} .. $config->{clients_num}) { sleep $config->{clients_spawn_sleep} // 0.2; - sf $commands->{env}() - . qq{ $config->{runner} @_ } - . $commands->{executable}() - . qq{ --name $config->{name}$_ --go --autoexit $autoexit --logfile $config->{logdir}/autotest.$g->{task_name}.game.log } - . options_make([qw( address gameid world address port config verbose)]) - . qq{ $config->{run_add} $config->{tee} $config->{logdir}/autotest.$g->{task_name}.$config->{name}$_.err.log}; + sf + $config->{runner}, + $commands->{env}(), + qq{@_}, + $commands->{executable}(), + qq{--name $config->{name}$_ --go --autoexit $autoexit --logfile $config->{logdir}/autotest.$g->{task_name}.game.log}, + options_make([qw( address gameid world address port config verbose)]), + qq{$config->{run_add} $config->{tee} $config->{logdir}/autotest.$g->{task_name}.$config->{name}$_.err.log}; } sleep $config->{clients_sleep} || 1 if $config->{clients_runs}; } @@ -621,15 +632,6 @@ () '---cmake_usan' => 1, }, ], - gperf => [ - sub { - $g->{keep_config} = 1; - $g->{build_names}{san} = 'gperf'; - 0; - }, { - '---cmake_gperf' => 1, - }, - ], ( map { 'valgrind_' . $_ => [ @@ -670,6 +672,7 @@ () ' env ASAN_OPTIONS=abort_on_error=1 ' . $config->{runner} . $config->{gdb} + . q{ -ex 'set debuginfod enabled on' } . q{ -ex 'run' -ex 't a a bt' } . ($config->{gdb_stay} ? '' : q{ -ex 'cont' -ex 'quit' }) . q{ --args }; @@ -711,16 +714,8 @@ () 'clients', ], - gperf => [ - 'gperf_prepare', - sub { - $g->{keep_config} = 1; - push @$task_run, 'gperf_report'; - 0; - } - ], - gperf_prepare => [ + 'debug', {'---cmake_gperf' => 1,}, sub { $g->{keep_config} = 1; @@ -739,6 +734,22 @@ () } ], + gperf => [ + 'gperf_prepare', + sub { + #$g->{keep_config} = 1; + #$g->{build_names}{san} = 'gperf'; + my ($libprofiler) = `ls -1 /usr/lib/*/libprofiler.so | head -n1`; + $libprofiler =~ s/\s+$//; + if ($libprofiler and -f $libprofiler) { + $config->{envs}{gperf} .= " LD_PRELOAD=$libprofiler"; + } + push @$task_run, 'gperf_report'; + 0; + }, + # {'---cmake_gperf' => 1,}, + ], + stress_gperf => [ {'---server_bg' => 1,}, 'gperf', @@ -746,21 +757,24 @@ () ['sleep', 10], {'---cmake_gperf' => 0,}, 'clients', 'gperf_report', ], - gperf_report => sub { - # sytee 'env | grep PPROF_PATH', "$config->{logdir}/tmp"; - sytee qq{$config->{PPROF_PATH} $config->{gperf_mode} } . $commands->{executable}() . qq{ $config->{logdir}/heap.out*}, - "$config->{logdir}/gperf.heap.out" - if $config->{gperf_heapprofile}; - if ($config->{gperf_cpuprofile}) { - sytee qq{$config->{PPROF_PATH} $config->{gperf_mode} } . $commands->{executable}() . qq{ $config->{logdir}/cpu.out }, - "$config->{logdir}/gperf.cpu.out"; - sy qq{$config->{PPROF_PATH} --callgrind } - . $commands->{executable}() - . qq{ $config->{logdir}/cpu.out > $config->{logdir}/pprof.callgrind }; - say qq{kcachegrind $config->{logdir}/pprof.callgrind}; + gperf_report => [ + 'gperf_prepare', + sub { + # sytee 'env | grep PPROF_PATH', "$config->{logdir}/tmp"; + sytee qq{$config->{PPROF_PATH} $config->{gperf_mode} } . $commands->{executable}() . qq{ $config->{logdir}/heap.out*}, + "$config->{logdir}/gperf.heap.out" + if $config->{gperf_heapprofile}; + if ($config->{gperf_cpuprofile}) { + sytee qq{$config->{PPROF_PATH} $config->{gperf_mode} } . $commands->{executable}() . qq{ $config->{logdir}/cpu.out }, + "$config->{logdir}/gperf.cpu.out"; + sy qq{$config->{PPROF_PATH} --callgrind } + . $commands->{executable}() + . qq{ $config->{logdir}/cpu.out > $config->{logdir}/pprof.callgrind }; + say qq{kcachegrind $config->{logdir}/pprof.callgrind}; + } + return 0; } - return 0; - }, + ], play => [ 'set_client', @@ -770,7 +784,7 @@ () }, 'build', $config->{run_task} - ], + ], fly => [{'---options_int' => 'fly,forward',}, 'build_client', 'run_single'], timelapse_stay => [ 'timelapse', { @@ -779,7 +793,7 @@ () }, 'build_client', 'run_single', - ], + ], timelapse => [ {'---options_int' => 'timelapse',},