#1614·v86

PIT IRQ0 / ELKS guest clock runs at approximately half speed on copy.sh/v86

Author: toncho11Created Jul 23, 2026Updated Sep 13, 2026

Problem

If ELKS tells us that 10 seconds elapsed, about 20 seconds actually elapsed!

Details

So when running ELKS under copy.sh/v86, ELKS gettimeofday() / jiffies appears to advance at approximately half the rate reported by direct PIT timing through ELKS get_ptime().

The same ELKS image and test program behave normally under 86Box.

Environment

  • Emulator: copy.sh/v86 - I use https://copy.sh/v86/
  • Browser: Chrome
  • Host OS: Windows 10
  • Guest: ELKS 9.1
  • Guest timer frequency: 100 Hz
  • PIT conversion used by ELKS: 11932 pticks = 10 ms

Test

The program:

  1. Calls init_ptime().
  2. Records gettimeofday().
  3. Repeatedly calls get_ptime() and accumulates its returned PIT ticks.
  4. Stops when the requested PIT duration has elapsed.
  5. Measures the total duration again with gettimeofday().

Simplified delay loop:

c
remaining = ((unsigned long)ms * 11932UL + 9UL) / 10UL;

(void)get_ptime();

while (remaining != 0) {
    delta = get_ptime();

    if (delta >= remaining)
        break;

    remaining -= delta;
}

Results on copy.sh/v86

requested 121 ms:
  gettimeofday wall =  60 ms
  get_ptime duration = 121.002 ms

requested 345 ms:
  gettimeofday wall = 170 ms
  get_ptime duration = 345.003 ms

requested 546 ms:
  gettimeofday wall = 280 ms
  get_ptime duration = 547.989 ms

requested 1034 ms:
  gettimeofday wall = 520 ms
  get_ptime duration = 1034.004 ms

Control test on 86Box

Using the same guest image and test:

requested 121 ms:
  gettimeofday wall = 120 ms
  get_ptime duration = 121.001 ms

requested 345 ms:
  gettimeofday wall = 350 ms
  get_ptime duration = 345.006 ms

requested 546 ms:
  gettimeofday wall = 510 ms
  get_ptime duration = 546.007 ms

requested 1034 ms:
  gettimeofday wall = 1000 ms
  get_ptime duration = 1034.004 ms

There is normal timer quantization and emulator jitter, but no factor-of-two difference.

Expected result

The PIT-derived duration and the IRQ-driven ELKS system clock should agree, apart from the guest clock's approximately 10 ms resolution and ordinary scheduling jitter.

Actual result

Under copy.sh/v86, the IRQ-driven ELKS clock advances at approximately half the rate of the directly read PIT counter.

Possible area to investigate

Could periodic PIT rollovers be collapsed into a single IRQ0 when the browser or emulator timer callback runs late?

Identified in: https://github.com/ghaerr/elks/issues/2764