aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-05-23 10:32:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-05-23 10:32:18 +0000
commitd65cd7a57bf0600b722afc770838a5d0c1c3a8e1 (patch)
tree0ae3978be5d5ef52ee35aa732555aaa432406a2b /contrib/llvm-project/compiler-rt
parent2bbab0af6dd5aa825fbe86813d917565bb885b67 (diff)
parentec2b0f99f245da9ce98e41cf4cc2b6b2a02726f6 (diff)
downloadsrc-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.c54
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);