Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new warning for deprecated keysyms #356

Merged
merged 4 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 74 additions & 6 deletions bench/bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@

#include <assert.h>
#include <stdio.h>
#include <math.h>

#include "bench.h"
#include "../src/utils.h"

#ifndef _WIN32
#include <time.h>
#include <sys/time.h>
#else
#include <windows.h>
Expand Down Expand Up @@ -67,7 +69,7 @@ bench_start(struct bench *bench)
(void) gettimeofday(&val, NULL);
bench->start = (struct bench_time) {
.seconds = val.tv_sec,
.microseconds = val.tv_usec,
.nanoseconds = val.tv_usec * 1000,
};
}

Expand All @@ -78,17 +80,43 @@ bench_stop(struct bench *bench)
(void) gettimeofday(&val, NULL);
bench->stop = (struct bench_time) {
.seconds = val.tv_sec,
.microseconds = val.tv_usec,
.nanoseconds = val.tv_usec * 1000,
};
}

#ifndef _WIN32
void
bench_start2(struct bench *bench)
{
struct timespec t;
(void) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
// (void) clock_gettime(CLOCK_MONOTONIC, &t);
bench->start = (struct bench_time) {
.seconds = t.tv_sec,
.nanoseconds = t.tv_nsec,
};
}

void
bench_stop2(struct bench *bench)
{
struct timespec t;
(void) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t);
// (void) clock_gettime(CLOCK_MONOTONIC, &t);
bench->stop = (struct bench_time) {
.seconds = t.tv_sec,
.nanoseconds = t.tv_nsec,
};
}
#endif

void
bench_elapsed(const struct bench *bench, struct bench_time *result)
{
result->seconds = bench->stop.seconds - bench->start.seconds;
result->microseconds = bench->stop.microseconds - bench->start.microseconds;
if (result->microseconds < 0) {
result->microseconds += 1000000;
result->nanoseconds = bench->stop.nanoseconds - bench->start.nanoseconds;
if (result->nanoseconds < 0) {
result->nanoseconds += 1000000000;
result->seconds--;
}
}
Expand All @@ -101,8 +129,48 @@ bench_elapsed_str(const struct bench *bench)
int ret;

bench_elapsed(bench, &elapsed);
ret = asprintf(&buf, "%ld.%06ld", elapsed.seconds, elapsed.microseconds);
ret = asprintf(&buf, "%ld.%06ld", elapsed.seconds, elapsed.nanoseconds / 1000);
assert(ret >= 0);

return buf;
}

/* Utils for bench method adapted from: https://hackage.haskell.org/package/tasty-bench */

#define fit(x1, x2) (x1) / 5 + 2 * ((x2) / 5)
#define sqr(x) (x) * (x)

static void
predict(long long t1, long long t2, struct estimate *est)
{
const long long t = fit(t1, t2);
est->elapsed = t;
est->stdev = trunc(sqrt((double)sqr(t1 - t) + (double)sqr(t2 - 2 * t)));
}

#define high(t, prec) t + prec
#define low(t, prec) t - prec
#define MIN_PRECISION 1000000 /* 1ms */

void
predictPerturbed(const struct bench_time *b1, const struct bench_time *b2,
struct estimate *est)
{
const long long t1 = bench_time_elapsed_nanoseconds(b1);
const long long t2 = bench_time_elapsed_nanoseconds(b2);

#ifndef _WIN32
struct timespec ts;
(void) clock_getres(CLOCK_PROCESS_CPUTIME_ID, &ts);
long long precision = MAX(ts.tv_sec * 1000000000 + ts.tv_nsec, MIN_PRECISION);
#else
long long precision = MIN_PRECISION;
#endif

struct estimate est1;
struct estimate est2;
predict(t1, t2, est);
predict(low(t1, precision), high(t2, precision), &est1);
predict(high(t1, precision), low(t2, precision), &est2);
est->stdev = MAX(est1.stdev, est2.stdev);
}
62 changes: 61 additions & 1 deletion bench/bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,83 @@

struct bench_time {
long seconds;
long microseconds;
long nanoseconds;
};

struct bench {
struct bench_time start;
struct bench_time stop;
};

struct estimate {
long long int elapsed;
long long int stdev;
};

void
bench_start(struct bench *bench);
void
bench_stop(struct bench *bench);

#ifndef _WIN32
void
bench_start2(struct bench *bench);
void
bench_stop2(struct bench *bench);
#else
/* TODO: implement clock_getres for Windows */
#define bench_start2 bench_start
#define bench_stop2 bench_stop
#endif

void
bench_elapsed(const struct bench *bench, struct bench_time *result);

#define bench_time_elapsed_microseconds(elapsed) \
(elapsed)->nanoseconds / 1000 + 1000000 * (elapsed)->seconds
#define bench_time_elapsed_nanoseconds(elapsed) \
(elapsed)->nanoseconds + 1000000000 * (elapsed)->seconds

/* The caller is responsibile to free() the returned string. */
char *
bench_elapsed_str(const struct bench *bench);

/* Bench method adapted from: https://hackage.haskell.org/package/tasty-bench */
#define BENCH(target_stdev, n, time, est, ...) do { \
struct bench _bench; \
struct bench_time _t1; \
struct bench_time _t2; \
n = 1; \
bench_start2(&_bench); \
do { __VA_ARGS__ } while (0); \
bench_stop2(&_bench); \
bench_elapsed(&_bench, &_t1); \
do { \
bench_start2(&_bench); \
for (int k = 0; k < 2 * n; k++) { \
do { __VA_ARGS__ } while (0); \
} \
bench_stop2(&_bench); \
bench_elapsed(&_bench, &_t2); \
predictPerturbed(&_t1, &_t2, &est); \
if (est.stdev < (long long)(MAX(0, target_stdev * (double)est.elapsed))) {\
scale_estimate(est, n); \
time = _t2; \
n *= 2; \
break; \
} \
n *= 2; \
_t1 = _t2; \
} while (1); \
} while (0)

void
predictPerturbed(const struct bench_time *t1, const struct bench_time *t2,
struct estimate *est);

#define scale_estimate(est, n) do { \
est.elapsed /= n; \
est.stdev /= n; \
} while (0);

#endif /* LIBXKBCOMMON_BENCH_H */
Loading
Loading