[Simh] VAX: CPU Usage and Network Timeout

Tim Riker Tim at Rikers.org
Thu Jun 9 14:19:18 EDT 2005


Note: I copied the list, I assume you left it off by mistake?

Kevin Handy wrote:
> The only select used is in the ethernet code, and not for handling
> emulated devices interrupts.

That's true at present, but the patch I posted a while back adds a
select() call in sim_console.c

Ideally I would recommend merging all the file handles into the select
set. The tcp listen port(s), the current connections, the console, any
disk, tape or other device handles, etc. Then the sleep can be woken up
by any of them. Things like reading from tape won't sleep in practice
for emulated files, but when they are attached to real devices, they
could block for a while the way things are now.

>> 1) watch for frequency of NOP calls. If there are a lot of them, assume
>> that we're in an idle loop, and sleep more. This could be an analog
>> range based on NOP frequency.
>>
> This doesn't work for VMS, RSTS/E, or NetBSD, as they don't use NOP's
> in the idle loops. I suspect few OS's do. They just run tight polling
> loops.
> 
> Some versions of RSTS/E, RT11, RSX had a routine to "rotate" the console
> lights as part of the idle loop.

agreed. I didn't say it would be easy. =/

>> 2) keep track of the program counter inside the emulated system. Perhaps
>> this would be the number of different values that the program counter
>> has hit between each "code burst" or "timer tick". There should be some
>> relationship between duplicate code execution and idleness.
>>
> The best way would be to tell the emulator the location of the idle loop.
> It usually resides at a specific location for most OS's. Then just watch
> for that location.

if known, sure. But watching for PC looping on a small set of
instructions might be able to figure that out by itself.

> To actually do an idle, you need to worry about all the internal delay
> counters for simulated devices (disks mostly), clock interrupts,
> instruction counters, etc. Whatever you do should not make the OS
> running on the emulated device unhappy.
> 
> You should try to estimate when the next interrupt should occur
> (from a device, clock, etc), and try to idle for the amount of time
> that interrupt should wait, then adjust all the counters by that
> amount of time.
> 
> You should also let it run a couple of times through the loop before
> taking any idleing action, in case there is something available to be
> polled first.

Agreed. These are all things that need to be considered.

> It would be nice to have this option, but it would be hard to make it
> work for all OS's/CPU's.
> 
> ...
> 
> So, as I see it, you need to have a function for all emulated devices
> to ask it how long until the next interrupt is due (with some huge
> value if none is due, or change code to deal with 0's), and another
> function to adjust the delay counters.
> 
> rough pseudo-code. Probably very wrong, but you get the idea.
> 
>    // Once we hit the delay loop
>    if (virtualpc == delay_location)
>    {
>        // determine how long until next interrupt
>        // with a maximum limit set so user typing isn't delayed too long
>       minwait = maximum_wait_time;
>       for (...loop through all devices...)
>       {
>          minwait = min(minwait, device_wait(...));
>       }
>        // Microsleep is only an approximate sleep, so we use an approximate
>        // time to determine how long to sleep. Hopefully it averages out.
>       microsleep = (minwait + instructions_per_usec/2) /
> instructions_per_usec;
>        // don't bother sleeping if too little time remaining
>       if (microsleep)
>       {
>          // Should this use nanosleep instead?
>          usleep(microsleep);
>          for (...loop through all devices...)
>          {
>             device_adjust_timer(..., minwait);
>          }
>       }
>    }

All more or less what I had in mind except I would not use usleep(). I
would select() all active input and output handles including devices,
console, and net connects in the loop. If there are bytes in any of the
queues, we should run the virtual machine at full speed till it
addresses them.

If soemthing like a paper tape drive is configured to emulate real time,
and is in process of loading a tape, then it would update its minwait to
the next time it thinks it should supply data. If it is running full
speed then it would add it's handle to the select() set. This way if the
handle is actually a real device, then the select() will throttle to
actual response times.
-- 
Tim Riker - http://Rikers.org/ - TimR at Debian.org
Embedded Linux Technologist - http://eLinux.org/
BZFlag maintainer - http://BZFlag.org/ - for fun!



More information about the Simh mailing list