pace.c 3.6 KB
Newer Older
Andreas Schmidt's avatar
Andreas Schmidt committed
1 2 3 4 5 6 7
#include "pace.h"
#include "../clock.h"
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "../../util/time.h"
#include <math.h>

Andreas Schmidt's avatar
Naming.  
Andreas Schmidt committed
8
PrrtPace* PrrtPace_create(void) {
Andreas Schmidt's avatar
Andreas Schmidt committed
9 10
    PrrtPace* pace = (PrrtPace*) calloc(1, sizeof(PrrtPace));
    check_mem(pace);
11
    prrtTimedelta_t filterLength_us = 2 * 1000 * 1000; // 2 seconds
Marlene Böhmer's avatar
Marlene Böhmer committed
12 13 14
    pace->internalPace = PrrtPaceFilter_create(filterLength_us, FILTER_TYPE_MIN);
    pace->dependentPace = PrrtPaceFilter_create(filterLength_us, FILTER_TYPE_MIN);
    pace->externalPace = PrrtPaceFilter_create(filterLength_us, FILTER_TYPE_MIN);
Andreas Schmidt's avatar
Andreas Schmidt committed
15

Andreas Schmidt's avatar
Naming.  
Andreas Schmidt committed
16
    pace->totalPauseDuration_ns = 0;
Andreas Schmidt's avatar
Andreas Schmidt committed
17 18
    pace->initialized = false;
    pace->firstRoundDone = false;
Andreas Schmidt's avatar
Andreas Schmidt committed
19 20 21 22 23 24 25 26 27 28 29
    clock_gettime(CLOCK_REALTIME, &pace->lastStartTimestamp);
    clock_gettime(CLOCK_REALTIME, &pace->lastEndTimestamp);
    clock_gettime(CLOCK_REALTIME, &pace->lastPauseTimestamp);
    return pace;

    error:
    PERROR("Out of memory%s.", "");
    return NULL;

}
bool PrrtPace_destroy(PrrtPace* pace) {
Andreas Schmidt's avatar
Andreas Schmidt committed
30 31
    if(pace->internalPace != NULL) {
        check(PrrtPaceFilter_destroy(pace->internalPace), "Cannot destroy internalPace.")
Andreas Schmidt's avatar
Andreas Schmidt committed
32
    }
Andreas Schmidt's avatar
Andreas Schmidt committed
33 34 35 36 37 38 39

    if(pace->dependentPace != NULL) {
        check(PrrtPaceFilter_destroy(pace->dependentPace), "Cannot destroy dependentPace.")
    }

    if(pace->externalPace != NULL) {
        check(PrrtPaceFilter_destroy(pace->externalPace), "Cannot destroy externalPace.")
Andreas Schmidt's avatar
Andreas Schmidt committed
40 41 42 43 44 45 46 47
    }

    free(pace);
    return true;
    error:
    return false;
}

Andreas Schmidt's avatar
Andreas Schmidt committed
48 49
prrtTimedelta_t PrrtPace_get_internal(PrrtPace* pace) {
    return PrrtPaceFilter_get(pace->internalPace);
Andreas Schmidt's avatar
Andreas Schmidt committed
50 51
}

Andreas Schmidt's avatar
Andreas Schmidt committed
52 53
prrtTimedelta_t PrrtPace_get_external(PrrtPace* pace) {
    return PrrtPaceFilter_get(pace->externalPace);
Andreas Schmidt's avatar
Andreas Schmidt committed
54 55
}

Andreas Schmidt's avatar
Andreas Schmidt committed
56 57 58 59 60 61 62 63 64
prrtTimedelta_t PrrtPace_get_dependent(PrrtPace* pace) {
    return PrrtPaceFilter_get(pace->dependentPace);
}

prrtTimedelta_t PrrtPace_get_total(PrrtPace* pace) {
    return PrrtPaceFilter_get(pace->internalPace) + PrrtPaceFilter_get(pace->externalPace);
}

prrtTimedelta_t PrrtPace_get_effective(PrrtPace* pace) {
65
    return (prrtTimedelta_t) MAX(0, ((int64_t) PrrtPaceFilter_get(pace->externalPace)) + ((int64_t)PrrtPaceFilter_get(pace->internalPace)) - ((int64_t)PrrtPaceFilter_get(pace->dependentPace)));
Andreas Schmidt's avatar
Andreas Schmidt committed
66 67 68 69 70
}

void PrrtPace_track_start(PrrtPace* pace) {
    struct timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
Andreas Schmidt's avatar
Andreas Schmidt committed
71 72 73 74 75
    if (pace->initialized) {
        long long int internalDelta_ns = timedelta(&pace->lastEndTimestamp, &pace->lastStartTimestamp);
        long long int externalDelta_ns = timedelta(&now, &pace->lastEndTimestamp);

        if (pace->firstRoundDone) {
76 77
            // make sure internal >= dependent
            PrrtPaceFilter_update(pace->internalPace, (prrtTimedelta_t) MAX(0, round(((double) MAX(internalDelta_ns, pace->totalPauseDuration_ns)) / 1000)));
Andreas Schmidt's avatar
Andreas Schmidt committed
78 79
            PrrtPaceFilter_update(pace->externalPace, (prrtTimedelta_t) MAX(0, round(((double) externalDelta_ns) / 1000)));
            PrrtPaceFilter_update(pace->dependentPace, (prrtTimedelta_t) MAX(0, round(((double) pace->totalPauseDuration_ns) / 1000)));
Andreas Schmidt's avatar
Andreas Schmidt committed
80
        }
Andreas Schmidt's avatar
Andreas Schmidt committed
81
        pace->firstRoundDone = true;
Andreas Schmidt's avatar
Andreas Schmidt committed
82
    }
Andreas Schmidt's avatar
Naming.  
Andreas Schmidt committed
83
    pace->totalPauseDuration_ns = 0;
Andreas Schmidt's avatar
Andreas Schmidt committed
84
    pace->lastStartTimestamp = now;
Andreas Schmidt's avatar
Andreas Schmidt committed
85
    pace->initialized = true;
Andreas Schmidt's avatar
Andreas Schmidt committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99
}
void PrrtPace_track_end(PrrtPace* pace) {
    clock_gettime(CLOCK_REALTIME, &pace->lastEndTimestamp);
}

void PrrtPace_track_pause(PrrtPace* pace) {
    clock_gettime(CLOCK_REALTIME, &pace->lastPauseTimestamp);
}

void PrrtPace_track_resume(PrrtPace* pace) {
    struct timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
    long long int delta = timedelta(&now, &pace->lastPauseTimestamp);
    clock_gettime(CLOCK_REALTIME, &pace->lastPauseTimestamp);
Andreas Schmidt's avatar
Naming.  
Andreas Schmidt committed
100
    pace->totalPauseDuration_ns += delta;
Andreas Schmidt's avatar
Andreas Schmidt committed
101
}