hperaza / RSX280

RSX-11M-like OS for the Z280 CPU.
Other
26 stars 2 forks source link

Kernel option, "idle hack" to play nicely when running under an emulator #2

Closed vandys closed 2 years ago

vandys commented 2 years ago

I'v been looking at the canonical "idle hack" so on emulated z280's the host process can not burn 100% CPU. It looks like at the tail of the dsp[123] sequence in tskmgr.mac, one could di and check again, and if still idle do an ei followed by, dunno, I/O port in to tell the outside emulation to idle the emulator until a new event. This makes it much easier to keep a virtual z280 host up and running 24/7. (This technique is very common in the emulated PDP-11 world.)

agn453 commented 2 years ago

Michal Tomek's z280emu emulator would need some co-ordination with any efforts for idle detection too. As an aside - for CP/M 2 and 3 it might be possible to do some throttling when a console input request is detected (these use polled I/O).

hperaza commented 2 years ago

The following patch throttles down the z280rc emulator to a speed comparable to that of a real Z280RC:

--- z280rc.c.orig       2021-09-18 13:05:00.000000000 +0200
+++ z280rc.c    2021-11-14 22:36:29.743940424 +0100
@@ -394,10 +394,15 @@

        //g_quit = 0;
        while(!g_quit) {
+               struct timeval tm0, tm1, tmd;
+               gettimeofday(&tm0, 0);
                if(instrcnt>=starttrace) VERBOSE=1;
-               cpu_execute_z280(cpu,10000);
+               cpu_execute_z280(cpu,65000);
                //printf("3\n");fflush(stdout);
                io_device_update();
+               gettimeofday(&tm1, 0);
+               timersub(&tm1, &tm0, &tmd);
+               if (tmd.tv_usec < 5000) usleep(5000 - tmd.tv_usec);
                /*if (!(--runtime))
                        g_quit=1;*/
        }

z280rc_patch.zip

Apply the patch as usual:

patch z280rc.c < z280rc.c.diff

On my machine it reduces the CPU usage to about 25..30%. You can play with the '65000' constant above to adjust the emulation speed.

vandys commented 2 years ago

Hi, so my sketch for what the kernel would do (corresponding changes to z280 emulator to follow after a sanity check!) to try and halt rather than hard spin. Let me know what you think? patch_idle.txt

hperaza commented 2 years ago

It may do the job, indeed. I'll try it on the real Z280 as soon as I get home.

hperaza commented 2 years ago

With the patch as it is, the halt condition will be (very likely) never met, as the clock queue will be (very likely) never empty: tasks such as SYSFCP and COT... (which by default are always active) reissue a Mark-Time system call immediately after the previous one expires, keeping the clock queue filled. User-started tasks such as RMD do the same. Therefore, I added a new function to the clkq.mac module that checks whether the item's time at the top of the list has expired or not and changed your patch accordingly. The new idle loop was tested on a Z280RC and confirmed that the halt condition is met, and that there were no problems due to race conditions, etc. The changes have been already uploaded to the repository.

vandys commented 2 years ago

I see! I mis-read that as the queue of clock events which had "fired". I will update & take on the z280emu part to add an (optional) IDLE code path to quiesce the host CPU until the next interrupt event.