| 54 | } |
| 55 | |
| 56 | static void InitThreads() { |
| 57 | static bool initialized; |
| 58 | // Don't worry about thread_safety - this should be called when there is |
| 59 | // a single thread. |
| 60 | if (LIKELY(initialized)) |
| 61 | return; |
| 62 | // Never reuse ASan threads: we store pointer to AsanThreadContext |
| 63 | // in TSD and can't reliably tell when no more TSD destructors will |
| 64 | // be called. It would be wrong to reuse AsanThreadContext for another |
| 65 | // thread before all TSD destructors will be called for it. |
| 66 | |
| 67 | // MIPS requires aligned address |
| 68 | alignas(alignof(ThreadRegistry)) static char |
| 69 | thread_registry_placeholder[sizeof(ThreadRegistry)]; |
| 70 | alignas(alignof(ThreadArgRetval)) static char |
| 71 | thread_data_placeholder[sizeof(ThreadArgRetval)]; |
| 72 | |
| 73 | asan_thread_registry = |
| 74 | new (thread_registry_placeholder) ThreadRegistry(GetAsanThreadContext); |
| 75 | thread_data = new (thread_data_placeholder) ThreadArgRetval(); |
| 76 | initialized = true; |
| 77 | } |
| 78 | |
| 79 | ThreadRegistry &asanThreadRegistry() { |
| 80 | InitThreads(); |