Commit d0473da1b93c0603fe1be110c3fe1b66181665b1
1 parent
64ec702a
Auto-detect number of threads
Showing
3 changed files
with
28 additions
and
4 deletions
mainapp.cpp
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | #include "getopt.h" |
| 5 | 5 | #include <unistd.h> |
| 6 | 6 | #include <stdio.h> |
| 7 | +#include <sys/sysinfo.h> | |
| 7 | 8 | |
| 8 | 9 | #include <openssl/ssl.h> |
| 9 | 10 | #include <openssl/err.h> |
| ... | ... | @@ -11,7 +12,6 @@ |
| 11 | 12 | #include "logger.h" |
| 12 | 13 | |
| 13 | 14 | #define MAX_EVENTS 1024 |
| 14 | -#define NR_OF_THREADS 4 | |
| 15 | 15 | |
| 16 | 16 | #define VERSION "0.1" |
| 17 | 17 | |
| ... | ... | @@ -148,12 +148,20 @@ void do_thread_work(ThreadData *threadData) |
| 148 | 148 | MainApp::MainApp(const std::string &configFilePath) : |
| 149 | 149 | subscriptionStore(new SubscriptionStore()) |
| 150 | 150 | { |
| 151 | + this->num_threads = get_nprocs(); | |
| 152 | + | |
| 153 | + if (num_threads <= 0) | |
| 154 | + throw std::runtime_error("Invalid number of CPUs: " + std::to_string(num_threads)); | |
| 155 | + | |
| 151 | 156 | epollFdAccept = check<std::runtime_error>(epoll_create(999)); |
| 152 | 157 | taskEventFd = eventfd(0, EFD_NONBLOCK); |
| 153 | 158 | |
| 154 | 159 | confFileParser.reset(new ConfigFileParser(configFilePath)); |
| 155 | 160 | loadConfig(); |
| 156 | 161 | |
| 162 | + // TODO: override in conf possibility. | |
| 163 | + logger->logf(LOG_NOTICE, "%d CPUs are detected, making as many threads.", num_threads); | |
| 164 | + | |
| 157 | 165 | auto f = std::bind(&MainApp::queueCleanup, this); |
| 158 | 166 | timer.addCallback(f, 86400000, "session expiration"); |
| 159 | 167 | } |
| ... | ... | @@ -342,7 +350,7 @@ void MainApp::start() |
| 342 | 350 | ev.events = EPOLLIN; |
| 343 | 351 | check<std::runtime_error>(epoll_ctl(this->epollFdAccept, EPOLL_CTL_ADD, taskEventFd, &ev)); |
| 344 | 352 | |
| 345 | - for (int i = 0; i < NR_OF_THREADS; i++) | |
| 353 | + for (int i = 0; i < num_threads; i++) | |
| 346 | 354 | { |
| 347 | 355 | std::shared_ptr<ThreadData> t(new ThreadData(i, subscriptionStore, *confFileParser.get())); |
| 348 | 356 | t->start(&do_thread_work); |
| ... | ... | @@ -373,7 +381,7 @@ void MainApp::start() |
| 373 | 381 | { |
| 374 | 382 | if (cur_fd == listen_fd_plain || cur_fd == listen_fd_ssl) |
| 375 | 383 | { |
| 376 | - std::shared_ptr<ThreadData> thread_data = threads[next_thread_index++ % NR_OF_THREADS]; | |
| 384 | + std::shared_ptr<ThreadData> thread_data = threads[next_thread_index++ % num_threads]; | |
| 377 | 385 | |
| 378 | 386 | logger->logf(LOG_INFO, "Accepting connection on thread %d", thread_data->threadnr); |
| 379 | 387 | ... | ... |
mainapp.h
threaddata.cpp
| ... | ... | @@ -21,7 +21,22 @@ void ThreadData::start(thread_f f) |
| 21 | 21 | std::ostringstream threadName; |
| 22 | 22 | threadName << "FlashMQ T " << threadnr; |
| 23 | 23 | threadName.flush(); |
| 24 | - pthread_setname_np(native, threadName.str().c_str()); | |
| 24 | + const char *c_str = threadName.str().c_str(); | |
| 25 | + pthread_setname_np(native, c_str); | |
| 26 | + | |
| 27 | + cpu_set_t cpuset; | |
| 28 | + CPU_ZERO(&cpuset); | |
| 29 | + CPU_SET(threadnr, &cpuset); | |
| 30 | + check<std::runtime_error>(pthread_setaffinity_np(native, sizeof(cpuset), &cpuset)); | |
| 31 | + | |
| 32 | + // It's not really necessary to get affinity again, but now I'm logging truth instead assumption. | |
| 33 | + check<std::runtime_error>(pthread_getaffinity_np(native, sizeof(cpuset), &cpuset)); | |
| 34 | + int pinned_cpu = -1; | |
| 35 | + for (int j = 0; j < CPU_SETSIZE; j++) | |
| 36 | + if (CPU_ISSET(j, &cpuset)) | |
| 37 | + pinned_cpu = j; | |
| 38 | + | |
| 39 | + logger->logf(LOG_NOTICE, "Thread '%s' pinned to CPU %d", c_str, pinned_cpu); | |
| 25 | 40 | } |
| 26 | 41 | |
| 27 | 42 | void ThreadData::quit() | ... | ... |