On 2022-05-13 04:14, Andres Freund wrote:
One interesting tidbit is that the log timestamps are computed differently (with elog.c:get_formatted_log_time()) than the reset timestamp (with GetCurrentTimestamp()). Both use gettimeofday() internally. I wonder if there's a chance that somehow openbsd ends up with more usecs than "fit" in a second in the result of gettimeofday()? The elog.c case would truncate everything above a second away afaics: /* 'paste' milliseconds into place... */ sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_usec / 1000)); memcpy(formatted_log_time + 19, msbuf, 4); whereas GetCurrentTimestamp() would add them to the timestamp: result = (TimestampTz) tp.tv_sec - ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY); result = (result * USECS_PER_SEC) + tp.tv_usec;
Well, I don't know if you remember but there was a thread a while back and a test program (monotime.c) to test the clock if it could go backwards and openbsd showed the following result when running the attached testprogram:
openbsd 5.9: $ ./monotime 1021006 Starting 1017367 Starting 1003415 Starting 1007598 Starting 1021006 Stopped 1007598 Stopped 1017367 Stopped 1003415 Stopped openbsd 6.9: $ ./monotime 410310 Starting 547727 Starting 410310 Back 262032.372314102 => 262032.242045208 410310 Stopped 465180 Starting 255646 Starting 547727 Stopped 465180 Stopped 255646 Stopped could that have something to do with it? /Mikael
#include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <time.h> #include <unistd.h> #include <pthread.h> #include <stdlib.h> #define NTHREAD 4 #define NTRY 50000 void * start(void *dummy) { int i; struct timespec ts0, ts1; printf("%d Starting\n", (int)getthrid()); clock_gettime(CLOCK_MONOTONIC, &ts0); for (i = 0; i < NTRY; i++) { clock_gettime(CLOCK_MONOTONIC, &ts1); if (timespeccmp(&ts0, &ts1, <=)) { ts0 = ts1; continue; } printf("%d Back %lld.%09lu => %lld.%09lu\n", (int)getthrid(), ts0.tv_sec, ts0.tv_nsec, ts1.tv_sec, ts1.tv_nsec); break; } printf("%d Stopped\n", (int)getthrid()); return (NULL); } int main(int argc, char *argv[]) { int i, n = NTHREAD; pthread_t *threads; threads = calloc(n, sizeof(pthread_t)); for (i = 0; i < n; i++) pthread_create(&threads[i], NULL, start, NULL); for (i = 0; i < n; i++) pthread_join(threads[i], NULL); }