Skip to content

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

Description

@toncho11

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:

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: ghaerr/elks#2764

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions