midout.cpp 2.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
#include "midout.h"

// to avoid linking error for empty lib on some stupid platforms
void midout_empty() {
}

#ifdef MIDOUT_PROFILING
#pragma message "midout profiling enabled"

#include <string>
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <mutex>

#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

namespace {
    class UsedTypes {
        std::unordered_set<const char*> m_types;
        std::mutex m_mtx;

        public:

            void add(const char *type) {
                std::lock_guard<std::mutex> guard{m_mtx};
                m_types.insert(type);
            }

            ~UsedTypes() {
                auto output_fname = getenv("MIDOUT_OUTPUT");
                char output_fname_storage[256];
                if (!output_fname) {
                    output_fname = output_fname_storage;
                    snprintf(output_fname, sizeof(output_fname_storage),
                            "midout_trace.%d", static_cast<int>(getpid()));
                }
                FILE *fout = fopen(output_fname, "w");
                if (!fout) {
                    fprintf(stderr,
                            "midout: failed to open output file %s: %s\n",
                            output_fname, strerror(errno));
                }
                fprintf(fout, "midout_trace v1\n");
                std::vector<std::string> sorted_types;
                sorted_types.reserve(m_types.size());
                for (auto &&i: m_types) {
                    sorted_types.emplace_back(i);
                }
                std::sort(sorted_types.begin(), sorted_types.end());
                for (auto &&i: sorted_types) {
                    fputs(i.c_str(), fout);
                    fputc('\n', fout);
                }
                fclose(fout);
                fprintf(stderr, "midout: %zu items written to %s\n",
                        sorted_types.size(), output_fname);
            }
    };
}

void midout::on_region_used(const std::type_info &type) {
    static UsedTypes used_types;
    used_types.add(type.name());
}

#endif  // MIDOUT_PROFILING

#ifdef MIDOUT_GENERATED
#pragma message "stripping by midout enabled"
#endif