-
-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use thread_local instead of static in EASY_LOCAL_STATIC_PTR. #130
base: develop
Are you sure you want to change the base?
Conversation
…ut it it's impossible to profile functions called from multiple threads.
Hi |
I use visual studio 2015. I have the following case: void ed::PoolTask::run() Which is called from many threads. So if you use static variable it'll be changed in the middle of profiling. It appears under relatively heavy load. |
I think this issue isn't compiler specific. |
C++11 standard guarantees that local static initialization is thread-safe. And this static in I think your problem is related to the usage of |
For example: void ed::PoolTask::run()
{
const std::string local_id = id; // try to use temporary buffer
EASY_BLOCK(local_id.c_str());
func();
// EASY_END_BLOCK; // this is not necessary because EASY_BLOCK using RAII
} |
Hi @madevgeny |
Hi, it appears that we use /Zc:threadSafeInit- flag which disables thread safe statics. We need it for our protection system and unfortunately we will not be able to change it in near future. I attached simple example to reproduce crash. But with my patch it works without crash. Another thought. EASY_BLOCK unrolls to something like this: static const ::profiler::BaseBlockDescriptor* desc = ::profiler::registerDescription("unique arguments"); if we call the same function from multiple threads but with different "unique arguments" we will write to desc pointers to different objects. So there is no guarantee that after writing pointer to desc we will have read the same pointer from it. As static variable desc can be changed from other threads. tread_local solves this problem too. |
No, id is member of PoolTask class. |
Well, this explains the problem :-) If this flag could be checked at compile-time in source code then the fix will be: #ifndef EASY_LOCAL_STATIC_PTR
# if defined(_MSC_VER) && defined(_MSC_ZC_THREAD_SAFE_INIT) // Something like this
# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer) thread_local static VarType ...
# else // This is existing branch:
# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer) static VarType ...
# define EASY_MAGIC_STATIC_AVAILABLE
#endif If it's impossible to check the flag in source code then you will have to add new CMake option into |
It would be great if you could fix it :-) |
…As without it it's impossible to profile functions called from multiple threads." This reverts commit 3ee2067.
There is no macros to detect /Zc:threadSafeInit- at compile time. I'll add option to easy_profiler_core/CMakeLists.txt. |
…safe initialization of static local variables.
…in project using profiler. EASY_OPTION_THREAD_SAFE_INIT doesn't require setting it in project using profiler.
Hi, I added EASY_OPTION_THREAD_SAFE_INIT option and generation of config header. |
# define EASY_MAGIC_STATIC_AVAILABLE | ||
# if defined(_MSC_VER) && EASY_DISABLE_THREAD_SAFE_INIT != 0 | ||
# define EASY_LOCAL_STATIC_PTR(VarType, VarName, VarInitializer) thread_local static VarType VarName = VarInitializer | ||
# define EASY_MAGIC_STATIC_AVAILABLE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EASY_MAGIC_STATIC_AVAILABLE should not be defined if thread-safe static init is disabled
set(EASY_DISABLE_THREAD_SAFE_INIT 1) | ||
endif () | ||
|
||
configure_file ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you, please, use existing easy_define_target_option
cmake command instead of generating new file?
Is it true that this PR addresses a critical multuthreading usability issue? |
Hi, please look at my changes, without them it's impossible to profile functions called from multiple threads.