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);

}

Reply via email to