introduce -DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL flag

This commit is contained in:
lganzzzo 2019-06-07 23:25:19 +03:00
parent fd6b1585c0
commit f80b8a8b7a
7 changed files with 113 additions and 46 deletions

View File

@ -32,6 +32,8 @@ set(OATPP_THREAD_HARDWARE_CONCURRENCY "AUTO" CACHE STRING "Predefined value for
set(OATPP_THREAD_DISTRIBUTED_MEM_POOL_SHARDS_COUNT "10" CACHE STRING "Number of shards of ThreadDistributedMemoryPool")
set(OATPP_ASYNC_EXECUTOR_THREAD_NUM_DEFAULT "2" CACHE STRING "oatpp::async::Executor default number of threads")
option(OATPP_COMPAT_BUILD_NO_THREAD_LOCAL "Disable 'thread_local' feature" OFF)
## Print config ##################################################################################
message("\n############################################################################")
@ -43,6 +45,8 @@ message("OATPP_THREAD_HARDWARE_CONCURRENCY=${OATPP_THREAD_HARDWARE_CONCURRENCY}"
message("OATPP_THREAD_DISTRIBUTED_MEM_POOL_SHARDS_COUNT=${OATPP_THREAD_DISTRIBUTED_MEM_POOL_SHARDS_COUNT}")
message("OATPP_ASYNC_EXECUTOR_THREAD_NUM_DEFAULT=${OATPP_ASYNC_EXECUTOR_THREAD_NUM_DEFAULT}")
message("OATPP_COMPAT_BUILD_NO_THREAD_LOCAL=${OATPP_COMPAT_BUILD_NO_THREAD_LOCAL}")
## Set definitions ###############################################################################
if(OATPP_DISABLE_ENV_OBJECT_COUNTERS)
@ -63,6 +67,10 @@ add_definitions (
-DOATPP_ASYNC_EXECUTOR_THREAD_NUM_DEFAULT=${OATPP_ASYNC_EXECUTOR_THREAD_NUM_DEFAULT}
)
if(OATPP_COMPAT_BUILD_NO_THREAD_LOCAL)
add_definitions(-DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL)
endif()
message("\n############################################################################\n")
###################################################################################################

View File

@ -63,6 +63,12 @@
#define OATPP_ASYNC_EXECUTOR_THREAD_NUM_DEFAULT 2
#endif
/**
* Disable `thread_local` feature. <br>
* See https://github.com/oatpp/oatpp/issues/81
*/
//#define OATPP_COMPAT_BUILD_NO_THREAD_LOCAL 1
/**
* DISABLE logs priority V
*/

View File

@ -38,9 +38,11 @@ std::unordered_map<std::string, std::unordered_map<std::string, void*>> Environm
v_atomicCounter Environment::m_objectsCount(0);
v_atomicCounter Environment::m_objectsCreated(0);
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
thread_local v_counter Environment::m_threadLocalObjectsCount = 0;
thread_local v_counter Environment::m_threadLocalObjectsCreated = 0;
#endif
DefaultLogger::DefaultLogger(const Config& config)
: m_config(config)
@ -115,8 +117,11 @@ void Environment::init(const std::shared_ptr<Logger>& logger) {
m_objectsCount = 0;
m_objectsCreated = 0;
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
m_threadLocalObjectsCount = 0;
m_threadLocalObjectsCreated = 0;
#endif
if(m_components.size() > 0) {
throw std::runtime_error("[oatpp::base::Environment]: Invalid state. Components were created before call to Environment::init()");
@ -155,15 +160,25 @@ void Environment::checkTypes(){
}
void Environment::incObjects(){
m_objectsCount ++;
m_objectsCreated ++;
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
m_threadLocalObjectsCount ++;
m_threadLocalObjectsCreated ++;
#endif
}
void Environment::decObjects(){
m_objectsCount --;
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
m_threadLocalObjectsCount --;
#endif
}
v_counter Environment::getObjectsCount(){
@ -175,11 +190,19 @@ v_counter Environment::getObjectsCreated(){
}
v_counter Environment::getThreadLocalObjectsCount(){
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
return m_threadLocalObjectsCount;
#else
return 0;
#endif
}
v_counter Environment::getThreadLocalObjectsCreated(){
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
return m_threadLocalObjectsCreated;
#else
return 0;
#endif
}
void Environment::setLogger(const std::shared_ptr<Logger>& logger){
@ -198,6 +221,10 @@ void Environment::printCompilationConfig() {
OATPP_LOGD("oatpp/Config", "OATPP_DISABLE_POOL_ALLOCATIONS");
#endif
#ifdef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
OATPP_LOGD("oatpp/Config", "OATPP_COMPAT_BUILD_NO_THREAD_LOCAL");
#endif
#ifdef OATPP_THREAD_HARDWARE_CONCURRENCY
OATPP_LOGD("oatpp/Config", "OATPP_THREAD_HARDWARE_CONCURRENCY=%d", OATPP_THREAD_HARDWARE_CONCURRENCY);
#endif

View File

@ -175,10 +175,15 @@ public:
*/
class Environment{
private:
static v_atomicCounter m_objectsCount;
static v_atomicCounter m_objectsCreated;
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
static thread_local v_counter m_threadLocalObjectsCount;
static thread_local v_counter m_threadLocalObjectsCreated;
#endif
private:
static std::shared_ptr<Logger> m_logger;
static void checkTypes();
@ -282,13 +287,15 @@ public:
/**
* Same as `getObjectsCount()` but `thread_local`
* @return - count of objects.
* @return - count of objects. <br>
* *0 - if built with `-DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL` flag*
*/
static v_counter getThreadLocalObjectsCount();
/**
* Same as `getObjectsCreated()` but `thread_local`
* @return - count of objects.
* @return - count of objects. <br>
* *0 - if built with `-DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL` flag*
*/
static v_counter getThreadLocalObjectsCreated();

View File

@ -101,7 +101,8 @@ inline bool operator != (const PoolSharedObjectAllocator<T>& a, const PoolShared
}
/**
* Same as &l:PoolSharedObjectAllocator; but uses `thread_local` &id:oatpp::base::memory::MemoryPool;.
* Same as &l:PoolSharedObjectAllocator; but uses `thread_local` &id:oatpp::base::memory::MemoryPool;. <br>
* *If built with OATPP_COMPAT_BUILD_NO_THREAD_LOCAL flag - same as &l:PoolSharedObjectAllocator;.*
* @tparam T - type of the object to allocate.
*/
template<class T>
@ -112,7 +113,11 @@ public:
const AllocatorPoolInfo& m_poolInfo;
public:
static oatpp::base::memory::MemoryPool& getPool(const AllocatorPoolInfo& info){
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
static thread_local oatpp::base::memory::MemoryPool pool(info.poolName, sizeof(T), info.poolChunkSize);
#else
static oatpp::base::memory::MemoryPool pool(info.poolName, sizeof(T), info.poolChunkSize);
#endif
return pool;
}
public:

View File

@ -136,7 +136,7 @@ std::atomic<v_int64> MemoryPool::poolIdCounter(0);
const v_int32 ThreadDistributedMemoryPool::SHARDS_COUNT_DEFAULT = OATPP_THREAD_DISTRIBUTED_MEM_POOL_SHARDS_COUNT;
#ifdef OATPP_DISABLE_POOL_ALLOCATIONS
#if defined(OATPP_DISABLE_POOL_ALLOCATIONS) || defined(OATPP_COMPAT_BUILD_NO_THREAD_LOCAL)
ThreadDistributedMemoryPool::ThreadDistributedMemoryPool(const std::string& name, v_int32 entrySize, v_int32 chunkSize, v_int32 shardsCount)
: m_shardsCount(1)
, m_shards(new MemoryPool*[1])
@ -166,7 +166,7 @@ ThreadDistributedMemoryPool::~ThreadDistributedMemoryPool(){
delete [] m_shards;
}
#ifdef OATPP_DISABLE_POOL_ALLOCATIONS
#if defined(OATPP_DISABLE_POOL_ALLOCATIONS) || defined(OATPP_COMPAT_BUILD_NO_THREAD_LOCAL)
void* ThreadDistributedMemoryPool::obtain() {
if(m_deleted) {
throw std::runtime_error("[oatpp::base::memory::ThreadDistributedMemoryPool::obtain()]. Error. Pool deleted.");

View File

@ -134,49 +134,63 @@ static void* operator new(std::size_t sz, void* entry) { \
static void operator delete(void* ptr, void* entry) { \
}
/**
* Macro to declare: `thread_local` &id:oatpp::base::memory::MemoryPool; for object, plus class-specific operators
* `static void* operator new(std::size_t sz)`, `static void operator delete(void* ptr, std::size_t sz)`,
* `static void* operator new(std::size_t sz, void* entry)`, `static void operator delete(void* ptr, void* entry)`.
* @param NAME - name of the memory pool.
* @param TYPE - type of the object.
* @param CHUNK_SIZE - chunk size for &id:oatpp::base::memory::MemoryPool;.
*/
#define OBJECT_POOL_THREAD_LOCAL(POOL_NAME, TYPE, CHUNK_SIZE) \
class POOL_NAME { \
public: \
\
static oatpp::base::memory::MemoryPool& getPool(){ \
static thread_local oatpp::base::memory::MemoryPool pool(#POOL_NAME"<"#TYPE">", sizeof(TYPE), CHUNK_SIZE); \
return pool; \
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
/**
* Macro to declare: `thread_local` &id:oatpp::base::memory::MemoryPool; for object, plus class-specific operators <br>
* `static void* operator new(std::size_t sz)`, `static void operator delete(void* ptr, std::size_t sz)`, <br>
* `static void* operator new(std::size_t sz, void* entry)`, `static void operator delete(void* ptr, void* entry)`. <br>
* *Memory pool is NOT `thread_local` if built with `-DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL` flag*
* @param NAME - name of the memory pool.
* @param TYPE - type of the object.
* @param CHUNK_SIZE - chunk size for &id:oatpp::base::memory::MemoryPool;.
*/
#define OBJECT_POOL_THREAD_LOCAL(POOL_NAME, TYPE, CHUNK_SIZE) \
class POOL_NAME { \
public: \
\
static oatpp::base::memory::MemoryPool& getPool(){ \
static thread_local oatpp::base::memory::MemoryPool pool(#POOL_NAME"<"#TYPE">", sizeof(TYPE), CHUNK_SIZE); \
return pool; \
} \
\
}; \
\
static void* operator new(std::size_t sz) { \
if(sz != sizeof(TYPE)){ \
throw std::runtime_error("wrong object size"); \
} \
static thread_local auto& pool = POOL_NAME::getPool(); \
return pool.obtain(); \
} \
\
}; \
\
static void* operator new(std::size_t sz) { \
if(sz != sizeof(TYPE)){ \
throw std::runtime_error("wrong object size"); \
\
static void operator delete(void* ptr, std::size_t sz) { \
if(sz != sizeof(TYPE)){ \
oatpp::base::Environment::log(2, #POOL_NAME, "[ERROR|CRITICAL]: MemoryPool malfunction. Deleting object of wrong size"); \
} \
oatpp::base::memory::MemoryPool::free(ptr); \
} \
static thread_local auto& pool = POOL_NAME::getPool(); \
return pool.obtain(); \
} \
\
static void operator delete(void* ptr, std::size_t sz) { \
if(sz != sizeof(TYPE)){ \
oatpp::base::Environment::log(2, #POOL_NAME, "[ERROR|CRITICAL]: MemoryPool malfunction. Deleting object of wrong size"); \
\
static void* operator new(std::size_t sz, void* entry) { \
if(sz != sizeof(TYPE)){ \
throw std::runtime_error("wrong object size"); \
} \
return entry; \
} \
oatpp::base::memory::MemoryPool::free(ptr); \
} \
\
static void* operator new(std::size_t sz, void* entry) { \
if(sz != sizeof(TYPE)){ \
throw std::runtime_error("wrong object size"); \
} \
return entry; \
} \
\
static void operator delete(void* ptr, void* entry) { \
}
\
static void operator delete(void* ptr, void* entry) { \
}
#else
#define OBJECT_POOL_THREAD_LOCAL(POOL_NAME, TYPE, CHUNK_SIZE) \
class POOL_NAME { \
public: \
\
static oatpp::base::memory::MemoryPool& getPool(){ \
static oatpp::base::memory::MemoryPool pool(#POOL_NAME"<"#TYPE">", sizeof(TYPE), CHUNK_SIZE); \
return pool; \
} \
\
};
#endif
}}}