Repository: valkey-io/valkey
File: src/monotonic.c (C)

Code before:

    /* Determine the number of TSC ticks in a micro-second.  This is
     * a constant value matching the standard speed of the processor.
     * On modern processors, this speed remains constant even though
     * the actual clock speed varies dynamically for each core.  */
    rc = regcomp(&cpuGhzRegex, "^model name\\s+:.*@ ([0-9.]+)GHz", REG_EXTENDED);
    assert(rc == 0);

    /* Also check that the constant_tsc flag is present.  (It should be
     * unless this is a really old CPU.  */
    rc = regcomp(&constTscRegex, "^flags\\s+:.* constant_tsc", REG_EXTENDED);
    assert(rc == 0);

    FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
    if (cpuinfo != NULL) {
        while (fgets(buf, bufflen, cpuinfo) != NULL) {
            if (regexec(&cpuGhzRegex, buf, nmatch, pmatch, 0) == 0) {
                buf[pmatch[1].rm_eo] = '\0';
                double ghz = atof(&buf[pmatch[1].rm_so]);
                mono_ticksPerMicrosecond = (long)(ghz * 1000);
                break;
            }
        }
        /* Some CPUs may not contain clock speed in the model name */
        if (mono_ticksPerMicrosecond == 0) {
            /* Calibrate TSC against CLOCK_MONOTONIC */
            struct timespec start, end;
            uint64_t tsc_start, tsc_end;

            clock_gettime(CLOCK_MONOTONIC, &start);
            tsc_start = __rdtsc();
            usleep(10000); /* Sleep for 10ms */
            tsc_end = __rdtsc();
            clock_gettime(CLOCK_MONOTONIC, &end);

            uint64_t elapsed_us = (end.tv_sec - start.tv_sec) * 1000000ULL +
                                (end.tv_nsec - start.tv_nsec) / 1000;
            uint64_t tsc_elapsed = tsc_end - tsc_start;
            mono_ticksPerMicrosecond = tsc_elapsed / elapsed_us;
        }
        /* Rewind file to search for constant_tsc flag */
        rewind(cpuinfo);
        while (fgets(buf, bufflen, cpuinfo) != NULL) {
            if (regexec(&constTscRegex, buf, nmatch, pmatch, 0) == 0) {
                constantTsc = 1;
                break;
            }
        }

        fclose(cpuinfo);
    }

Review comment (suggestion):
LGTM. I wonder if we should run multiple loops and take the minimum to reduce the chance of introducing impact caused by jitter? (eg https://elixir.bootlin.com/linux/v6.17.5/source/arch/x86/kernel/tsc.c#L758) 

Code after:
    int constantTsc = 0;
    int rc;

    /* Determine the number of TSC ticks in a micro-second.  This is
     * a constant value matching the standard speed of the processor.
     * On modern processors, this speed remains constant even though
     * the actual clock speed varies dynamically for each core.  */
    rc = regcomp(&cpuGhzRegex, "^model name\\s+:.*@ ([0-9.]+)GHz", REG_EXTENDED);
    assert(rc == 0);

    /* Also check that the constant_tsc flag is present.  (It should be
     * unless this is a really old CPU.  */
    rc = regcomp(&constTscRegex, "^flags\\s+:.* constant_tsc", REG_EXTENDED);
    assert(rc == 0);

    FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
    if (cpuinfo != NULL) {
        while (fgets(buf, bufflen, cpuinfo) != NULL) {
            if (regexec(&cpuGhzRegex, buf, nmatch, pmatch, 0) == 0) {
                buf[pmatch[1].rm_eo] = '\0';
                double ghz = atof(&buf[pmatch[1].rm_so]);
                mono_ticksPerMicrosecond = (long)(ghz * 1000);
                break;
            }
        }
        /* Some CPUs may not contain clock speed in the model name */
        if (mono_ticksPerMicrosecond == 0) {
            for (int i = 0; i < TSC_CALIBRATION_ITERATIONS; ++i) {
                /* Calibrate TSC against CLOCK_MONOTONIC */
                struct timespec start, end;
                uint64_t tsc_start, tsc_end;

                clock_gettime(CLOCK_MONOTONIC, &start);
                tsc_start = __rdtsc();
                usleep(10000); /* Sleep for 10ms */
                tsc_end = __rdtsc();
                clock_gettime(CLOCK_MONOTONIC, &end);

                uint64_t elapsed_us = (end.tv_sec - start.tv_sec) * 1000000ULL + (end.tv_nsec - start.tv_nsec) / 1000;
                uint64_t tsc_elapsed = tsc_end - tsc_start;
                long sample_ticksPerMicrosecond = tsc_elapsed / elapsed_us;

                /* Use the maximum out of TSC_CALIBRATION_ITERATIONS iterations for accuracy */
                if (sample_ticksPerMicrosecond > mono_ticksPerMicrosecond) {
                    mono_ticksPerMicrosecond = sample_ticksPerMicrosecond;
                }
            }
        }
        /* Rewind file to search for constant_tsc flag */
        rewind(cpuinfo);
        while (fgets(buf, bufflen, cpuinfo) != NULL) {