summaryrefslogtreecommitdiff
path: root/lib/profile
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-03-19 21:01:19 +0000
committerBill Wendling <isanbard@gmail.com>2013-03-19 21:01:19 +0000
commitc533304a95fbed444ea02f5f9e7c6e37debd1c43 (patch)
treec87c8dac9bd7c1b00df6991f95026cc29dd76889 /lib/profile
parente1ba0009d5be18d513ffd29c1b6fccea1a3bffa0 (diff)
downloadcompiler-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.c45
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;