diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-05-23 10:32:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-05-23 10:32:18 +0000 |
commit | d65cd7a57bf0600b722afc770838a5d0c1c3a8e1 (patch) | |
tree | 0ae3978be5d5ef52ee35aa732555aaa432406a2b /contrib/llvm-project/compiler-rt | |
parent | 2bbab0af6dd5aa825fbe86813d917565bb885b67 (diff) | |
parent | ec2b0f99f245da9ce98e41cf4cc2b6b2a02726f6 (diff) | |
download | src-d65cd7a57bf0600b722afc770838a5d0c1c3a8e1.tar.gz src-d65cd7a57bf0600b722afc770838a5d0c1c3a8e1.zip |
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
llvmorg-10.0.1-rc1-0-gf79cd71e145 (aka 10.0.1 rc1).
MFC after: 3 weeks
Notes
Notes:
svn path=/head/; revision=361410
Diffstat (limited to 'contrib/llvm-project/compiler-rt')
-rw-r--r-- | contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c b/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c index 498c05900bf2..124be3c13af6 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c +++ b/contrib/llvm-project/compiler-rt/lib/profile/GCDAProfiling.c @@ -32,8 +32,10 @@ #include <windows.h> #include "WindowsMMap.h" #else -#include <sys/mman.h> #include <sys/file.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> #endif #if defined(__FreeBSD__) && defined(__i386__) @@ -119,6 +121,11 @@ struct fn_list writeout_fn_list; */ struct fn_list flush_fn_list; +/* + * A list of reset functions, shared between all dynamic objects. + */ +struct fn_list reset_fn_list; + static void fn_list_insert(struct fn_list* list, fn_ptr fn) { struct fn_node* new_node = malloc(sizeof(struct fn_node)); new_node->fn = fn; @@ -634,7 +641,46 @@ void llvm_delete_flush_function_list(void) { } COMPILER_RT_VISIBILITY -void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn) { +void llvm_register_reset_function(fn_ptr fn) { + fn_list_insert(&reset_fn_list, fn); +} + +COMPILER_RT_VISIBILITY +void llvm_delete_reset_function_list(void) { fn_list_remove(&reset_fn_list); } + +COMPILER_RT_VISIBILITY +void llvm_reset_counters(void) { + struct fn_node *curr = reset_fn_list.head; + + while (curr) { + if (curr->id == CURRENT_ID) { + curr->fn(); + } + curr = curr->next; + } +} + +#if !defined(_WIN32) +COMPILER_RT_VISIBILITY +pid_t __gcov_fork() { + pid_t parent_pid = getpid(); + pid_t pid = fork(); + + if (pid == 0) { + pid_t child_pid = getpid(); + if (child_pid != parent_pid) { + // The pid changed so we've a fork (one could have its own fork function) + // Just reset the counters for this child process + // threads. + llvm_reset_counters(); + } + } + return pid; +} +#endif + +COMPILER_RT_VISIBILITY +void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn, fn_ptr rfn) { static int atexit_ran = 0; if (wfn) @@ -643,10 +689,14 @@ void llvm_gcov_init(fn_ptr wfn, fn_ptr ffn) { if (ffn) llvm_register_flush_function(ffn); + if (rfn) + llvm_register_reset_function(rfn); + if (atexit_ran == 0) { atexit_ran = 1; /* Make sure we write out the data and delete the data structures. */ + atexit(llvm_delete_reset_function_list); atexit(llvm_delete_flush_function_list); atexit(llvm_delete_writeout_function_list); atexit(llvm_writeout_files); |