From b9d8e59bbf727fcc1a073bbf27e5d1703b9490ef Mon Sep 17 00:00:00 2001 From: kwolekr Date: Wed, 13 Feb 2013 22:43:15 -0500 Subject: Add emerge.cpp, initial EmergeThread changes - Neatly placed all emerge related code into a new file, emerge.cpp - Greatly cleaned up the code in EmergeThread::Thread() - Reworked Emerge queue. Now an actual std::queue of v3s16 block positions - Removed the completely unnecessary map of peer ids requesting blocks --- src/emerge.cpp | 677 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 677 insertions(+) create mode 100644 src/emerge.cpp (limited to 'src/emerge.cpp') diff --git a/src/emerge.cpp b/src/emerge.cpp new file mode 100644 index 000000000..728ea7196 --- /dev/null +++ b/src/emerge.cpp @@ -0,0 +1,677 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "server.h" +#include +#include +#include "clientserver.h" +#include "map.h" +#include "jmutexautolock.h" +#include "main.h" +#include "constants.h" +#include "voxel.h" +#include "config.h" +#include "mapblock.h" +#include "serverobject.h" +#include "settings.h" +#include "script.h" +#include "scriptapi.h" +#include "profiler.h" +#include "log.h" +#include "nodedef.h" +#include "biome.h" +#include "emerge.h" +#include "mapgen_v6.h" + + +EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { + //register built-in mapgens + registerMapgen("v6", new MapgenFactoryV6()); + + this->biomedef = bdef ? bdef : new BiomeDefManager(gamedef); + this->params = NULL; + this->mapgen = NULL; + + queuemutex.Init(); + emergethread = new EmergeThread((Server *)gamedef); +} + + +EmergeManager::~EmergeManager() { + emergethread->setRun(false); + emergethread->stop(); + + delete emergethread; + delete biomedef; + delete mapgen; + delete params; +} + + +void EmergeManager::initMapgens(MapgenParams *mgparams) { + if (mapgen) + return; + + this->params = mgparams; + this->mapgen = getMapgen(); //only one mapgen for now! +} + + +Mapgen *EmergeManager::getMapgen() { + if (!mapgen) { + mapgen = createMapgen(params->mg_name, 0, params, this); + if (!mapgen) { + infostream << "EmergeManager: falling back to mapgen v6" << std::endl; + delete params; + params = createMapgenParams("v6"); + mapgen = createMapgen("v6", 0, params, this); + } + } + return mapgen; +} + + +bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { ///return false if adding failed, or queue full! + u8 flags = 0; + + if (allow_generate) + flags |= BLOCK_EMERGE_ALLOWGEN; + + //TODO: + // add logic to select which emergethread to add it to + // - one with the least queue contents? + // - if a queue is too full, move onto another one + // - use the peer id sometime + + { + JMutexAutoLock queuelock(queuemutex); + + std::map::const_iterator iter = blocks_enqueued.find(p); + if (iter != blocks_enqueued.end()) { + flags |= iter->second; + blocks_enqueued[p] = flags; + return true; + } + + blocks_enqueued.insert(std::make_pair(p, flags)); + emergethread->blockqueue.push(p); + } + emergethread->qevent.signal(); + + return true; +} + + +bool EmergeManager::popBlockEmerge(v3s16 *pos, u8 *flags) { + JMutexAutoLock queuelock(queuemutex); + + if (emergethread->blockqueue.empty()) + return false; + v3s16 p = emergethread->blockqueue.front(); + emergethread->blockqueue.pop(); + + *pos = p; + + std::map::iterator iter = blocks_enqueued.find(p); + if (iter == blocks_enqueued.end()) //uh oh, this isn't right!!!!!!!!!!!!!!!!!! + return false; + + *flags = iter->second; + blocks_enqueued.erase(iter); + + return true; +} + + +int EmergeManager::getGroundLevelAtPoint(v2s16 p) { + if (!mapgen) + return 0; + return mapgen->getGroundLevelAtPoint(p); +} + + +bool EmergeManager::isBlockUnderground(v3s16 blockpos) { + /* + v2s16 p = v2s16((blockpos.X * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2, + (blockpos.Y * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2); + int ground_level = getGroundLevelAtPoint(p); + return blockpos.Y * (MAP_BLOCKSIZE + 1) <= min(water_level, ground_level); + */ + + //yuck, but then again, should i bother being accurate? + //the height of the nodes in a single block is quite variable + return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params->water_level; +} + + +u32 EmergeManager::getBlockSeed(v3s16 p) { + return (u32)(params->seed & 0xFFFFFFFF) + + p.Z * 38134234 + + p.Y * 42123 + + p.Y * 23; +} + + +Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid, + MapgenParams *mgparams, EmergeManager *emerge) { + std::map::const_iterator iter = mglist.find(mgname); + if (iter == mglist.end()) { + errorstream << "EmergeManager; mapgen " << mgname << + " not registered" << std::endl; + return NULL; + } + + MapgenFactory *mgfactory = iter->second; + return mgfactory->createMapgen(mgid, mgparams, emerge); +} + + +MapgenParams *EmergeManager::createMapgenParams(std::string mgname) { + std::map::const_iterator iter = mglist.find(mgname); + if (iter == mglist.end()) { + errorstream << "EmergeManager: mapgen " << mgname << + " not registered" << std::endl; + return NULL; + } + + MapgenFactory *mgfactory = iter->second; + return mgfactory->createMapgenParams(); +} + + +MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) { + std::string mg_name = settings->get("mg_name"); + MapgenParams *mgparams = createMapgenParams(mg_name); + + mgparams->mg_name = mg_name; + mgparams->seed = settings->getU64(settings == g_settings ? "fixed_map_seed" : "seed"); + mgparams->water_level = settings->getS16("water_level"); + mgparams->chunksize = settings->getS16("chunksize"); + mgparams->flags = settings->getS32("mg_flags"); + + if (!mgparams->readParams(settings)) { + delete mgparams; + return NULL; + } + return mgparams; +} + + +void EmergeManager::setParamsToSettings(Settings *settings) { + settings->set("mg_name", params->mg_name); + settings->setU64("seed", params->seed); + settings->setS16("water_level", params->water_level); + settings->setS16("chunksize", params->chunksize); + settings->setFlagStr("mg_flags", params->flags, flagdesc_mapgen); + + params->writeParams(settings); +} + + +bool EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory) { + mglist.insert(std::make_pair(mgname, mgfactory)); + infostream << "EmergeManager: registered mapgen " << mgname << std::endl; +} + + + +class MapEditEventIgnorer +{ +public: + MapEditEventIgnorer(bool *flag): + m_flag(flag) + { + if(*m_flag == false) + *m_flag = true; + else + m_flag = NULL; + } + + ~MapEditEventIgnorer() + { + if(m_flag) + { + assert(*m_flag); + *m_flag = false; + } + } + +private: + bool *m_flag; +}; + +class MapEditEventAreaIgnorer +{ +public: + MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): + m_ignorevariable(ignorevariable) + { + if(m_ignorevariable->getVolume() == 0) + *m_ignorevariable = a; + else + m_ignorevariable = NULL; + } + + ~MapEditEventAreaIgnorer() + { + if(m_ignorevariable) + { + assert(m_ignorevariable->getVolume() != 0); + *m_ignorevariable = VoxelArea(); + } + } + +private: + VoxelArea *m_ignorevariable; +}; + + +#if 1 + +#define EMERGE_DBG_OUT(x) \ + { if (enable_mapgen_debug_info) \ + infostream << "EmergeThread: " x << std::endl; } + +bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, + BlockMakeData *data, bool allow_gen) { + v2s16 p2d(p.X, p.Z); + //envlock: usually takes <=1ms, sometimes 90ms or ~400ms to acquire + JMutexAutoLock envlock(m_server->m_env_mutex); + + // Load sector if it isn't loaded + if (map->getSectorNoGenerateNoEx(p2d) == NULL) + map->loadSectorMeta(p2d); + + // Attempt to load block + MapBlock *block = map->getBlockNoCreateNoEx(p); + if (!block || block->isDummy() || !block->isGenerated()) { + EMERGE_DBG_OUT("not in memory, attempting to load from disk"); + block = map->loadBlock(p); + } + + // If could not load and allowed to generate, + // start generation inside this same envlock + if (allow_gen && (block == NULL || !block->isGenerated())) { + EMERGE_DBG_OUT("generating"); + map->initBlockMake(data, p); + return true; + } + + *b = block; + return false; +} + + +void *EmergeThread::Thread() { + ThreadStarted(); + log_register_thread("EmergeThread"); + DSTACK(__FUNCTION_NAME); + BEGIN_DEBUG_EXCEPTION_HANDLER + + v3s16 last_tried_pos(-32768,-32768,-32768); // For error output + v3s16 p; + u8 flags; + + map = (ServerMap *)&(m_server->m_env->getMap()); + emerge = m_server->m_emerge; + mapgen = emerge->getMapgen(); + + while (getRun()) + try { + while (!emerge->popBlockEmerge(&p, &flags)) + qevent.wait(); + + last_tried_pos = p; + if (blockpos_over_limit(p)) + continue; + + bool allow_generate = flags & BLOCK_EMERGE_ALLOWGEN; + EMERGE_DBG_OUT("p=" PP(p) " allow_generate=" << allow_generate); + + /* + Try to fetch block from memory or disk. + If not found and asked to generate, initialize generator. + */ + BlockMakeData data; + MapBlock *block = NULL; + core::map modified_blocks; + + if (getBlockOrStartGen(p, &block, &data, allow_generate)) { + { + ScopeProfiler sp(g_profiler, "EmergeThread: Mapgen::makeChunk", SPT_AVG); + TimeTaker t("mapgen::make_block()"); + + mapgen->makeChunk(&data); + + if (enable_mapgen_debug_info == false) + t.stop(true); // Hide output + } + + { + //envlock: usually 0ms, but can take either 30 or 400ms to acquire + JMutexAutoLock envlock(m_server->m_env_mutex); + ScopeProfiler sp(g_profiler, "EmergeThread: after " + "mapgen::make_block (envlock)", SPT_AVG); + + map->finishBlockMake(&data, modified_blocks); + + block = map->getBlockNoCreateNoEx(p); + if (block) { + /* + Do some post-generate stuff + */ + v3s16 minp = data.blockpos_min * MAP_BLOCKSIZE; + v3s16 maxp = data.blockpos_max * MAP_BLOCKSIZE + + v3s16(1,1,1) * (MAP_BLOCKSIZE - 1); + + // Ignore map edit events, they will not need to be sent + // to anybody because the block hasn't been sent to anybody + MapEditEventAreaIgnorer + ign(&m_server->m_ignore_map_edit_events_area, + VoxelArea(minp, maxp)); + { // takes about 90ms with -O1 on an e3-1230v2 + scriptapi_environment_on_generated(m_server->m_lua, + minp, maxp, emerge->getBlockSeed(minp)); + } + + EMERGE_DBG_OUT("ended up with: " << analyze_block(block)); + + m_server->m_env->activateBlock(block, 0); + } + } + } + + /* + Set sent status of modified blocks on clients + */ + + // NOTE: Server's clients are also behind the connection mutex + //conlock: consistently takes 30-40ms to acquire + JMutexAutoLock lock(m_server->m_con_mutex); + // Add the originally fetched block to the modified list + if (block) + modified_blocks.insert(p, block); + + // Set the modified blocks unsent for all the clients + for (core::map::Iterator + i = m_server->m_clients.getIterator(); + i.atEnd() == false; i++) { + RemoteClient *client = i.getNode()->getValue(); + if (modified_blocks.size() > 0) { + // Remove block from sent history + client->SetBlocksNotSent(modified_blocks); + } + } + } + catch (VersionMismatchException &e) { + std::ostringstream err; + err << "World data version mismatch in MapBlock "<setAsyncFatalError(err.str()); + } + catch (SerializationError &e) { + std::ostringstream err; + err << "Invalid data in MapBlock "<setAsyncFatalError(err.str()); + } + + END_DEBUG_EXCEPTION_HANDLER(errorstream) + log_deregister_thread(); + return NULL; +} + +#else + +void *EmergeThread::Thread() { + ThreadStarted(); + log_register_thread("EmergeThread"); + DSTACK(__FUNCTION_NAME); + BEGIN_DEBUG_EXCEPTION_HANDLER + + bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); + + v3s16 last_tried_pos(-32768,-32768,-32768); // For error output + ServerMap &map = ((ServerMap&)m_server->m_env->getMap()); + EmergeManager *emerge = m_server->m_emerge; + Mapgen *mapgen = emerge->getMapgen(); + + while(getRun()) + try { + QueuedBlockEmerge *qptr = m_server->m_emerge_queue.pop(); + if(qptr == NULL) + break; + SharedPtr q(qptr); + + v3s16 &p = q->pos; + v2s16 p2d(p.X,p.Z); + + last_tried_pos = p; + + /* + Do not generate over-limit + */ + if (blockpos_over_limit(p)) + continue; + + //infostream<<"EmergeThread::Thread(): running"<::Iterator i; + for (i=q->s.getIterator(); !i.atEnd(); i++) { + u8 flags = i.getNode()->getValue(); + if (!(flags & BLOCK_EMERGE_FLAG_FROMDISK)) { + only_from_disk = false; + break; + } + } + } + + if (enable_mapgen_debug_info) + infostream<<"EmergeThread: p=" + <<"("<isGenerated() == false)){ + if(enable_mapgen_debug_info) + infostream<<"EmergeThread: generating"<makeChunk(&data); + + if (enable_mapgen_debug_info == false) + t.stop(true); // Hide output + } + + do{ // enable break + // Lock environment again to access the map + JMutexAutoLock envlock(m_server->m_env_mutex); + + ScopeProfiler sp(g_profiler, "EmergeThread: after " + "mapgen::make_block (envlock)", SPT_AVG); + + // Blit data back on map, update lighting, add mobs and + // whatever this does + map.finishBlockMake(&data, modified_blocks); + + // Get central block + block = map.getBlockNoCreateNoEx(p); + + // If block doesn't exist, don't try doing anything with it + // This happens if the block is not in generation boundaries + if(!block) + break; + + /* + Do some post-generate stuff + */ + v3s16 minp = data.blockpos_min * MAP_BLOCKSIZE; + v3s16 maxp = data.blockpos_max * MAP_BLOCKSIZE + + v3s16(1,1,1) * (MAP_BLOCKSIZE - 1); + + /* + Ignore map edit events, they will not need to be + sent to anybody because the block hasn't been sent + to anybody + */ + MapEditEventAreaIgnorer ign( + &m_server->m_ignore_map_edit_events_area, + VoxelArea(minp, maxp)); + { + TimeTaker timer("on_generated"); + scriptapi_environment_on_generated(m_server->m_lua, + minp, maxp, emerge->getBlockSeed(minp)); + //int t = timer.stop(true); + //dstream<<"on_generated took "<m_env->activateBlock(block, 0); + }while(false); + } + + if(block == NULL) + got_block = false; + + /* + Set sent status of modified blocks on clients + */ + + // NOTE: Server's clients are also behind the connection mutex + JMutexAutoLock lock(m_server->m_con_mutex); + + /* + Add the originally fetched block to the modified list + */ + if(got_block) + modified_blocks.insert(p, block); + + /* + Set the modified blocks unsent for all the clients + */ + for(core::map::Iterator + i = m_server->m_clients.getIterator(); + i.atEnd() == false; i++) { + RemoteClient *client = i.getNode()->getValue(); + if(modified_blocks.size() > 0) { + // Remove block from sent history + client->SetBlocksNotSent(modified_blocks); + } + } + + +niters++; + } + catch (VersionMismatchException &e) { + std::ostringstream err; + err << "World data version mismatch in MapBlock "<setAsyncFatalError(err.str()); + } + catch (SerializationError &e) { + std::ostringstream err; + err << "Invalid data in MapBlock "<setAsyncFatalError(err.str()); + } +printf("emergethread iterated %d times\n", niters); + END_DEBUG_EXCEPTION_HANDLER(errorstream) + log_deregister_thread(); + return NULL; +} + +#endif -- cgit v1.2.3 From 3b7a445cd78c6b5ab301b5bf44e1ec54a00427f1 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 14 Feb 2013 18:32:56 -0500 Subject: Add global and per-peer queue limits --- src/emerge.cpp | 43 ++++++++++++++++++++++++++++++++++--------- src/emerge.h | 32 +++++++++++++++----------------- src/mapgen.h | 1 - 3 files changed, 49 insertions(+), 27 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/emerge.cpp b/src/emerge.cpp index 728ea7196..82867be50 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -88,7 +88,10 @@ Mapgen *EmergeManager::getMapgen() { } -bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { ///return false if adding failed, or queue full! +bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) { + std::map::const_iterator iter; + BlockEmergeData *bedata; + u16 count; u8 flags = 0; if (allow_generate) @@ -103,14 +106,30 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate { JMutexAutoLock queuelock(queuemutex); - std::map::const_iterator iter = blocks_enqueued.find(p); + count = blocks_enqueued.size(); + u16 queuelimit_total = 256; + if (count >= queuelimit_total) + return false; + + count = peer_queue_count[peer_id]; + u16 queuelimit_peer = allow_generate ? 1 : 5; + if (count >= queuelimit_peer) + return false; + + iter = blocks_enqueued.find(p); if (iter != blocks_enqueued.end()) { - flags |= iter->second; - blocks_enqueued[p] = flags; + bedata = iter->second; + bedata->flags |= flags; return true; } + + bedata = new BlockEmergeData; + bedata->flags = flags; + bedata->peer_requested = peer_id; + blocks_enqueued.insert(std::make_pair(p, bedata)); + + peer_queue_count[peer_id] = count + 1; - blocks_enqueued.insert(std::make_pair(p, flags)); emergethread->blockqueue.push(p); } emergethread->qevent.signal(); @@ -120,6 +139,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate bool EmergeManager::popBlockEmerge(v3s16 *pos, u8 *flags) { + std::map::iterator iter; JMutexAutoLock queuelock(queuemutex); if (emergethread->blockqueue.empty()) @@ -128,12 +148,17 @@ bool EmergeManager::popBlockEmerge(v3s16 *pos, u8 *flags) { emergethread->blockqueue.pop(); *pos = p; + + iter = blocks_enqueued.find(p); + if (iter == blocks_enqueued.end()) + return false; //uh oh, queue and map out of sync!! - std::map::iterator iter = blocks_enqueued.find(p); - if (iter == blocks_enqueued.end()) //uh oh, this isn't right!!!!!!!!!!!!!!!!!! - return false; + BlockEmergeData *bedata = iter->second; + *flags = bedata->flags; + + peer_queue_count[bedata->peer_requested]--; - *flags = iter->second; + delete bedata; blocks_enqueued.erase(iter); return true; diff --git a/src/emerge.h b/src/emerge.h index 0acc89a6d..5f73dcd86 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -14,8 +14,6 @@ class Biome; class BiomeDefManager; class EmergeThread; class ManualMapVoxelManipulator; -//class ServerMap; -//class MapBlock; #include "server.h" @@ -29,20 +27,19 @@ struct BlockMakeData { UniqueQueue transforming_liquid; INodeDefManager *nodedef; -// BlockMakeData(); -// ~BlockMakeData(); - -BlockMakeData(): - no_op(false), - vmanip(NULL), - seed(0), - nodedef(NULL) -{} - -~BlockMakeData() -{ - delete vmanip; -} + BlockMakeData(): + no_op(false), + vmanip(NULL), + seed(0), + nodedef(NULL) + {} + + ~BlockMakeData() { delete vmanip; } +}; + +struct BlockEmergeData { + u16 peer_requested; + u8 flags; }; class EmergeManager { @@ -53,7 +50,8 @@ public: MapgenParams *params; JMutex queuemutex; - std::map blocks_enqueued; //change to a hashtable later + std::map blocks_enqueued; + std::map peer_queue_count; Mapgen *mapgen; EmergeThread *emergethread; diff --git a/src/mapgen.h b/src/mapgen.h index c3c209ad1..911e87537 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapnode.h" #include "noise.h" #include "settings.h" -//#include "emerge.h" #include /////////////////// Mapgen flags -- cgit v1.2.3 From 206ec36c8e50a017636a70345b95f79feffb2446 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 14 Feb 2013 19:22:43 -0500 Subject: Fix EmergeThread hang on exit --- src/emerge.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/emerge.cpp b/src/emerge.cpp index 82867be50..e2b9e5a6c 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -56,6 +56,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { EmergeManager::~EmergeManager() { emergethread->setRun(false); + emergethread->qevent.signal(); emergethread->stop(); delete emergethread; @@ -360,8 +361,11 @@ void *EmergeThread::Thread() { while (getRun()) try { - while (!emerge->popBlockEmerge(&p, &flags)) + while (!emerge->popBlockEmerge(&p, &flags)) { qevent.wait(); + if (!getRun()) + goto exit_emerge_loop; + } last_tried_pos = p; if (blockpos_over_limit(p)) @@ -393,7 +397,7 @@ void *EmergeThread::Thread() { //envlock: usually 0ms, but can take either 30 or 400ms to acquire JMutexAutoLock envlock(m_server->m_env_mutex); ScopeProfiler sp(g_profiler, "EmergeThread: after " - "mapgen::make_block (envlock)", SPT_AVG); + "Mapgen::makeChunk (envlock)", SPT_AVG); map->finishBlockMake(&data, modified_blocks); @@ -465,6 +469,7 @@ void *EmergeThread::Thread() { } END_DEBUG_EXCEPTION_HANDLER(errorstream) +exit_emerge_loop: log_deregister_thread(); return NULL; } -- cgit v1.2.3 From 76217939e05bdd8d06fa7113902a74b02deeb915 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 14 Feb 2013 20:36:58 -0500 Subject: Add emerge queue limit configuration --- src/defaultsettings.cpp | 4 ++++ src/emerge.cpp | 17 +++++++---------- src/emerge.h | 13 +++++++++---- 3 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 610dd65a4..f18e9b1e0 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -184,6 +184,10 @@ void set_default_settings(Settings *settings) settings->setDefault("congestion_control_min_rate", "10"); settings->setDefault("remote_media", ""); settings->setDefault("debug_log_level", "0"); + settings->setDefault("emergequeue_limit_total", "256"); + settings->setDefault("emergequeue_limit_diskonly", "5"); + settings->setDefault("emergequeue_limit_generate", "1"); + // physics stuff settings->setDefault("movement_acceleration_default", "3"); settings->setDefault("movement_acceleration_air", "2"); diff --git a/src/emerge.cpp b/src/emerge.cpp index e2b9e5a6c..b785c8688 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -49,6 +49,10 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { this->params = NULL; this->mapgen = NULL; + qlimit_total = g_settings->getU16("emergequeue_limit_total"); + qlimit_diskonly = g_settings->getU16("emergequeue_limit_diskonly"); + qlimit_generate = g_settings->getU16("emergequeue_limit_generate"); + queuemutex.Init(); emergethread = new EmergeThread((Server *)gamedef); } @@ -98,23 +102,16 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate if (allow_generate) flags |= BLOCK_EMERGE_ALLOWGEN; - //TODO: - // add logic to select which emergethread to add it to - // - one with the least queue contents? - // - if a queue is too full, move onto another one - // - use the peer id sometime - { JMutexAutoLock queuelock(queuemutex); count = blocks_enqueued.size(); - u16 queuelimit_total = 256; - if (count >= queuelimit_total) + if (count >= qlimit_total) return false; count = peer_queue_count[peer_id]; - u16 queuelimit_peer = allow_generate ? 1 : 5; - if (count >= queuelimit_peer) + u16 qlimit_peer = allow_generate ? qlimit_generate : qlimit_diskonly; + if (count >= qlimit_peer) return false; iter = blocks_enqueued.find(p); diff --git a/src/emerge.h b/src/emerge.h index 5f73dcd86..b4461ae61 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -45,15 +45,20 @@ struct BlockEmergeData { class EmergeManager { public: std::map mglist; - + + Mapgen *mapgen; + EmergeThread *emergethread; + //settings MapgenParams *params; - + u16 qlimit_total; + u16 qlimit_diskonly; + u16 qlimit_generate; + + //block emerge queue data structures JMutex queuemutex; std::map blocks_enqueued; std::map peer_queue_count; - Mapgen *mapgen; - EmergeThread *emergethread; //biome manager BiomeDefManager *biomedef; -- cgit v1.2.3 From 5ec5b1cbd64a22e628be2cf03391883c44074811 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 17 Feb 2013 01:47:49 -0500 Subject: Add multi-Emerge thread support --- src/defaultsettings.cpp | 1 + src/emerge.cpp | 99 ++++++++++++++++++++++++++++++------------------- src/emerge.h | 15 ++++---- src/map.cpp | 65 +++++++++++++++++++++++++------- src/map.h | 13 ++++--- src/porting.cpp | 23 ++++++++++++ src/porting.h | 5 +++ src/server.cpp | 3 +- 8 files changed, 160 insertions(+), 64 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index f18e9b1e0..219cda9e7 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -187,6 +187,7 @@ void set_default_settings(Settings *settings) settings->setDefault("emergequeue_limit_total", "256"); settings->setDefault("emergequeue_limit_diskonly", "5"); settings->setDefault("emergequeue_limit_generate", "1"); + settings->setDefault("num_emerge_threads", ""); // physics stuff settings->setDefault("movement_acceleration_default", "3"); diff --git a/src/emerge.cpp b/src/emerge.cpp index b785c8688..ee6650f9c 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -47,49 +47,56 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { this->biomedef = bdef ? bdef : new BiomeDefManager(gamedef); this->params = NULL; - this->mapgen = NULL; qlimit_total = g_settings->getU16("emergequeue_limit_total"); qlimit_diskonly = g_settings->getU16("emergequeue_limit_diskonly"); qlimit_generate = g_settings->getU16("emergequeue_limit_generate"); queuemutex.Init(); - emergethread = new EmergeThread((Server *)gamedef); + int nthreads = g_settings->get("num_emerge_threads").empty() ? + porting::getNumberOfProcessors() : + g_settings->getU16("num_emerge_threads"); + if (nthreads < 1) + nthreads = 1; + + for (int i = 0; i != nthreads; i++) + emergethread.push_back(new EmergeThread((Server *)gamedef, i)); + + infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } EmergeManager::~EmergeManager() { - emergethread->setRun(false); - emergethread->qevent.signal(); - emergethread->stop(); + for (int i = 0; i != emergethread.size(); i++) { + emergethread[i]->setRun(false); + emergethread[i]->qevent.signal(); + emergethread[i]->stop(); + delete emergethread[i]; + delete mapgen[i]; + } - delete emergethread; delete biomedef; - delete mapgen; delete params; } void EmergeManager::initMapgens(MapgenParams *mgparams) { - if (mapgen) + Mapgen *mg; + + if (mapgen.size()) return; this->params = mgparams; - this->mapgen = getMapgen(); //only one mapgen for now! -} - - -Mapgen *EmergeManager::getMapgen() { - if (!mapgen) { - mapgen = createMapgen(params->mg_name, 0, params, this); - if (!mapgen) { + for (int i = 0; i != emergethread.size(); i++) { + mg = createMapgen(params->mg_name, 0, params); + if (!mg) { infostream << "EmergeManager: falling back to mapgen v6" << std::endl; delete params; params = createMapgenParams("v6"); - mapgen = createMapgen("v6", 0, params, this); + mg = createMapgen("v6", 0, params); } + mapgen.push_back(mg); } - return mapgen; } @@ -98,6 +105,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate BlockEmergeData *bedata; u16 count; u8 flags = 0; + int idx = 0; if (allow_generate) flags |= BLOCK_EMERGE_ALLOWGEN; @@ -128,45 +136,58 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate peer_queue_count[peer_id] = count + 1; - emergethread->blockqueue.push(p); + int lowestitems = emergethread[0]->blockqueue.size(); + for (int i = 1; i != emergethread.size(); i++) { + int nitems = emergethread[i]->blockqueue.size(); + if (nitems < lowestitems) { + idx = i; + lowestitems = nitems; + } + } + + emergethread[idx]->blockqueue.push(p); } - emergethread->qevent.signal(); + emergethread[idx]->qevent.signal(); return true; } -bool EmergeManager::popBlockEmerge(v3s16 *pos, u8 *flags) { +bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) { std::map::iterator iter; - JMutexAutoLock queuelock(queuemutex); + JMutexAutoLock queuelock(emerge->queuemutex); - if (emergethread->blockqueue.empty()) + if (blockqueue.empty()) return false; - v3s16 p = emergethread->blockqueue.front(); - emergethread->blockqueue.pop(); + v3s16 p = blockqueue.front(); + blockqueue.pop(); *pos = p; - iter = blocks_enqueued.find(p); - if (iter == blocks_enqueued.end()) + iter = emerge->blocks_enqueued.find(p); + if (iter == emerge->blocks_enqueued.end()) return false; //uh oh, queue and map out of sync!! BlockEmergeData *bedata = iter->second; *flags = bedata->flags; - peer_queue_count[bedata->peer_requested]--; + emerge->peer_queue_count[bedata->peer_requested]--; delete bedata; - blocks_enqueued.erase(iter); + emerge->blocks_enqueued.erase(iter); return true; } int EmergeManager::getGroundLevelAtPoint(v2s16 p) { - if (!mapgen) + if (!mapgen[0]) { + errorstream << "EmergeManager: getGroundLevelAtPoint() called" + " before mapgen initialized" << std::endl; return 0; - return mapgen->getGroundLevelAtPoint(p); + } + + return mapgen[0]->getGroundLevelAtPoint(p); } @@ -193,8 +214,9 @@ u32 EmergeManager::getBlockSeed(v3s16 p) { Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid, - MapgenParams *mgparams, EmergeManager *emerge) { - std::map::const_iterator iter = mglist.find(mgname); + MapgenParams *mgparams) { + std::map::const_iterator iter; + iter = mglist.find(mgname); if (iter == mglist.end()) { errorstream << "EmergeManager; mapgen " << mgname << " not registered" << std::endl; @@ -202,12 +224,13 @@ Mapgen *EmergeManager::createMapgen(std::string mgname, int mgid, } MapgenFactory *mgfactory = iter->second; - return mgfactory->createMapgen(mgid, mgparams, emerge); + return mgfactory->createMapgen(mgid, mgparams, this); } MapgenParams *EmergeManager::createMapgenParams(std::string mgname) { - std::map::const_iterator iter = mglist.find(mgname); + std::map::const_iterator iter; + iter = mglist.find(mgname); if (iter == mglist.end()) { errorstream << "EmergeManager: mapgen " << mgname << " not registered" << std::endl; @@ -227,7 +250,7 @@ MapgenParams *EmergeManager::getParamsFromSettings(Settings *settings) { mgparams->seed = settings->getU64(settings == g_settings ? "fixed_map_seed" : "seed"); mgparams->water_level = settings->getS16("water_level"); mgparams->chunksize = settings->getS16("chunksize"); - mgparams->flags = settings->getS32("mg_flags"); + mgparams->flags = settings->getFlagStr("mg_flags", flagdesc_mapgen); if (!mgparams->readParams(settings)) { delete mgparams; @@ -354,11 +377,11 @@ void *EmergeThread::Thread() { map = (ServerMap *)&(m_server->m_env->getMap()); emerge = m_server->m_emerge; - mapgen = emerge->getMapgen(); + mapgen = emerge->mapgen[id]; //emerge->getMapgen(); while (getRun()) try { - while (!emerge->popBlockEmerge(&p, &flags)) { + while (!popBlockEmerge(&p, &flags)) { qevent.wait(); if (!getRun()) goto exit_emerge_loop; diff --git a/src/emerge.h b/src/emerge.h index b4461ae61..7e0cc4850 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -46,8 +46,8 @@ class EmergeManager { public: std::map mglist; - Mapgen *mapgen; - EmergeThread *emergethread; + std::vector mapgen; + std::vector emergethread; //settings MapgenParams *params; @@ -68,11 +68,9 @@ public: void initMapgens(MapgenParams *mgparams); Mapgen *createMapgen(std::string mgname, int mgid, - MapgenParams *mgparams, EmergeManager *emerge); + MapgenParams *mgparams); MapgenParams *createMapgenParams(std::string mgname); - Mapgen *getMapgen(); bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate); - bool popBlockEmerge(v3s16 *pos, u8 *flags); bool registerMapgen(std::string name, MapgenFactory *mgfactory); MapgenParams *getParamsFromSettings(Settings *settings); @@ -92,17 +90,19 @@ class EmergeThread : public SimpleThread EmergeManager *emerge; Mapgen *mapgen; bool enable_mapgen_debug_info; + int id; public: Event qevent; std::queue blockqueue; - EmergeThread(Server *server): + EmergeThread(Server *server, int ethreadid): SimpleThread(), m_server(server), map(NULL), emerge(NULL), - mapgen(NULL) + mapgen(NULL), + id(ethreadid) { enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); } @@ -118,6 +118,7 @@ public: } } + bool popBlockEmerge(v3s16 *pos, u8 *flags); bool getBlockOrStartGen(v3s16 p, MapBlock **b, BlockMakeData *data, bool allow_generate); }; diff --git a/src/map.cpp b/src/map.cpp index 7eb45463f..a8928d864 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2009,7 +2009,7 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer m_mgparams = m_emerge->getParamsFromSettings(g_settings); if (!m_mgparams) m_mgparams = new MapgenV6Params(); - + m_seed = m_mgparams->seed; if (g_settings->get("fixed_map_seed").empty()) @@ -2246,6 +2246,21 @@ void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) //TimeTaker timer("initBlockMake() initialEmerge"); data->vmanip->initialEmerge(bigarea_blocks_min, bigarea_blocks_max); } + + // Ensure none of the blocks to be generated were marked as containing CONTENT_IGNORE + for (s16 z = blockpos_min.Z; z <= blockpos_max.Z; z++) { + for (s16 y = blockpos_min.Y; y <= blockpos_max.Y; y++) { + for (s16 x = blockpos_min.X; x <= blockpos_max.X; x++) { + core::map::Node *n; + n = data->vmanip->m_loaded_blocks.find(v3s16(x, y, z)); + if (n == NULL) + continue; + u8 flags = n->getValue(); + flags &= ~VMANIP_BLOCK_CONTAINS_CIGNORE; + n->setValue(flags); + } + } + } // Data is ready now. } @@ -3672,8 +3687,10 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) for(s32 y=p_min.Y; y<=p_max.Y; y++) for(s32 x=p_min.X; x<=p_max.X; x++) { + u8 flags = 0; + MapBlock *block; v3s16 p(x,y,z); - core::map::Node *n; + core::map::Node *n; n = m_loaded_blocks.find(p); if(n != NULL) continue; @@ -3689,7 +3706,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) a.print(infostream); infostream<getBlockNoCreate(p); + block = m_map->getBlockNoCreate(p); if(block->isDummy()) block_data_inexistent = true; else @@ -3702,6 +3719,8 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) if(block_data_inexistent) { + flags |= VMANIP_BLOCK_DATA_INEXIST; + VoxelArea a(p*MAP_BLOCKSIZE, (p+1)*MAP_BLOCKSIZE-v3s16(1,1,1)); // Fill with VOXELFLAG_INEXISTENT for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++) @@ -3711,8 +3730,13 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) memset(&m_flags[i], VOXELFLAG_INEXISTENT, MAP_BLOCKSIZE); } } + else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE) + { + // Mark that block was loaded as blank + flags |= VMANIP_BLOCK_CONTAINS_CIGNORE; + } - m_loaded_blocks.insert(p, !block_data_inexistent); + m_loaded_blocks.insert(p, flags); } //infostream<<"emerge done"<::Node *n; + core::map::Node *n; n = m_loaded_blocks.find(p); if(n != NULL) continue; @@ -3843,7 +3869,7 @@ void ManualMapVoxelManipulator::initialEmerge( { TimeTaker timer1("emerge load", &emerge_load_time); - MapBlock *block = m_map->getBlockNoCreate(p); + block = m_map->getBlockNoCreate(p); if(block->isDummy()) block_data_inexistent = true; else @@ -3856,6 +3882,8 @@ void ManualMapVoxelManipulator::initialEmerge( if(block_data_inexistent) { + flags |= VMANIP_BLOCK_DATA_INEXIST; + /* Mark area inexistent */ @@ -3868,8 +3896,13 @@ void ManualMapVoxelManipulator::initialEmerge( memset(&m_flags[i], VOXELFLAG_INEXISTENT, MAP_BLOCKSIZE); } } + else if (block->getNode(0, 0, 0).getContent() == CONTENT_IGNORE) + { + // Mark that block was loaded as blank + flags |= VMANIP_BLOCK_CONTAINS_CIGNORE; + } - m_loaded_blocks.insert(p, !block_data_inexistent); + m_loaded_blocks.insert(p, flags); } } @@ -3882,12 +3915,14 @@ void ManualMapVoxelManipulator::blitBackAll( /* Copy data of all blocks */ - for(core::map::Iterator + for(core::map::Iterator i = m_loaded_blocks.getIterator(); i.atEnd() == false; i++) { v3s16 p = i.getNode()->getKey(); - bool existed = i.getNode()->getValue(); + u8 flags = i.getNode()->getValue(); + + bool existed = !(flags & VMANIP_BLOCK_DATA_INEXIST); if(existed == false) { // The Great Bug was found using this @@ -3896,6 +3931,7 @@ void ManualMapVoxelManipulator::blitBackAll( <getBlockNoCreateNoEx(p); if(block == NULL) { @@ -3906,10 +3942,13 @@ void ManualMapVoxelManipulator::blitBackAll( continue; } - block->copyFrom(*this); - - if(modified_blocks) - modified_blocks->insert(p, block); + bool no_content_ignore = !(flags & VMANIP_BLOCK_CONTAINS_CIGNORE); + if (no_content_ignore) + { + block->copyFrom(*this); + if(modified_blocks) + modified_blocks->insert(p, block); + } } } diff --git a/src/map.h b/src/map.h index 0b2311f39..1062f8301 100644 --- a/src/map.h +++ b/src/map.h @@ -517,6 +517,9 @@ private: sqlite3_stmt *m_database_list; }; +#define VMANIP_BLOCK_DATA_INEXIST 1 +#define VMANIP_BLOCK_CONTAINS_CIGNORE 2 + class MapVoxelManipulator : public VoxelManipulator { public: @@ -532,14 +535,14 @@ public: virtual void emerge(VoxelArea a, s32 caller_id=-1); void blitBack(core::map & modified_blocks); - -protected: - Map *m_map; + /* key = blockpos - value = block existed when loaded + value = flags describing the block */ - core::map m_loaded_blocks; + core::map m_loaded_blocks; +protected: + Map *m_map; }; class ManualMapVoxelManipulator : public MapVoxelManipulator diff --git a/src/porting.cpp b/src/porting.cpp index 7ad557833..58d71e4aa 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -131,6 +131,29 @@ void signal_handler_init(void) #endif +/* + Multithreading support +*/ +int getNumberOfProcessors() { + #if defined(_SC_NPROCESSORS_ONLN) + return sysconf(_SC_NPROCESSORS_ONLN); + #elif defined(__FreeBSD__) || defined(__APPLE__) + unsigned int len, count; + len = sizeof(count); + return sysctlbyname("hw.ncpu", &count, &len, NULL, 0); + #elif defined(_GNU_SOURCE) + return get_nprocs(); + #elif defined(_WIN32) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; + #elif defined(PTW32_VERSION) || defined(__hpux) + return pthread_num_processors_np(); + #else + return 1; + #endif +} + /* Path mangler */ diff --git a/src/porting.h b/src/porting.h index 13b715557..53aad6171 100644 --- a/src/porting.h +++ b/src/porting.h @@ -103,6 +103,11 @@ std::string getDataPath(const char *subpath); */ void initializePaths(); +/* + Get number of online processors in the system. +*/ +int getNumberOfProcessors(); + /* Resolution is 10-20ms. Remember to check for overflows. diff --git a/src/server.cpp b/src/server.cpp index f2897d46d..5021718a3 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1649,7 +1649,8 @@ void Server::AsyncRunStep() { counter = 0.0; - m_emerge->emergethread->trigger(); + for (int i = 0; i != m_emerge->emergethread.size(); i++) + m_emerge->emergethread[i]->trigger(); // Update m_enable_rollback_recording here too m_enable_rollback_recording = -- cgit v1.2.3 From 67c59645ecd76cbf7a8186d0850ab5950e9ea22a Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sun, 17 Feb 2013 02:46:08 -0500 Subject: Misc. cleanup and minor fixes --- src/emerge.cpp | 21 +++++++++------------ src/emerge.h | 8 +++++--- src/map.cpp | 29 +++++++---------------------- src/map.h | 2 +- src/mapgen_v6.cpp | 7 +------ 5 files changed, 23 insertions(+), 44 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/emerge.cpp b/src/emerge.cpp index ee6650f9c..ac654f368 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -48,6 +48,8 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { this->biomedef = bdef ? bdef : new BiomeDefManager(gamedef); this->params = NULL; + mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); + qlimit_total = g_settings->getU16("emergequeue_limit_total"); qlimit_diskonly = g_settings->getU16("emergequeue_limit_diskonly"); qlimit_generate = g_settings->getU16("emergequeue_limit_generate"); @@ -209,7 +211,7 @@ u32 EmergeManager::getBlockSeed(v3s16 p) { return (u32)(params->seed & 0xFFFFFFFF) + p.Z * 38134234 + p.Y * 42123 + - p.Y * 23; + p.X * 23; } @@ -331,10 +333,6 @@ private: #if 1 -#define EMERGE_DBG_OUT(x) \ - { if (enable_mapgen_debug_info) \ - infostream << "EmergeThread: " x << std::endl; } - bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, BlockMakeData *data, bool allow_gen) { v2s16 p2d(p.X, p.Z); @@ -356,8 +354,8 @@ bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, // start generation inside this same envlock if (allow_gen && (block == NULL || !block->isGenerated())) { EMERGE_DBG_OUT("generating"); - map->initBlockMake(data, p); - return true; + *b = block; + return map->initBlockMake(data, p); } *b = block; @@ -377,14 +375,14 @@ void *EmergeThread::Thread() { map = (ServerMap *)&(m_server->m_env->getMap()); emerge = m_server->m_emerge; - mapgen = emerge->mapgen[id]; //emerge->getMapgen(); + mapgen = emerge->mapgen[id]; + enable_mapgen_debug_info = emerge->mapgen_debug_info; while (getRun()) try { - while (!popBlockEmerge(&p, &flags)) { + if (!popBlockEmerge(&p, &flags)) { qevent.wait(); - if (!getRun()) - goto exit_emerge_loop; + continue; } last_tried_pos = p; @@ -489,7 +487,6 @@ void *EmergeThread::Thread() { } END_DEBUG_EXCEPTION_HANDLER(errorstream) -exit_emerge_loop: log_deregister_thread(); return NULL; } diff --git a/src/emerge.h b/src/emerge.h index 7e0cc4850..e5014df58 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -7,6 +7,10 @@ #define BLOCK_EMERGE_ALLOWGEN (1<<0) +#define EMERGE_DBG_OUT(x) \ + { if (enable_mapgen_debug_info) \ + infostream << "EmergeThread: " x << std::endl; } + class Mapgen; class MapgenParams; class MapgenFactory; @@ -18,7 +22,6 @@ class ManualMapVoxelManipulator; #include "server.h" struct BlockMakeData { - bool no_op; ManualMapVoxelManipulator *vmanip; u64 seed; v3s16 blockpos_min; @@ -28,7 +31,6 @@ struct BlockMakeData { INodeDefManager *nodedef; BlockMakeData(): - no_op(false), vmanip(NULL), seed(0), nodedef(NULL) @@ -51,6 +53,7 @@ public: //settings MapgenParams *params; + bool mapgen_debug_info; u16 qlimit_total; u16 qlimit_diskonly; u16 qlimit_generate; @@ -104,7 +107,6 @@ public: mapgen(NULL), id(ethreadid) { - enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); } void *Thread(); diff --git a/src/map.cpp b/src/map.cpp index a8928d864..3f2f8d1d3 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2143,14 +2143,10 @@ ServerMap::~ServerMap() #endif } -void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) +bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) { - bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); - if(enable_mapgen_debug_info) - infostream<<"initBlockMake(): " - <<"("<mapgen_debug_info; + EMERGE_DBG_OUT("initBlockMake(): " PP(blockpos) " - " PP(blockpos)); //s16 chunksize = 3; //v3s16 chunk_offset(-1,-1,-1); @@ -2170,12 +2166,8 @@ void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) // Do nothing if not inside limits (+-1 because of neighbors) if(blockpos_over_limit(blockpos_min - extra_borders) || blockpos_over_limit(blockpos_max + extra_borders)) - { - data->no_op = true; - return; - } + return false; - data->no_op = false; data->seed = m_seed; data->blockpos_min = blockpos_min; data->blockpos_max = blockpos_max; @@ -2263,6 +2255,7 @@ void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) } // Data is ready now. + return true; } MapBlock* ServerMap::finishBlockMake(BlockMakeData *data, @@ -2277,13 +2270,7 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data, v3s16 extra_borders(1,1,1); - if(data->no_op) - { - //infostream<<"finishBlockMake(): no-op"<getBool("enable_mapgen_debug_info"); + bool enable_mapgen_debug_info = m_emerge->mapgen_debug_info; /*infostream<<"Resulting vmanip:"<vmanip.print(infostream);*/ @@ -2311,9 +2298,7 @@ MapBlock* ServerMap::finishBlockMake(BlockMakeData *data, data->vmanip->blitBackAll(&changed_blocks); } - if(enable_mapgen_debug_info) - infostream<<"finishBlockMake: changed_blocks.size()=" - <generating = true; assert(data->vmanip); @@ -1436,4 +1430,5 @@ void MapgenV6::makeChunk(BlockMakeData *data) vmanip.spreadLight(bank, light_sources, ndef); } } + this->generating = false; } -- cgit v1.2.3 From 60e6284f30d31e11c1a464d9a8b3c5c392ceb3f0 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Thu, 21 Feb 2013 17:44:14 -0500 Subject: Tune queue limits, some other adjustments --- src/defaultsettings.cpp | 4 +- src/emerge.cpp | 30 +++++++---- src/porting.cpp | 132 +++++++++++++++++++++++++++++++++++++++++------- src/porting.h | 37 +++++++++++++- 4 files changed, 174 insertions(+), 29 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 219cda9e7..0e82c4e2f 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -185,8 +185,8 @@ void set_default_settings(Settings *settings) settings->setDefault("remote_media", ""); settings->setDefault("debug_log_level", "0"); settings->setDefault("emergequeue_limit_total", "256"); - settings->setDefault("emergequeue_limit_diskonly", "5"); - settings->setDefault("emergequeue_limit_generate", "1"); + settings->setDefault("emergequeue_limit_diskonly", ""); + settings->setDefault("emergequeue_limit_generate", ""); settings->setDefault("num_emerge_threads", ""); // physics stuff diff --git a/src/emerge.cpp b/src/emerge.cpp index ac654f368..dd97734c5 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -49,18 +49,29 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { this->params = NULL; mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); - - qlimit_total = g_settings->getU16("emergequeue_limit_total"); - qlimit_diskonly = g_settings->getU16("emergequeue_limit_diskonly"); - qlimit_generate = g_settings->getU16("emergequeue_limit_generate"); queuemutex.Init(); - int nthreads = g_settings->get("num_emerge_threads").empty() ? - porting::getNumberOfProcessors() : - g_settings->getU16("num_emerge_threads"); + + int nthreads; + if (g_settings->get("num_emerge_threads").empty()) { + int nprocs = porting::getNumberOfProcessors(); + // leave a proc for the main thread and one for some other misc threads + if (nprocs > 2) + nthreads = nprocs - 2; + } else { + nthreads = g_settings->getU16("num_emerge_threads"); + } if (nthreads < 1) nthreads = 1; + qlimit_total = g_settings->getU16("emergequeue_limit_total"); + qlimit_diskonly = g_settings->get("emergequeue_limit_diskonly").empty() ? + nthreads * 5 + 1 : + g_settings->getU16("emergequeue_limit_diskonly"); + qlimit_generate = g_settings->get("emergequeue_limit_generate").empty() ? + nthreads + 1 : + g_settings->getU16("emergequeue_limit_generate"); + for (int i = 0; i != nthreads; i++) emergethread.push_back(new EmergeThread((Server *)gamedef, i)); @@ -138,6 +149,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate peer_queue_count[peer_id] = count + 1; + // insert into the EmergeThread queue with the least items int lowestitems = emergethread[0]->blockqueue.size(); for (int i = 1; i != emergethread.size(); i++) { int nitems = emergethread[i]->blockqueue.size(); @@ -183,7 +195,7 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) { int EmergeManager::getGroundLevelAtPoint(v2s16 p) { - if (!mapgen[0]) { + if (mapgen.size() == 0 || !mapgen[0]) { errorstream << "EmergeManager: getGroundLevelAtPoint() called" " before mapgen initialized" << std::endl; return 0; @@ -365,7 +377,7 @@ bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, void *EmergeThread::Thread() { ThreadStarted(); - log_register_thread("EmergeThread"); + log_register_thread("EmergeThread" + id); DSTACK(__FUNCTION_NAME); BEGIN_DEBUG_EXCEPTION_HANDLER diff --git a/src/porting.cpp b/src/porting.cpp index 58d71e4aa..84df15b30 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -131,29 +131,127 @@ void signal_handler_init(void) #endif + /* Multithreading support */ int getNumberOfProcessors() { - #if defined(_SC_NPROCESSORS_ONLN) - return sysconf(_SC_NPROCESSORS_ONLN); - #elif defined(__FreeBSD__) || defined(__APPLE__) - unsigned int len, count; - len = sizeof(count); - return sysctlbyname("hw.ncpu", &count, &len, NULL, 0); - #elif defined(_GNU_SOURCE) - return get_nprocs(); - #elif defined(_WIN32) - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; - #elif defined(PTW32_VERSION) || defined(__hpux) - return pthread_num_processors_np(); - #else - return 1; - #endif +#if defined(_SC_NPROCESSORS_ONLN) + + return sysconf(_SC_NPROCESSORS_ONLN); + +#elif defined(__FreeBSD__) || defined(__APPLE__) + + unsigned int len, count; + len = sizeof(count); + return sysctlbyname("hw.ncpu", &count, &len, NULL, 0); + +#elif defined(_GNU_SOURCE) + + return get_nprocs(); + +#elif defined(_WIN32) + + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; + +#elif defined(PTW32_VERSION) || defined(__hpux) + + return pthread_num_processors_np(); + +#else + + return 1; + +#endif } + +bool threadBindToProcessor(threadid_t tid, int pnumber) { +#if defined(_WIN32) + + HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid); + if (!hThread) + return false; + + bool success = SetThreadAffinityMask(hThread, 1 << pnumber) != 0; + + CloseHandle(hThread); + return success; + +#elif (defined(__FreeBSD__) && (__FreeBSD_version >= 702106)) \ + || defined(__linux) || defined(linux) + + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(pnumber, &cpuset); + return pthread_setaffinity_np(tid, sizeof(cpuset), &cpuset) == 0; + +#elif defined(__sun) || defined(sun) + + return processor_bind(P_LWPID, MAKE_LWPID_PTHREAD(tid), + pnumber, NULL) == 0; + +#elif defined(_AIX) + + return bindprocessor(BINDTHREAD, (tid_t)tid, pnumber) == 0; + +#elif defined(__hpux) || defined(hpux) + + pthread_spu_t answer; + + return pthread_processor_bind_np(PTHREAD_BIND_ADVISORY_NP, + &answer, pnumber, tid) == 0; + +#elif defined(__APPLE__) + + struct thread_affinity_policy tapol; + + thread_port_t threadport = pthread_mach_thread_np(tid); + tapol.affinity_tag = pnumber + 1; + return thread_policy_set(threadport, THREAD_AFFINITY_POLICY, + (thread_policy_t)&tapol, THREAD_AFFINITY_POLICY_COUNT) == KERN_SUCCESS; + +#else + + return false; + +#endif +} + + +bool threadSetPriority(threadid_t tid, int prio) { +#if defined(_WIN32) + + HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, 0, tid); + if (!hThread) + return false; + + bool success = SetThreadPriority(hThread, prio) != 0; + + CloseHandle(hThread); + return success; + +#else + + struct sched_param sparam; + int policy; + + if (pthread_getschedparam(tid, &policy, &sparam) != 0) + return false; + + int min = sched_get_priority_min(policy); + int max = sched_get_priority_max(policy); + + sparam.sched_priority = min + prio * (max - min) / THREAD_PRIORITY_HIGHEST; + return pthread_setschedparam(tid, policy, &sparam) == 0; + +#endif +} + + /* Path mangler */ diff --git a/src/porting.h b/src/porting.h index 53aad6171..74ee97f88 100644 --- a/src/porting.h +++ b/src/porting.h @@ -46,8 +46,33 @@ with this program; if not, write to the Free Software Foundation, Inc., #else #include #include //for uintptr_t - + + #if defined(linux) || defined(__linux) + #define _GNU_SOURCE + #endif + + #include + + #ifdef __FreeBSD__ + #include + typedef cpuset_t cpu_set_t; + #elif defined(__sun) || defined(sun) + #include + #include + #elif defined(_AIX) + #include + #elif __APPLE__ + #include + #include + #endif + #define sleep_ms(x) usleep(x*1000) + + #define THREAD_PRIORITY_LOWEST 0 + #define THREAD_PRIORITY_BELOW_NORMAL 1 + #define THREAD_PRIORITY_NORMAL 2 + #define THREAD_PRIORITY_ABOVE_NORMAL 3 + #define THREAD_PRIORITY_HIGHEST 4 #endif #ifdef _MSC_VER @@ -108,6 +133,16 @@ void initializePaths(); */ int getNumberOfProcessors(); +/* + Set a thread's affinity to a particular processor. +*/ +bool threadBindToProcessor(threadid_t tid, int pnumber); + +/* + Set a thread's priority. +*/ +bool threadSetPriority(threadid_t tid, int prio); + /* Resolution is 10-20ms. Remember to check for overflows. -- cgit v1.2.3 From f00d136ab1523297fdf4707bbc5d40ec9d4f7afb Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 23 Feb 2013 22:06:16 -0500 Subject: Fix selection of # threads, set default to 1 thread --- src/defaultsettings.cpp | 2 +- src/emerge.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 0e82c4e2f..4307f7610 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -187,7 +187,7 @@ void set_default_settings(Settings *settings) settings->setDefault("emergequeue_limit_total", "256"); settings->setDefault("emergequeue_limit_diskonly", ""); settings->setDefault("emergequeue_limit_generate", ""); - settings->setDefault("num_emerge_threads", ""); + settings->setDefault("num_emerge_threads", "1"); // physics stuff settings->setDefault("movement_acceleration_default", "3"); diff --git a/src/emerge.cpp b/src/emerge.cpp index dd97734c5..dc2bb3e99 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -56,8 +56,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { if (g_settings->get("num_emerge_threads").empty()) { int nprocs = porting::getNumberOfProcessors(); // leave a proc for the main thread and one for some other misc threads - if (nprocs > 2) - nthreads = nprocs - 2; + nthreads = (nprocs > 2) ? nthreads = nprocs - 2 : 1; } else { nthreads = g_settings->getU16("num_emerge_threads"); } -- cgit v1.2.3 From 9b5f182642416add39aab7782b1d155dafead160 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 23 Feb 2013 22:45:12 -0500 Subject: Remove dead code, relocate some code --- src/emerge.cpp | 332 +++++---------------------------------------------------- src/server.h | 120 +++++---------------- 2 files changed, 53 insertions(+), 399 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/emerge.cpp b/src/emerge.cpp index dc2bb3e99..250c44fbb 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -41,6 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen_v6.h" +/////////////////////////////// Emerge Manager //////////////////////////////// + EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { //register built-in mapgens registerMapgen("v6", new MapgenFactoryV6()); @@ -166,33 +168,6 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate } -bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) { - std::map::iterator iter; - JMutexAutoLock queuelock(emerge->queuemutex); - - if (blockqueue.empty()) - return false; - v3s16 p = blockqueue.front(); - blockqueue.pop(); - - *pos = p; - - iter = emerge->blocks_enqueued.find(p); - if (iter == emerge->blocks_enqueued.end()) - return false; //uh oh, queue and map out of sync!! - - BlockEmergeData *bedata = iter->second; - *flags = bedata->flags; - - emerge->peer_queue_count[bedata->peer_requested]--; - - delete bedata; - emerge->blocks_enqueued.erase(iter); - - return true; -} - - int EmergeManager::getGroundLevelAtPoint(v2s16 p) { if (mapgen.size() == 0 || !mapgen[0]) { errorstream << "EmergeManager: getGroundLevelAtPoint() called" @@ -290,59 +265,34 @@ bool EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory) } +////////////////////////////// Emerge Thread ////////////////////////////////// -class MapEditEventIgnorer -{ -public: - MapEditEventIgnorer(bool *flag): - m_flag(flag) - { - if(*m_flag == false) - *m_flag = true; - else - m_flag = NULL; - } - - ~MapEditEventIgnorer() - { - if(m_flag) - { - assert(*m_flag); - *m_flag = false; - } - } - -private: - bool *m_flag; -}; - -class MapEditEventAreaIgnorer -{ -public: - MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): - m_ignorevariable(ignorevariable) - { - if(m_ignorevariable->getVolume() == 0) - *m_ignorevariable = a; - else - m_ignorevariable = NULL; - } +bool EmergeThread::popBlockEmerge(v3s16 *pos, u8 *flags) { + std::map::iterator iter; + JMutexAutoLock queuelock(emerge->queuemutex); - ~MapEditEventAreaIgnorer() - { - if(m_ignorevariable) - { - assert(m_ignorevariable->getVolume() != 0); - *m_ignorevariable = VoxelArea(); - } - } + if (blockqueue.empty()) + return false; + v3s16 p = blockqueue.front(); + blockqueue.pop(); + + *pos = p; + + iter = emerge->blocks_enqueued.find(p); + if (iter == emerge->blocks_enqueued.end()) + return false; //uh oh, queue and map out of sync!! -private: - VoxelArea *m_ignorevariable; -}; + BlockEmergeData *bedata = iter->second; + *flags = bedata->flags; + + emerge->peer_queue_count[bedata->peer_requested]--; + delete bedata; + emerge->blocks_enqueued.erase(iter); + + return true; +} -#if 1 bool EmergeThread::getBlockOrStartGen(v3s16 p, MapBlock **b, BlockMakeData *data, bool allow_gen) { @@ -501,235 +451,3 @@ void *EmergeThread::Thread() { log_deregister_thread(); return NULL; } - -#else - -void *EmergeThread::Thread() { - ThreadStarted(); - log_register_thread("EmergeThread"); - DSTACK(__FUNCTION_NAME); - BEGIN_DEBUG_EXCEPTION_HANDLER - - bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info"); - - v3s16 last_tried_pos(-32768,-32768,-32768); // For error output - ServerMap &map = ((ServerMap&)m_server->m_env->getMap()); - EmergeManager *emerge = m_server->m_emerge; - Mapgen *mapgen = emerge->getMapgen(); - - while(getRun()) - try { - QueuedBlockEmerge *qptr = m_server->m_emerge_queue.pop(); - if(qptr == NULL) - break; - SharedPtr q(qptr); - - v3s16 &p = q->pos; - v2s16 p2d(p.X,p.Z); - - last_tried_pos = p; - - /* - Do not generate over-limit - */ - if (blockpos_over_limit(p)) - continue; - - //infostream<<"EmergeThread::Thread(): running"<::Iterator i; - for (i=q->s.getIterator(); !i.atEnd(); i++) { - u8 flags = i.getNode()->getValue(); - if (!(flags & BLOCK_EMERGE_FLAG_FROMDISK)) { - only_from_disk = false; - break; - } - } - } - - if (enable_mapgen_debug_info) - infostream<<"EmergeThread: p=" - <<"("<isGenerated() == false)){ - if(enable_mapgen_debug_info) - infostream<<"EmergeThread: generating"<makeChunk(&data); - - if (enable_mapgen_debug_info == false) - t.stop(true); // Hide output - } - - do{ // enable break - // Lock environment again to access the map - JMutexAutoLock envlock(m_server->m_env_mutex); - - ScopeProfiler sp(g_profiler, "EmergeThread: after " - "mapgen::make_block (envlock)", SPT_AVG); - - // Blit data back on map, update lighting, add mobs and - // whatever this does - map.finishBlockMake(&data, modified_blocks); - - // Get central block - block = map.getBlockNoCreateNoEx(p); - - // If block doesn't exist, don't try doing anything with it - // This happens if the block is not in generation boundaries - if(!block) - break; - - /* - Do some post-generate stuff - */ - v3s16 minp = data.blockpos_min * MAP_BLOCKSIZE; - v3s16 maxp = data.blockpos_max * MAP_BLOCKSIZE + - v3s16(1,1,1) * (MAP_BLOCKSIZE - 1); - - /* - Ignore map edit events, they will not need to be - sent to anybody because the block hasn't been sent - to anybody - */ - MapEditEventAreaIgnorer ign( - &m_server->m_ignore_map_edit_events_area, - VoxelArea(minp, maxp)); - { - TimeTaker timer("on_generated"); - scriptapi_environment_on_generated(m_server->m_lua, - minp, maxp, emerge->getBlockSeed(minp)); - //int t = timer.stop(true); - //dstream<<"on_generated took "<m_env->activateBlock(block, 0); - }while(false); - } - - if(block == NULL) - got_block = false; - - /* - Set sent status of modified blocks on clients - */ - - // NOTE: Server's clients are also behind the connection mutex - JMutexAutoLock lock(m_server->m_con_mutex); - - /* - Add the originally fetched block to the modified list - */ - if(got_block) - modified_blocks.insert(p, block); - - /* - Set the modified blocks unsent for all the clients - */ - for(core::map::Iterator - i = m_server->m_clients.getIterator(); - i.atEnd() == false; i++) { - RemoteClient *client = i.getNode()->getValue(); - if(modified_blocks.size() > 0) { - // Remove block from sent history - client->SetBlocksNotSent(modified_blocks); - } - } - - -niters++; - } - catch (VersionMismatchException &e) { - std::ostringstream err; - err << "World data version mismatch in MapBlock "<setAsyncFatalError(err.str()); - } - catch (SerializationError &e) { - std::ostringstream err; - err << "Invalid data in MapBlock "<setAsyncFatalError(err.str()); - } -printf("emergethread iterated %d times\n", niters); - END_DEBUG_EXCEPTION_HANDLER(errorstream) - log_deregister_thread(); - return NULL; -} - -#endif diff --git a/src/server.h b/src/server.h index e92cbb564..907be485d 100644 --- a/src/server.h +++ b/src/server.h @@ -73,115 +73,55 @@ public: */ v3f findSpawnPos(ServerMap &map); -/* - A structure containing the data needed for queueing the fetching - of blocks. -*/ -struct QueuedBlockEmerge -{ - v3s16 pos; - // key = peer_id, value = flags - core::map peer_ids; -}; -/* - This is a thread-safe class. -*/ -class BlockEmergeQueue +class MapEditEventIgnorer { public: - BlockEmergeQueue() + MapEditEventIgnorer(bool *flag): + m_flag(flag) { - m_mutex.Init(); + if(*m_flag == false) + *m_flag = true; + else + m_flag = NULL; } - ~BlockEmergeQueue() + ~MapEditEventIgnorer() { - JMutexAutoLock lock(m_mutex); - - core::list::Iterator i; - for(i=m_queue.begin(); i!=m_queue.end(); i++) + if(m_flag) { - QueuedBlockEmerge *q = *i; - delete q; + assert(*m_flag); + *m_flag = false; } } - /* - peer_id=0 adds with nobody to send to - */ - void addBlock(u16 peer_id, v3s16 pos, u8 flags) - { - DSTACK(__FUNCTION_NAME); - - JMutexAutoLock lock(m_mutex); - - if(peer_id != 0) - { - /* - Find if block is already in queue. - If it is, update the peer to it and quit. - */ - core::list::Iterator i; - for(i=m_queue.begin(); i!=m_queue.end(); i++) { - QueuedBlockEmerge *q = *i; - if (q->pos == pos) { - q->peer_ids[peer_id] = flags; - return; - } - } - } - - /* - Add the block - */ - QueuedBlockEmerge *q = new QueuedBlockEmerge; - q->pos = pos; - if (peer_id != 0) - q->peer_ids[peer_id] = flags; - m_queue.push_back(q); - } - - // Returned pointer must be deleted - // Returns NULL if queue is empty - QueuedBlockEmerge * pop() - { - JMutexAutoLock lock(m_mutex); - - core::list::Iterator i = m_queue.begin(); - if(i == m_queue.end()) - return NULL; - QueuedBlockEmerge *q = *i; - m_queue.erase(i); - return q; - } +private: + bool *m_flag; +}; - u32 size() +class MapEditEventAreaIgnorer +{ +public: + MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a): + m_ignorevariable(ignorevariable) { - JMutexAutoLock lock(m_mutex); - return m_queue.size(); + if(m_ignorevariable->getVolume() == 0) + *m_ignorevariable = a; + else + m_ignorevariable = NULL; } - u32 peerItemCount(u16 peer_id) + ~MapEditEventAreaIgnorer() { - JMutexAutoLock lock(m_mutex); - - u32 count = 0; - - core::list::Iterator i; - for(i=m_queue.begin(); i!=m_queue.end(); i++) + if(m_ignorevariable) { - QueuedBlockEmerge *q = *i; - if(q->peer_ids.find(peer_id) != NULL) - count++; + assert(m_ignorevariable->getVolume() != 0); + *m_ignorevariable = VoxelArea(); } - - return count; } private: - core::list m_queue; - JMutex m_mutex; + VoxelArea *m_ignorevariable; }; class Server; @@ -761,10 +701,6 @@ private: // The server mainly operates in this thread ServerThread m_thread; - // This thread fetches and generates map - //EmergeThread m_emergethread; - // Queue of block coordinates to be processed by the emerge thread - //BlockEmergeQueue m_emerge_queue; /* Time related stuff -- cgit v1.2.3 From d31f07bd4b83f858cce589faac56922e12ba670f Mon Sep 17 00:00:00 2001 From: kwolekr Date: Tue, 26 Feb 2013 01:57:59 -0500 Subject: Fix most warnings, re-fix MSVC compile error --- src/base64.h | 2 +- src/content_cso.cpp | 2 ++ src/emerge.cpp | 10 +++++----- src/emerge.h | 2 +- src/game.cpp | 4 ++-- src/map.cpp | 2 +- src/noise.cpp | 4 ++-- src/server.cpp | 2 +- src/test.cpp | 2 +- src/util/serialize.h | 11 ++++++----- 10 files changed, 22 insertions(+), 19 deletions(-) (limited to 'src/emerge.cpp') diff --git a/src/base64.h b/src/base64.h index 5f2d6743d..1cb175518 100644 --- a/src/base64.h +++ b/src/base64.h @@ -7,4 +7,4 @@ bool base64_is_valid(std::string const& s); std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); -#endif // BASE64_HEADER \ No newline at end of file +#endif // BASE64_HEADER diff --git a/src/content_cso.cpp b/src/content_cso.cpp index 20eb88b7d..73d5f2b48 100644 --- a/src/content_cso.cpp +++ b/src/content_cso.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "map.h" +/* static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, float txs, float tys, int col, int row) { @@ -33,6 +34,7 @@ static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill, matrix.setTextureTranslate(txs*col, tys*row); matrix.setTextureScale(txs, tys); } +*/ class SmokePuffCSO: public ClientSimpleObject { diff --git a/src/emerge.cpp b/src/emerge.cpp index 250c44fbb..6c6863eff 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -58,7 +58,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { if (g_settings->get("num_emerge_threads").empty()) { int nprocs = porting::getNumberOfProcessors(); // leave a proc for the main thread and one for some other misc threads - nthreads = (nprocs > 2) ? nthreads = nprocs - 2 : 1; + nthreads = (nprocs > 2) ? nprocs - 2 : 1; } else { nthreads = g_settings->getU16("num_emerge_threads"); } @@ -81,7 +81,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef, BiomeDefManager *bdef) { EmergeManager::~EmergeManager() { - for (int i = 0; i != emergethread.size(); i++) { + for (unsigned int i = 0; i != emergethread.size(); i++) { emergethread[i]->setRun(false); emergethread[i]->qevent.signal(); emergethread[i]->stop(); @@ -101,7 +101,7 @@ void EmergeManager::initMapgens(MapgenParams *mgparams) { return; this->params = mgparams; - for (int i = 0; i != emergethread.size(); i++) { + for (unsigned int i = 0; i != emergethread.size(); i++) { mg = createMapgen(params->mg_name, 0, params); if (!mg) { infostream << "EmergeManager: falling back to mapgen v6" << std::endl; @@ -152,7 +152,7 @@ bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate // insert into the EmergeThread queue with the least items int lowestitems = emergethread[0]->blockqueue.size(); - for (int i = 1; i != emergethread.size(); i++) { + for (unsigned int i = 1; i != emergethread.size(); i++) { int nitems = emergethread[i]->blockqueue.size(); if (nitems < lowestitems) { idx = i; @@ -259,7 +259,7 @@ void EmergeManager::setParamsToSettings(Settings *settings) { } -bool EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory) { +void EmergeManager::registerMapgen(std::string mgname, MapgenFactory *mgfactory) { mglist.insert(std::make_pair(mgname, mgfactory)); infostream << "EmergeManager: registered mapgen " << mgname << std::endl; } diff --git a/src/emerge.h b/src/emerge.h index e5014df58..70b67e731 100644 --- a/src/emerge.h +++ b/src/emerge.h @@ -75,7 +75,7 @@ public: MapgenParams *createMapgenParams(std::string mgname); bool enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate); - bool registerMapgen(std::string name, MapgenFactory *mgfactory); + void registerMapgen(std::string name, MapgenFactory *mgfactory); MapgenParams *getParamsFromSettings(Settings *settings); void setParamsToSettings(Settings *settings); diff --git a/src/game.cpp b/src/game.cpp index 8ab0f3fe3..1ae29b13b 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2816,12 +2816,12 @@ void the_game( char temptext[300]; snprintf(temptext, 300, "(% .1f, % .1f, % .1f)" - " (yaw = %.1f) (seed = %lli)", + " (yaw = %.1f) (seed = %llu)", player_position.X/BS, player_position.Y/BS, player_position.Z/BS, wrapDegrees_0_360(camera_yaw), - client.getMapSeed()); + (unsigned long long)client.getMapSeed()); guitext2->setText(narrow_to_wide(temptext).c_str()); guitext2->setVisible(true); diff --git a/src/map.cpp b/src/map.cpp index 07af2676b..4be094326 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3283,7 +3283,7 @@ void ServerMap::save(ModifiedState save_level) block_count_all++; - if(block->getModified() >= save_level) + if(block->getModified() >= (u32)save_level) { // Lazy beginSave() if(!save_started){ diff --git a/src/noise.cpp b/src/noise.cpp index d250882e8..49b5f7e58 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -507,7 +507,7 @@ void Noise::gradientMap3D(float x, float y, float z, float *Noise::perlinMap2D(float x, float y) { - float a = 0.0, f = 1.0, g = 1.0; + float f = 1.0, g = 1.0; int i, j, index, oct; x /= np->spread.X; @@ -537,7 +537,7 @@ float *Noise::perlinMap2D(float x, float y) { float *Noise::perlinMap3D(float x, float y, float z) { - float a = 0.0, f = 1.0, g = 1.0; + float f = 1.0, g = 1.0; int i, j, k, index, oct; x /= np->spread.X; diff --git a/src/server.cpp b/src/server.cpp index 2d00cf4ac..41a7a4289 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1652,7 +1652,7 @@ void Server::AsyncRunStep() { counter = 0.0; - for (int i = 0; i != m_emerge->emergethread.size(); i++) + for (unsigned int i = 0; i != m_emerge->emergethread.size(); i++) m_emerge->emergethread[i]->trigger(); // Update m_enable_rollback_recording here too diff --git a/src/test.cpp b/src/test.cpp index f988b34f7..d86868118 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -462,7 +462,7 @@ struct TestCompress: public TestBase <