diff options
| -rw-r--r-- | compiler-rt/lib/profile/GCDAProfiling.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c index c7f74fd9093..ccaf01bbec1 100644 --- a/compiler-rt/lib/profile/GCDAProfiling.c +++ b/compiler-rt/lib/profile/GCDAProfiling.c @@ -42,8 +42,24 @@ typedef unsigned int uint64_t; * --- GCOV file format I/O primitives --- */ +/* + * The current file we're outputting. + */ static FILE *output_file = NULL; +/* + * A list of flush functions that our __gcov_flush() function should call. + */ +typedef void (*flush_fn)(); + +struct flush_fn_node { + flush_fn fn; + struct flush_fn_node *next; +}; + +struct flush_fn_node *flush_fn_head = NULL; +struct flush_fn_node *flush_fn_tail = NULL; + static void write_int32(uint32_t i) { fwrite(&i, 4, 1, output_file); } @@ -288,3 +304,35 @@ void llvm_gcda_end_file() { fprintf(stderr, "llvmgcda: -----\n"); #endif } + +void llvm_register_flush_function(flush_fn fn) { + struct flush_fn_node *new_node = malloc(sizeof(struct flush_fn_node)); + new_node->fn = fn; + new_node->next = NULL; + + if (!flush_fn_head) { + flush_fn_head = flush_fn_tail = new_node; + } else { + flush_fn_tail->next = new_node; + flush_fn_tail = new_node; + } +} + +void __gcov_flush() { + struct flush_fn_node *curr = flush_fn_head; + + while (curr) { + curr->fn(); + curr = curr->next; + } +} + +void llvm_delete_flush_function_list() { + while (flush_fn_head) { + struct flush_fn_node *node = flush_fn_head; + flush_fn_head = flush_fn_head->next; + free(node); + } + + flush_fn_head = flush_fn_tail = NULL; +} |

