Skip to content
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

Added initial version of thread.c #239

Merged
merged 29 commits into from
Sep 14, 2022
Merged

Conversation

JCash
Copy link
Contributor

@JCash JCash commented Sep 9, 2022

No description provided.

@JCash
Copy link
Contributor Author

JCash commented Sep 9, 2022

Compiles with

clang -std=c11 -DRMT_ENABLED=1 -DRMT_ARCH_64BIT -DRMT_USE_C_ATOMICS -g -O0 -fsanitize=thread -Ilib sample/thread.c lib/Remotery.c -o build/test && ./build/test

@JCash JCash mentioned this pull request Sep 12, 2022
@dwilliamson
Copy link
Collaborator

So just to be clear: this defeats all your TSAN warnings, right? I will comb through this tomorrow but given we don't have load/acquire and store/release memory fences on non-x64/86 platforms, I feel this is only just the beginning...

lib/Remotery.c Outdated Show resolved Hide resolved
lib/Remotery.c Outdated Show resolved Hide resolved
lib/Remotery.c Show resolved Hide resolved
lib/Remotery.c Outdated
Comment on lines 170 to 176
#if __STDC_VERSION__ >= 201112L || __cplusplus >= 199711L
#if !defined(__STDC_NO_ATOMICS__)
#if !defined(RMT_USE_C_ATOMICS) // Check if the user already specified it
#define RMT_USE_C_ATOMICS
#endif
#endif
#endif
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a way to explicitly choose not to use the C atomics?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we do because we want to have an explicit test case that ensures that path always compiles.

lib/Remotery.c Show resolved Hide resolved
lib/Remotery.c Outdated Show resolved Hide resolved
lib/Remotery.c Outdated Show resolved Hide resolved
lib/Remotery.c Show resolved Hide resolved
@JCash
Copy link
Contributor Author

JCash commented Sep 13, 2022

On linux, I still get this TSAN warning, when using the C11 atomics:

  Read of size 4 at 0x0000037b903c by thread T4:
    #0 ThreadProfiler_GetNameHash /home/builder/lib/Remotery.c:5336:21 (test+0x4be8e8)
    #1 _rmt_BeginCPUSample /home/builder/lib/Remotery.c:7378:28 (test+0x4be763)
    #2 recursiveFunction /home/builder/sample/thread.c:102:5 (test+0x4bb567)
    #3 Run /home/builder/sample/thread.c:116:13 (test+0x4bb491)
    #4 thread_start_proxy /home/builder/sample/thread.c:36:5 (test+0x4bb1c9)

  Previous write of size 4 at 0x0000037b903c by thread T3:
    #0 ThreadProfiler_GetNameHash /home/builder/lib/Remotery.c:5346:29 (test+0x4be98f)
    #1 _rmt_BeginCPUSample /home/builder/lib/Remotery.c:7378:28 (test+0x4be763)
    #2 recursiveFunction /home/builder/sample/thread.c:102:5 (test+0x4bb567)
    #3 Run /home/builder/sample/thread.c:116:13 (test+0x4bb491)
    #4 thread_start_proxy /home/builder/sample/thread.c:36:5 (test+0x4bb1c9)

  Location is global 'recursiveFunction.rmt_sample_hash_recursive' of size 4 at 0x0000037b903c (test+0x0000037b903c)

  Thread T4 'thread_1' (tid=17, running) created by main thread at:
    #0 pthread_create /local/mnt/workspace/bcain_clang_hu-bcain-lv_8872/final/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:977:3 (test+0x4476dd)
    #1 thread_create /home/builder/sample/thread.c:70:11 (test+0x4bb0a3)
    #2 main /home/builder/sample/thread.c:147:22 (test+0x4bb37d)

  Thread T3 'thread_0' (tid=16, running) created by main thread at:
    #0 pthread_create /local/mnt/workspace/bcain_clang_hu-bcain-lv_8872/final/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:977:3 (test+0x4476dd)
    #1 thread_create /home/builder/sample/thread.c:70:11 (test+0x4bb0a3)
    #2 main /home/builder/sample/thread.c:147:22 (test+0x4bb37d)

And, I'm not sure what's going on with the Windows "dump.exe". I need to look into that as well.

@dwilliamson
Copy link
Collaborator

Your line numbers are different to the version I have so I'm not sure what it's referencing.

At a guess I'd say it's the hash_cache read/write. Which makes sense: multiple threads will be reading and writing the cached hash value. However it's completely harmless as the value is either zero or the same calculated hash value across all threads.

The side effects are:

  1. The string gets added to the string table more than once (which it can safely ignore).
  2. The expensive path of calculating the hash happens more than once, which again is only once per thread in contention.

Options:

  • Expose atomic types outside the implementation and use a rmtAtomicU32 pointer, but I really don't like that.
  • Can we cast to rmtAtomicU32?
  • Put the whole thing in a CAS loop to ensure 100% validity.
  • Can we comment the code in a way that TSAN classifies it as a false positive?

@@ -5333,7 +5359,7 @@ static rmtU32 ThreadProfiler_GetNameHash(ThreadProfiler* thread_profiler, rmtMes
if (hash_cache != NULL)
{
// Calculate the hash first time round only
name_hash = *hash_cache;
name_hash = AtomicLoadU32((rmtAtomicU32*)hash_cache);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried some variants but so far, this was the one that worked and wasn't too intrusive.

lib/Remotery.c Show resolved Hide resolved
@JCash
Copy link
Contributor Author

JCash commented Sep 13, 2022

I think it's all coming together now.

However, I haven't figured out why the windows test stopped working.
It builds and runs fine locally on my windows machine.

lib/Remotery.c Outdated
@@ -167,6 +167,28 @@ static rmtBool g_SettingsInitialized = RMT_FALSE;
#include <cuda.h>
#endif

#if RMT_USE_LEGACY_ATOMICS==0
#if !defined(RMT_PLATFORM_WINDOWS)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully can enable this once the windows tests start working again.

lib/Remotery.c Show resolved Hide resolved
lib/Remotery.h Show resolved Hide resolved
@@ -55,6 +55,7 @@ cl.exe %CL_OPTS% -Ilib -DRMT_USE_INTERNAL_HASH_FUNCTION=1 sample/sample.c lib/Re
echo "Samples"
cl.exe %CL_OPTS% -Ilib sample/sample.c lib/Remotery.c /link /out:build\sample.exe || goto :error
cl.exe %CL_OPTS% -Ilib sample/dump.c lib/Remotery.c /link /out:build\dump.exe || goto :error
cl.exe %CL_OPTS% -TP /MTd /O1 /fsanitize=address /Zi -Ilib sample/thread.c lib/Remotery.c /link /DEBUG /out:build\thread_asan.exe || goto :error
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying out address sanitizer for windows

@JCash JCash marked this pull request as ready for review September 14, 2022 07:36
@dwilliamson
Copy link
Collaborator

Is this ready to go? What is the status of running ASAN/UBSAN/TSAN after this change?

@JCash
Copy link
Contributor Author

JCash commented Sep 14, 2022

I think it's good to go.
I have no asan/tsan/ubsan issues locally, and the linux/darwin tests produce no warnings either. And the windows asan test is green as well.

@dwilliamson
Copy link
Collaborator

Awesome work, thanks!

@dwilliamson dwilliamson merged commit 0cc955e into Celtoys:main Sep 14, 2022
@JCash JCash deleted the thread-sample branch September 14, 2022 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants