summaryrefslogtreecommitdiffstats
path: root/src/bin/pg_test_timing
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_test_timing')
-rw-r--r--src/bin/pg_test_timing/.gitignore3
-rw-r--r--src/bin/pg_test_timing/Makefile36
-rw-r--r--src/bin/pg_test_timing/nls.mk4
-rw-r--r--src/bin/pg_test_timing/pg_test_timing.c208
-rw-r--r--src/bin/pg_test_timing/po/de.po84
-rw-r--r--src/bin/pg_test_timing/po/el.po86
-rw-r--r--src/bin/pg_test_timing/po/es.po86
-rw-r--r--src/bin/pg_test_timing/po/fr.po87
-rw-r--r--src/bin/pg_test_timing/po/ja.po83
-rw-r--r--src/bin/pg_test_timing/po/ru.po88
-rw-r--r--src/bin/pg_test_timing/po/sv.po83
-rw-r--r--src/bin/pg_test_timing/po/uk.po86
-rw-r--r--src/bin/pg_test_timing/po/zh_CN.po83
-rw-r--r--src/bin/pg_test_timing/t/001_basic.pl28
14 files changed, 1045 insertions, 0 deletions
diff --git a/src/bin/pg_test_timing/.gitignore b/src/bin/pg_test_timing/.gitignore
new file mode 100644
index 0000000..e5aac2a
--- /dev/null
+++ b/src/bin/pg_test_timing/.gitignore
@@ -0,0 +1,3 @@
+/pg_test_timing
+
+/tmp_check/
diff --git a/src/bin/pg_test_timing/Makefile b/src/bin/pg_test_timing/Makefile
new file mode 100644
index 0000000..84d84c3
--- /dev/null
+++ b/src/bin/pg_test_timing/Makefile
@@ -0,0 +1,36 @@
+# src/bin/pg_test_timing/Makefile
+
+PGFILEDESC = "pg_test_timing - test timing overhead"
+PGAPPICON = win32
+
+subdir = src/bin/pg_test_timing
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+OBJS = \
+ $(WIN32RES) \
+ pg_test_timing.o
+
+all: pg_test_timing
+
+pg_test_timing: $(OBJS) | submake-libpgport
+ $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+
+install: all installdirs
+ $(INSTALL_PROGRAM) pg_test_timing$(X) '$(DESTDIR)$(bindir)/pg_test_timing$(X)'
+
+installdirs:
+ $(MKDIR_P) '$(DESTDIR)$(bindir)'
+
+check:
+ $(prove_check)
+
+installcheck:
+ $(prove_installcheck)
+
+uninstall:
+ rm -f '$(DESTDIR)$(bindir)/pg_test_timing$(X)'
+
+clean distclean maintainer-clean:
+ rm -f pg_test_timing$(X) $(OBJS)
+ rm -rf tmp_check
diff --git a/src/bin/pg_test_timing/nls.mk b/src/bin/pg_test_timing/nls.mk
new file mode 100644
index 0000000..1affb9b
--- /dev/null
+++ b/src/bin/pg_test_timing/nls.mk
@@ -0,0 +1,4 @@
+# src/bin/pg_test_timing/nls.mk
+CATALOG_NAME = pg_test_timing
+AVAIL_LANGUAGES = de el es fr ja ru sv uk zh_CN
+GETTEXT_FILES = pg_test_timing.c
diff --git a/src/bin/pg_test_timing/pg_test_timing.c b/src/bin/pg_test_timing/pg_test_timing.c
new file mode 100644
index 0000000..c29d6f8
--- /dev/null
+++ b/src/bin/pg_test_timing/pg_test_timing.c
@@ -0,0 +1,208 @@
+/*
+ * pg_test_timing.c
+ * tests overhead of timing calls and their monotonicity: that
+ * they always move forward
+ */
+
+#include "postgres_fe.h"
+
+#include <limits.h>
+
+#include "getopt_long.h"
+#include "portability/instr_time.h"
+
+static const char *progname;
+
+static unsigned int test_duration = 3;
+
+static void handle_args(int argc, char *argv[]);
+static uint64 test_timing(unsigned int duration);
+static void output(uint64 loop_count);
+
+/* record duration in powers of 2 microseconds */
+long long int histogram[32];
+
+int
+main(int argc, char *argv[])
+{
+ uint64 loop_count;
+
+ set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_test_timing"));
+ progname = get_progname(argv[0]);
+
+ handle_args(argc, argv);
+
+ loop_count = test_timing(test_duration);
+
+ output(loop_count);
+
+ return 0;
+}
+
+static void
+handle_args(int argc, char *argv[])
+{
+ static struct option long_options[] = {
+ {"duration", required_argument, NULL, 'd'},
+ {NULL, 0, NULL, 0}
+ };
+
+ int option; /* Command line option */
+ int optindex = 0; /* used by getopt_long */
+ unsigned long optval; /* used for option parsing */
+ char *endptr;
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ printf(_("Usage: %s [-d DURATION]\n"), progname);
+ exit(0);
+ }
+ if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
+ {
+ puts("pg_test_timing (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
+
+ while ((option = getopt_long(argc, argv, "d:",
+ long_options, &optindex)) != -1)
+ {
+ switch (option)
+ {
+ case 'd':
+ errno = 0;
+ optval = strtoul(optarg, &endptr, 10);
+
+ if (endptr == optarg || *endptr != '\0' ||
+ errno != 0 || optval != (unsigned int) optval)
+ {
+ fprintf(stderr, _("%s: invalid argument for option %s\n"),
+ progname, "--duration");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(1);
+ }
+
+ test_duration = (unsigned int) optval;
+ if (test_duration == 0)
+ {
+ fprintf(stderr, _("%s: %s must be in range %u..%u\n"),
+ progname, "--duration", 1, UINT_MAX);
+ exit(1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+ progname);
+ exit(1);
+ break;
+ }
+ }
+
+ if (argc > optind)
+ {
+ fprintf(stderr,
+ _("%s: too many command-line arguments (first is \"%s\")\n"),
+ progname, argv[optind]);
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+ progname);
+ exit(1);
+ }
+
+
+ printf(ngettext("Testing timing overhead for %u second.\n",
+ "Testing timing overhead for %u seconds.\n",
+ test_duration),
+ test_duration);
+}
+
+static uint64
+test_timing(unsigned int duration)
+{
+ uint64 total_time;
+ int64 time_elapsed = 0;
+ uint64 loop_count = 0;
+ uint64 prev,
+ cur;
+ instr_time start_time,
+ end_time,
+ temp;
+
+ total_time = duration > 0 ? duration * INT64CONST(1000000) : 0;
+
+ INSTR_TIME_SET_CURRENT(start_time);
+ cur = INSTR_TIME_GET_MICROSEC(start_time);
+
+ while (time_elapsed < total_time)
+ {
+ int32 diff,
+ bits = 0;
+
+ prev = cur;
+ INSTR_TIME_SET_CURRENT(temp);
+ cur = INSTR_TIME_GET_MICROSEC(temp);
+ diff = cur - prev;
+
+ /* Did time go backwards? */
+ if (diff < 0)
+ {
+ fprintf(stderr, _("Detected clock going backwards in time.\n"));
+ fprintf(stderr, _("Time warp: %d ms\n"), diff);
+ exit(1);
+ }
+
+ /* What is the highest bit in the time diff? */
+ while (diff)
+ {
+ diff >>= 1;
+ bits++;
+ }
+
+ /* Update appropriate duration bucket */
+ histogram[bits]++;
+
+ loop_count++;
+ INSTR_TIME_SUBTRACT(temp, start_time);
+ time_elapsed = INSTR_TIME_GET_MICROSEC(temp);
+ }
+
+ INSTR_TIME_SET_CURRENT(end_time);
+
+ INSTR_TIME_SUBTRACT(end_time, start_time);
+
+ printf(_("Per loop time including overhead: %0.2f ns\n"),
+ INSTR_TIME_GET_DOUBLE(end_time) * 1e9 / loop_count);
+
+ return loop_count;
+}
+
+static void
+output(uint64 loop_count)
+{
+ int64 max_bit = 31,
+ i;
+ char *header1 = _("< us");
+ char *header2 = /* xgettext:no-c-format */ _("% of total");
+ char *header3 = _("count");
+ int len1 = strlen(header1);
+ int len2 = strlen(header2);
+ int len3 = strlen(header3);
+
+ /* find highest bit value */
+ while (max_bit > 0 && histogram[max_bit] == 0)
+ max_bit--;
+
+ printf(_("Histogram of timing durations:\n"));
+ printf("%*s %*s %*s\n",
+ Max(6, len1), header1,
+ Max(10, len2), header2,
+ Max(10, len3), header3);
+
+ for (i = 0; i <= max_bit; i++)
+ printf("%*ld %*.5f %*lld\n",
+ Max(6, len1), 1l << i,
+ Max(10, len2) - 1, (double) histogram[i] * 100 / loop_count,
+ Max(10, len3), histogram[i]);
+}
diff --git a/src/bin/pg_test_timing/po/de.po b/src/bin/pg_test_timing/po/de.po
new file mode 100644
index 0000000..6bcbc73
--- /dev/null
+++ b/src/bin/pg_test_timing/po/de.po
@@ -0,0 +1,84 @@
+# German message translation file for pg_test_timing
+# Copyright (C) 2021 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+#
+# Use these quotes: »%s«
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL) 13\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-04-12 14:17+0000\n"
+"PO-Revision-Date: 2021-04-12 16:37+0200\n"
+"Last-Translator: Peter Eisentraut <peter@eisentraut.org>\n"
+"Language-Team: German <pgsql-translators@postgresql.org>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Aufruf: %s [-d DAUER]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: ungültiges Argument für Option %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %s muss im Bereich %u..%u sein\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Testen des Overheads der Zeitmessung für %u Sekunde\n"
+msgstr[1] "Testen des Overheads der Zeitmessung für %u Sekunden\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Rückwärts gehende Uhr festgestellt.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Zeitdifferenz: %d ms\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Zeit pro Durchlauf einschließlich Overhead: %0.2f ns\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< µs"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% von gesamt"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "Anzahl"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Histogramm der Dauern der Zeitmessungen:\n"
diff --git a/src/bin/pg_test_timing/po/el.po b/src/bin/pg_test_timing/po/el.po
new file mode 100644
index 0000000..3d1ba0b
--- /dev/null
+++ b/src/bin/pg_test_timing/po/el.po
@@ -0,0 +1,86 @@
+# Greek message translation file for pg_test_timing
+# Copyright (C) 2021 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package.
+# Georgios Kokolatos <gkokolatos@pm.me>, 2021
+#
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL) 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-07-20 03:46+0000\n"
+"PO-Revision-Date: 2021-07-20 10:42+0200\n"
+"Last-Translator: Georgios Kokolatos <gkokolatos@pm.me>\n"
+"Language-Team: \n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 3.0\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Χρήση: %s [-d DURATION]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: μη έγκυρη παράμετρος για την επιλογή %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Δοκιμάστε «%s --help» για περισσότερες πληροφορίες.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %s πρέπει να βρίσκεται εντός εύρους %u..%u\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: πάρα πολλοί παράμετροι εισόδου από την γραμμή εντολών (η πρώτη είναι η «%s»)\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Έλεγχος επίφορτου χρονισμού για %u δευτερόλεπτο.\n"
+msgstr[1] "Έλεγχος επίφορτου χρονισμού για %u δευτερόλεπτα.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Εντοπίστηκε ρολόι που πηγαίνει προς τα πίσω στο χρόνο.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Χρονική στρέβλωση: %d ms\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Χρόνος ανά βρόχο συμπεριλαμβανομένου επίφορτου: %0.2f ns\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< us"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% του συνόλου"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "μετρητής"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Ιστόγραμμα διαρκειών χρονισμού:\n"
diff --git a/src/bin/pg_test_timing/po/es.po b/src/bin/pg_test_timing/po/es.po
new file mode 100644
index 0000000..e66c17f
--- /dev/null
+++ b/src/bin/pg_test_timing/po/es.po
@@ -0,0 +1,86 @@
+# Spanish message translation file for pg_test_timing
+#
+# Copyright (c) 2017-2019, PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+#
+# Carlos Chapi <carloswaldo@babelruins.org>, 2017-2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL) 12\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-08-07 20:34+0000\n"
+"PO-Revision-Date: 2021-05-19 22:07-0500\n"
+"Last-Translator: Carlos Chapi <carloswaldo@babelruins.org>\n"
+"Language-Team: PgSQL-es-Ayuda <pgsql-es-ayuda@lists.postgresql.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 2.4.2\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Empleo: %s [-d DURACIÓN]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: argumento no válido para la opción %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Pruebe «%s --help» para mayor información.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %s debe estar en el rango %u..%u\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Midiendo sobrecosto de lectura de reloj durante %u segundo.\n"
+msgstr[1] "Midiendo sobrecosto de lectura de reloj durante %u segundos.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Se detectó que el reloj retrocede en el tiempo.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Desfase de tiempo: %d ms\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Tiempo por lectura incluyendo sobrecosto: %0.2f ns\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< us"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% del total"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "cantidad"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Histograma de duraciones de lectura de reloj:\n"
diff --git a/src/bin/pg_test_timing/po/fr.po b/src/bin/pg_test_timing/po/fr.po
new file mode 100644
index 0000000..17d321c
--- /dev/null
+++ b/src/bin/pg_test_timing/po/fr.po
@@ -0,0 +1,87 @@
+# LANGUAGE message translation file for pg_test_timing
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL) 12\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-04-22 04:17+0000\n"
+"PO-Revision-Date: 2021-04-22 10:10+0200\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+"X-Generator: Poedit 2.4.2\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Usage: %s [-d DURÉE]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s : argument invalide pour l'option %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Essayez « %s --help » pour plus d'informations.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s : %s doit être compris entre %u et %u\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Test du coût du chronométrage pour %u seconde.\n"
+msgstr[1] "Test du coût du chronométrage pour %u secondes.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Détection d'une horloge partant à rebours.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Décalage de temps : %d ms\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Durée par boucle incluant le coût : %0.2f ns\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< us"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% du total"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "nombre"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Histogramme des durées de chronométrage\n"
+
+#~ msgid "%s: duration must be a positive integer (duration is \"%d\")\n"
+#~ msgstr "%s : la durée doit être un entier positif (la durée est « %d »)\n"
diff --git a/src/bin/pg_test_timing/po/ja.po b/src/bin/pg_test_timing/po/ja.po
new file mode 100644
index 0000000..b5b2586
--- /dev/null
+++ b/src/bin/pg_test_timing/po/ja.po
@@ -0,0 +1,83 @@
+# LANGUAGE message translation file for pg_test_timing
+# Copyright (C) 2022 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL 14)\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-08-20 15:40+0900\n"
+"PO-Revision-Date: 2021-05-17 14:59+0900\n"
+"Last-Translator: Michihide Hotta <hotta@net-newbie.com>\n"
+"Language-Team: \n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 1.8.13\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "使用方法: %s [-d 期間]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: オプション%sの引数が不正です\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "詳細は\"%s --help\"で確認してください。\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %sは%u..%uの範囲になければなりません\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: コマンドライン引数が多すぎます (先頭は\"%s\")\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "%u秒のタイミングのオーバーヘッドをテストしています。\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "クロックの時刻が逆行していることを検出しました。\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "逆行した時間: %d ms\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "オーバーヘッド込みのループ時間毎: %0.2f ns\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< us"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "割合(%)"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "回数"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "タイミング持続時間のヒストグラム:\n"
diff --git a/src/bin/pg_test_timing/po/ru.po b/src/bin/pg_test_timing/po/ru.po
new file mode 100644
index 0000000..2bc6ad3
--- /dev/null
+++ b/src/bin/pg_test_timing/po/ru.po
@@ -0,0 +1,88 @@
+# Russian message translation file for pg_test_timing
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Alexander Lakhin <a.lakhin@postgrespro.ru>, 2017, 2021.
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL) 10\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-08-14 06:29+0300\n"
+"PO-Revision-Date: 2021-09-04 12:18+0300\n"
+"Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n"
+"Language-Team: Russian <pgsql-ru-general@postgresql.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Использование: %s [-d ДЛИТЕЛЬНОСТЬ]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: недопустимый аргумент параметра %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Для дополнительной информации попробуйте \"%s --help\".\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: параметр %s должен быть в диапазоне %u..%u\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: слишком много аргументов командной строки (первый: \"%s\")\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Оценка издержек замеров времени в течение %u сек.\n"
+msgstr[1] "Оценка издержек замеров времени в течение %u сек.\n"
+msgstr[2] "Оценка издержек замеров времени в течение %u сек.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Обнаружен обратный ход часов.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Сдвиг времени: %d мс\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Время одного цикла, включая издержки: %0.2f нс\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< мкс"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% от общего"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "число"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Гистограмма длительности замеров времени:\n"
+
+#~ msgid "%s: duration must be a positive integer (duration is \"%d\")\n"
+#~ msgstr ""
+#~ "%s: длительность должна задаваться положительным целым (указано: \"%d\")\n"
diff --git a/src/bin/pg_test_timing/po/sv.po b/src/bin/pg_test_timing/po/sv.po
new file mode 100644
index 0000000..92c130d
--- /dev/null
+++ b/src/bin/pg_test_timing/po/sv.po
@@ -0,0 +1,83 @@
+# Swedish message translation file for pg_test_timing
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Dennis Björklund <db@zigo.dhs.org>, 2017, 2018, 2019, 2020, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PostgreSQL 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-11-06 17:16+0000\n"
+"PO-Revision-Date: 2021-11-06 21:59+0100\n"
+"Last-Translator: Dennis Björklund <db@zigo.dhs.org>\n"
+"Language-Team: Swedish <pgsql-translators@postgresql.org>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Användning: %s [-d TID]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: ogiltigt argument för flaggan %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Försök med \"%s --help\" för mer information.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %s måste vara i intervallet %u..%u\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: för många kommandoradsargument (första är \"%s\")\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Testar timingoverhead under %u sekund.\n"
+msgstr[1] "Testar timingoverhead under %u sekunder.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Upptäckte att klockan gått bakåt i tiden.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Tidsförskjutning: %d ms\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Tid per varv inklusive overhead: %0.2f ns\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< us"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% av totalt"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "antal"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Histogram över tider:\n"
diff --git a/src/bin/pg_test_timing/po/uk.po b/src/bin/pg_test_timing/po/uk.po
new file mode 100644
index 0000000..c898d45
--- /dev/null
+++ b/src/bin/pg_test_timing/po/uk.po
@@ -0,0 +1,86 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: postgresql\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-03-16 09:17+0000\n"
+"PO-Revision-Date: 2022-06-19 10:10\n"
+"Last-Translator: \n"
+"Language-Team: Ukrainian\n"
+"Language: uk_UA\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
+"X-Crowdin-Project: postgresql\n"
+"X-Crowdin-Project-ID: 324573\n"
+"X-Crowdin-Language: uk\n"
+"X-Crowdin-File: /REL_14_STABLE/pg_test_timing.pot\n"
+"X-Crowdin-File-ID: 748\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "Використання: %s [-d ТРИВАЛІСТЬ]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: неприпустимий аргумент для параметру %s\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %s має бути в діапазоні %u..%u\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: забагато аргументів у командному рядку (перший \"%s\")\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "Тестування накладних витрат часу на %u секунду.\n"
+msgstr[1] "Тестування накладних витрат часу на %u секунди.\n"
+msgstr[2] "Тестування накладних витрат часу на %u секунд.\n"
+msgstr[3] "Тестування накладних витрат часу на %u секунд.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "Годинник іде в зворотньому напряму у минуле.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "Зсув часу: %d мс\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "Час одного цикла, у тому числі накладні витрати: %0.2f нс\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< мкс"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "% від загалу"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "кількість"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "Гістограмма тривалості замірів часу:\n"
+
diff --git a/src/bin/pg_test_timing/po/zh_CN.po b/src/bin/pg_test_timing/po/zh_CN.po
new file mode 100644
index 0000000..10b5efc
--- /dev/null
+++ b/src/bin/pg_test_timing/po/zh_CN.po
@@ -0,0 +1,83 @@
+# LANGUAGE message translation file for pg_test_timing
+# Copyright (C) 2019 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package.
+# FIRST AUTHOR <zhangjie2@fujitsu.com>, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_test_timing (PostgreSQL) 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-08-14 05:47+0000\n"
+"PO-Revision-Date: 2021-06-10 10:50+0800\n"
+"Last-Translator: Jie Zhang <zhangjie2@fujitsu.com>\n"
+"Language-Team: Chinese (Simplified) <zhangjie2@fujitsu.com>\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: pg_test_timing.c:59
+#, c-format
+msgid "Usage: %s [-d DURATION]\n"
+msgstr "用法: %s [-d 持续时间]\n"
+
+#: pg_test_timing.c:81
+#, c-format
+msgid "%s: invalid argument for option %s\n"
+msgstr "%s: 选项%s的参数无效\n"
+
+#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "请用 \"%s --help\" 获取更多的信息.\n"
+
+#: pg_test_timing.c:90
+#, c-format
+msgid "%s: %s must be in range %u..%u\n"
+msgstr "%s: %s必须位于%u..%u的范围内\n"
+
+#: pg_test_timing.c:107
+#, c-format
+msgid "%s: too many command-line arguments (first is \"%s\")\n"
+msgstr "%s: 命令行参数太多 (第一个是 \"%s\")\n"
+
+#: pg_test_timing.c:115
+#, c-format
+msgid "Testing timing overhead for %u second.\n"
+msgid_plural "Testing timing overhead for %u seconds.\n"
+msgstr[0] "测试%u秒的计时开销.\n"
+msgstr[1] "测试%u秒的计时开销.\n"
+
+#: pg_test_timing.c:151
+#, c-format
+msgid "Detected clock going backwards in time.\n"
+msgstr "检测到时钟时间倒转.\n"
+
+#: pg_test_timing.c:152
+#, c-format
+msgid "Time warp: %d ms\n"
+msgstr "时间错位: %d 毫秒\n"
+
+#: pg_test_timing.c:175
+#, c-format
+msgid "Per loop time including overhead: %0.2f ns\n"
+msgstr "每次循环的平均开销: %0.2f 纳秒\n"
+
+#: pg_test_timing.c:186
+msgid "< us"
+msgstr "< 微秒"
+
+#: pg_test_timing.c:187
+#, no-c-format
+msgid "% of total"
+msgstr "总计的 %"
+
+#: pg_test_timing.c:188
+msgid "count"
+msgstr "计数"
+
+#: pg_test_timing.c:197
+#, c-format
+msgid "Histogram of timing durations:\n"
+msgstr "持续时间的柱状图:\n"
diff --git a/src/bin/pg_test_timing/t/001_basic.pl b/src/bin/pg_test_timing/t/001_basic.pl
new file mode 100644
index 0000000..72e5a42
--- /dev/null
+++ b/src/bin/pg_test_timing/t/001_basic.pl
@@ -0,0 +1,28 @@
+
+# Copyright (c) 2021, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+
+use Config;
+use TestLib;
+use Test::More tests => 12;
+
+#########################################
+# Basic checks
+
+program_help_ok('pg_test_timing');
+program_version_ok('pg_test_timing');
+program_options_handling_ok('pg_test_timing');
+
+#########################################
+# Test invalid option combinations
+
+command_fails_like(
+ [ 'pg_test_timing', '--duration', 'a' ],
+ qr/\Qpg_test_timing: invalid argument for option --duration\E/,
+ 'pg_test_timing: invalid argument for option --duration');
+command_fails_like(
+ [ 'pg_test_timing', '--duration', '0' ],
+ qr/\Qpg_test_timing: --duration must be in range 1..4294967295\E/,
+ 'pg_test_timing: --duration must be in range');