-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pthread_setname_np does linear search over all thread descriptors to map pthread_t to the thread descriptor. This has O(N^2) complexity and becomes much worse in the new tsan runtime that keeps all ever existed threads in the thread registry. Replace linear search with direct access if pthread_setname_np is called for the current thread (a very common case). Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D113916
- Loading branch information
Showing
2 changed files
with
51 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// RUN: %clangxx_tsan %s -o %t | ||
// RUN: %run %t 2>&1 | FileCheck %s | ||
|
||
// bench.h needs pthread barriers which are not available on OS X | ||
// UNSUPPORTED: darwin | ||
|
||
#include "bench.h" | ||
|
||
void *nop_thread(void *arg) { | ||
pthread_setname_np(pthread_self(), "nop_thread"); | ||
return nullptr; | ||
} | ||
|
||
void thread(int tid) { | ||
for (int i = 0; i < bench_niter; i++) { | ||
pthread_t th; | ||
pthread_create(&th, nullptr, nop_thread, nullptr); | ||
pthread_join(th, nullptr); | ||
} | ||
} | ||
|
||
void bench() { | ||
// Benchmark thread creation/joining in presence of a large number | ||
// of threads (both alive and already joined). | ||
printf("starting transient threads...\n"); | ||
for (int i = 0; i < 200; i++) { | ||
const int kBatch = 100; | ||
pthread_t th[kBatch]; | ||
for (int j = 0; j < kBatch; j++) | ||
pthread_create(&th[j], nullptr, nop_thread, nullptr); | ||
for (int j = 0; j < kBatch; j++) | ||
pthread_join(th[j], nullptr); | ||
} | ||
printf("starting persistent threads...\n"); | ||
const int kLiveThreads = 2000; | ||
pthread_t th[kLiveThreads]; | ||
for (int j = 0; j < kLiveThreads; j++) | ||
pthread_create(&th[j], nullptr, nop_thread, nullptr); | ||
printf("starting benchmark threads...\n"); | ||
start_thread_group(bench_nthread, thread); | ||
for (int j = 0; j < kLiveThreads; j++) | ||
pthread_join(th[j], nullptr); | ||
} | ||
|
||
// CHECK: DONE |