diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-03-19 21:01:19 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-03-19 21:01:19 +0000 |
commit | c533304a95fbed444ea02f5f9e7c6e37debd1c43 (patch) | |
tree | c87c8dac9bd7c1b00df6991f95026cc29dd76889 /lib/profile | |
parent | e1ba0009d5be18d513ffd29c1b6fccea1a3bffa0 (diff) | |
download | compiler-rt-c533304a95fbed444ea02f5f9e7c6e37debd1c43.tar.gz |
Add a way to register and execute "writeout" functions.
It may be prohibitively expensive to write out >1000 files at the same time. So
we would rather emit them serially. These functions allow the GCOV
implementation to register the functions that writeout the GCOV information per
compile unit. At exit, they are written.
<rdar://problem/12439551>
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@177436 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile')
-rw-r--r-- | lib/profile/GCDAProfiling.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c index ccaf01bbe..bca255367 100644 --- a/lib/profile/GCDAProfiling.c +++ b/lib/profile/GCDAProfiling.c @@ -48,6 +48,19 @@ typedef unsigned int uint64_t; static FILE *output_file = NULL; /* + * A list of functions to write out the data. + */ +typedef void (*writeout_fn)(); + +struct writeout_fn_node { + writeout_fn fn; + struct writeout_fn_node *next; +}; + +struct writeout_fn_node *writeout_fn_head = NULL; +struct writeout_fn_node *writeout_fn_tail = NULL; + +/* * A list of flush functions that our __gcov_flush() function should call. */ typedef void (*flush_fn)(); @@ -305,6 +318,38 @@ void llvm_gcda_end_file() { #endif } +void llvm_register_writeout_function(writeout_fn fn) { + struct writeout_fn_node *new_node = malloc(sizeof(struct writeout_fn_node)); + new_node->fn = fn; + new_node->next = NULL; + + if (!writeout_fn_head) { + writeout_fn_head = writeout_fn_tail = new_node; + } else { + writeout_fn_tail->next = new_node; + writeout_fn_tail = new_node; + } +} + +void __llvm_writeout_files() { + struct writeout_fn_node *curr = writeout_fn_head; + + while (curr) { + curr->fn(); + curr = curr->next; + } +} + +void llvm_delete_writeout_function_list() { + while (writeout_fn_head) { + struct writeout_fn_node *node = writeout_fn_head; + writeout_fn_head = writeout_fn_head->next; + free(node); + } + + writeout_fn_head = writeout_fn_tail = NULL; +} + void llvm_register_flush_function(flush_fn fn) { struct flush_fn_node *new_node = malloc(sizeof(struct flush_fn_node)); new_node->fn = fn; |