Tune queue limits, some other adjustments
authorkwolekr <mirrorisim@gmail.com>
Thu, 21 Feb 2013 22:44:14 +0000 (17:44 -0500)
committerkwolekr <mirrorisim@gmail.com>
Tue, 26 Feb 2013 04:08:41 +0000 (23:08 -0500)
src/defaultsettings.cpp
src/emerge.cpp
src/porting.cpp
src/porting.h

index 219cda9e70da2ee279a67dd386e195207bc39d06..0e82c4e2f91b7a57a9b09283ea572f0320bdd3eb 100644 (file)
@@ -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
index ac654f36811f770ed65c922e5bde96b197e87dc2..dd97734c56e5dab68d40a08291f792095ce4e288 100644 (file)
@@ -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
 
index 58d71e4aa6db6287ddc8d57da7f660f789063ef2..84df15b3093d166670a3b268e6c2354ad899989f 100644 (file)
@@ -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
 */
index 53aad61715c42ffa7bf88b02b995a0dc15218187..74ee97f88efa8dcca558d2d4229e3ad018937578 100644 (file)
@@ -46,8 +46,33 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #else
        #include <unistd.h>
        #include <stdint.h> //for uintptr_t
-       
+
+       #if defined(linux) || defined(__linux)
+               #define _GNU_SOURCE
+       #endif
+
+       #include <sched.h>
+
+       #ifdef __FreeBSD__
+               #include <pthread_np.h>
+               typedef cpuset_t cpu_set_t;
+       #elif defined(__sun) || defined(sun)
+               #include <sys/types.h>
+               #include <sys/processor.h>
+       #elif defined(_AIX)
+               #include <sys/processor.h>
+       #elif __APPLE__
+               #include <mach/mach_init.h>
+               #include <mach/thread_policy.h>
+       #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.