Chrono time wrapper

https://gist.github.com/arxeiss/540e975b96b0d2c70c2be96a28da07e9

This is an implementation of the generic TimeMeasurement interface. The parameters are: TODO

module chrono_time_wrapper(timer) = {

    object measures = {}          # struct holding the measures

    <<< header
include include
    using namespace std::chrono;

    class ChronoTimeMeasuring;

    >>>

    <<< impl

        struct ChronoTimeMeasuring {
            %`timer.start` start;
            %`timer.timeout` timeout;
            %`timer.now_micros` now_micros;
            %`timer.now_millis` now_millis;
            %`timer.now_micros_last_bp` now_micros_last_bp;
            %`timer.now_millis_last_bp` now_millis_last_bp;
        ChronoTimeMeasuring(
            const %`timer.start` start,
            const %`timer.timeout` timeout,
            const %`timer.now_micros` now_micros,
            const %`timer.now_millis` now_millis,
            const %`timer.now_micros_last_bp` now_micros_last_bp,
            const %`timer.now_millis_last_bp` now_millis_last_bp
        )
        : start(start), timeout(timeout), now_micros(now_micros), now_millis(now_millis), now_micros_last_bp(now_micros_last_bp), now_millis_last_bp(now_millis_last_bp) {}
        };

        std::string chrono_last_bp_ms = "0";
        std::string chrono_last_bp_micro = "0";
        bool chrono_started = false;
        std::chrono::high_resolution_clock::time_point chrono_start;
        std::unordered_map<std::string, std::chrono::high_resolution_clock::time_point> chrono_breakpoints = std::unordered_map<std::string, std::chrono::high_resolution_clock::time_point>();
        unsigned long  long chrono_fake_sleep_ms_duration = 0;
        unsigned long  long chrono_fake_sleep_ms_start = 0; //seems to have bug with breakpoint

        bool chrono_startMeasuring() {
            if (!chrono_started)
            {
                chrono_start = std::chrono::high_resolution_clock::now();
                chrono_started = true;
                return true;
            }
            return false;
        }

        bool chrono_insertBreakpoint(std::string name) {
            if (chrono_breakpoints.count(name) == 0)
            {
                chrono_breakpoints[name] = std::chrono::high_resolution_clock::now();
                return true;
            }
            return false;
        }

        unsigned long  long   chrono_getTimeFromBeginning(bool microSeconds = false) {
            if (!chrono_started)
            {
                return -1;
            }
            if (microSeconds)
            {
                return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - chrono_start).count();
            }
            return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - chrono_start).count();
        }

        unsigned long  long   chrono_getTimeFromBreakpoint(std::string breakpoint, bool microSeconds = false) {
            if (!chrono_started || chrono_breakpoints.count(breakpoint) == 0)
            {
                return -1;
            }
            if (microSeconds)
            {
                return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - chrono_breakpoints[breakpoint]).count();
            }
            return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - chrono_breakpoints[breakpoint]).count();
        }

        int chrono_msleep(long msec)
        {
            struct timespec ts;
            int res;

            if (msec < 0)
            {
                errno = EINVAL;
                return -1;
            }

            ts.tv_sec = msec / 1000;
            ts.tv_nsec = (msec % 1000) * 1000000;

            do {
                res = nanosleep(&ts, &ts);
            } while (res && errno == EINTR);

            return res;
        }

    >>>

    <<< member

    std::chrono::high_resolution_clock::time_point chrono_start;
    std::unordered_map<std::string, std::chrono::high_resolution_clock::time_point> chrono_breakpoints;
    ChronoTimeMeasuring * `measures`;

    >>>

    <<< init

        `measures` = new ChronoTimeMeasuring(`timer.start`, `timer.timeout`, `timer.now_micros`, `timer.now_millis`, `timer.now_micros_last_bp`, `timer.now_millis_last_bp`);

    >>>
TODO probably, we will need some type of fingerprinting here to make sure that the time syscall are those we want in shadow

    object impl = {

        implement start { # timer.start ??
            <<<
            std::cerr << "chrono time = start" << std::endl;
            chrono_startMeasuring();
            chrono_insertBreakpoint(chrono_last_bp_ms);
            chrono_insertBreakpoint(chrono_last_bp_micro);
            >>>
        }

        implement timeout {
            <<<
            if(chrono_started)
            {
                chrono_started = false;
                std::cerr << "chrono time = timeout - timer chrono_started" << std::endl;
            }
            else
            {
                std::cerr << "chrono time = timeout - timer not chrono_started" << std::endl;
            }

            >>>
        }

        implement now_micros returns (i:microseconds) {
            <<<
            std::cerr << "chrono time = now_micros" << std::endl;
            if(chrono_started) {
                unsigned long  long  time = chrono_getTimeFromBeginning(true);
                std::cerr << "chrono time = now_micros - timer chrono_started" << std::endl;
                std::cerr << "chrono time = now_micros - time = " << time << std::endl;
            }
            else {
                std::cerr << "chrono time = now_micros - timer not chrono_started" << std::endl;
            }
            >>>
        }

        implement now_millis returns (i:milliseconds) {
            <<<
            std::cerr << "chrono time = now_millis" << std::endl;
            if(chrono_started) {
                unsigned long  long  time = chrono_getTimeFromBeginning(false);
                std::cerr << "chrono time = now_millis - timer chrono_started" << std::endl;
                std::cerr << "chrono time = now_millis - time = " << time << std::endl;
            }
            else {
                std::cerr << "chrono time = now_millis - timer not chrono_started" << std::endl;
            }
            >>>
        }

        implement now_micros_last_bp returns (i:microseconds) {
            <<<
            std::cerr << "chrono time = now_micros_last_bp" << std::endl;
            if(chrono_started) {
                unsigned long  long time = chrono_getTimeFromBreakpoint(chrono_last_bp_micro,true);
                std::cerr << "chrono time = now_micros_last_bp - timer chrono_started" << std::endl;
                std::cerr << "chrono time = now_micros_last_bp - time = " << time << std::endl;
                int int_last_bp = std::stoi(chrono_last_bp_micro);
                int_last_bp++;
                chrono_last_bp_micro = std::to_string(int_last_bp);
                chrono_insertBreakpoint(chrono_last_bp_micro);
            }
            else {
                std::cerr << "chrono time = now_micros_last_bp - timer not chrono_started" << std::endl;
            }
            >>>
        }

        implement now_millis_last_bp returns (i:milliseconds) {
            <<<
            std::cerr << "chrono time = now_millis_last_bp" << std::endl;
            if(chrono_started) {
                unsigned long  long time = chrono_getTimeFromBreakpoint(chrono_last_bp_ms,false);
                std::cerr << "chrono time = now_millis_last_bp - timer chrono_started" << std::endl;
                std::cerr << "chrono time = now_millis_last_bp - time = " << time << std::endl;
                int int_last_bp = std::stoi(chrono_last_bp_ms);
                int_last_bp++;
                chrono_last_bp_ms = std::to_string(int_last_bp);
                chrono_insertBreakpoint(chrono_last_bp_ms);
            }
            else {
                std::cerr << "chrono time = now_millis_last_bp - timer not chrono_started" << std::endl;
            }
            >>>
        }

        implement sleep(i:milliseconds) {
            <<<
            chrono_msleep(i);
            >>>
        }

        implement sleep_fake(i:milliseconds) returns (r:milliseconds) {
            <<<
            if(started) {
                chrono_fake_sleep_ms_duration = i;
                unsigned long  long  time = getTimeFromBeginning(false);
                chrono_fake_sleep_ms_start = time;
                std::cerr << "C time = sleep_fake - timer started" << std::endl;
                std::cerr << "C time = sleep_fake - time = " << time << std::endl;
                std::cerr << "C time = sleep_fake - fake_sleep_ms_duration = " << chrono_fake_sleep_ms_duration << std::endl;
                unsigned long  long  time_fb = getTimeFromBreakpoint("fakesleep",false);
                std::cerr << "C time = sleep_fake - time_fb = " << time_fb << std::endl;
                insertBreakpoint("fakesleep");
                unsigned long  long  time_fb2 = getTimeFromBreakpoint("fakesleep",false);
                std::cerr << "C time = sleep_fake - time_fb2 = " << time_fb2 << std::endl;

                r = time;
            }
            else {
                std::cerr << "C time = sleep_fake - timer not started" << std::endl;
            }
            >>>
        }

        implement is_sleep_fake_timeout returns (b:bool) {
            <<<
            if(started) {
                if(chrono_fake_sleep_ms_duration == 0)
                {
                    b = true;
                }
                else {
                    unsigned long  long  time_now = getTimeFromBeginning(false);
                    unsigned long  long  time = getTimeFromBreakpoint("fake_sleep",false);
                    std::cerr << "C time = is_sleep_fake_timeout - timer started" << std::endl;
                    std::cerr << "C time = is_sleep_fake_timeout - time = " << time << std::endl;
                    std::cerr << "C time = is_sleep_fake_timeout - fake_sleep_ms_duration = " << chrono_fake_sleep_ms_duration << std::endl;
                    if(chrono_fake_sleep_ms_duration <= time - chrono_fake_sleep_ms_start) {
                        b = true;
                    }
                    else {
                        b = false;
                    }
                }
            }
            else {
                std::cerr << "C time = is_sleep_fake_timeout - timer not started" << std::endl;
            }
            >>>
        }


        trusted isolate iso = this

        attribute test = impl

    }

}