udata: optimise the udata handling further for bankfixed
authorAlan Cox <alan@linux.intel.com>
Tue, 2 Jun 2015 17:23:18 +0000 (18:23 +0100)
committerAlan Cox <alan@linux.intel.com>
Tue, 2 Jun 2015 17:23:18 +0000 (18:23 +0100)
Take the idle in the thread doing switchout() and make it act simply as a
function call (no udata switch) providing

- We go from just us running to idle
- We are the only process woken

This saves us a lot. It has to be per arch and per banking type but it does
live entirely in switchout() and is invisible to the core so has no affect
on anything it doesn't work with or where it makes no sense.

Also add it for the 6809, although the 6809 changes from nready all still
need debugging first, so its disabled.

Kernel/include/kdata.h
Kernel/kdata.c
Kernel/lib/z80fixedbank.s
Kernel/platform-dragon-nx32/tricks.s

index fdc1b50..b4643ea 100644 (file)
@@ -16,7 +16,7 @@ extern uint16_t maxproc;   /* Actual max number of processes */
 extern uint16_t ramsize;
 extern uint16_t procmem;
 extern uint16_t nproc;    /* Current number of processes */
-extern uint16_t nready;           /* Number of ready processes */
+extern uint8_t nready;    /* Number of ready processes */
 
 extern inoptr root;        /* Address of root dir in inode table */
 extern uint16_t root_dev;  /* Device number of root filesystem. */
index 6f64d57..05b74ff 100644 (file)
@@ -4,7 +4,8 @@
 
 p_tab *init_process;
 unsigned char *cmdline = (unsigned char *) CMDLINE;
-uint16_t ramsize, procmem, maxproc, nproc, nready;
+uint16_t ramsize, procmem, maxproc, nproc;
+uint8_t nready;
 uint16_t runticks;
 bool inint;
 uint16_t root_dev;
index 864f09e..511405a 100644 (file)
@@ -24,6 +24,8 @@
         .globl interrupt_handler
        .globl _swapper
        .globl _need_resched
+       .globl _nready
+       .globl _platform_idle
 
        .globl map_kernel
        .globl map_process
@@ -56,6 +58,33 @@ _switchout:
         push iy
         ld (U_DATA__U_SP), sp ; this is where the SP is restored in _switchin
 
+       ld a, (_nready)
+       or a
+       jr nz, slow_path
+
+idling:
+       ei
+       call _platform_idle
+       di
+       ld a, (_nready)
+       or a
+       jr z, idling
+       cp #1
+       jr nz, slow_path
+       ld hl, (U_DATA__U_PTAB)
+       ld a, (hl)              ; Process table status is first byte
+       ; Are we the one process ?
+       cp #P_READY
+       jr nz, slow_path
+       ; We are - fast path return from switchout
+       ld (hl), #P_RUNNING
+       pop iy
+       pop ix
+       pop hl
+       ei
+       ret
+
+slow_path:
        ; Stash the uarea back into process memory
        call map_process_always
        ld hl, #U_DATA
index 6f41e9d..517a6fb 100644 (file)
@@ -14,6 +14,8 @@
         .globl map_process_a
         .globl map_process_always
         .globl copybank
+       .globl _nready
+       .globl _platform_idle
 
        # exported
         .globl _switchout
@@ -49,6 +51,54 @@ _switchout:
        pshs d,y,u
        sts U_DATA__U_SP        ; this is where the SP is restored in _switchin
 
+       ; See if we are about to go idle
+       lda _nready
+       ; Someone else will run - go the slow path into the scheduler
+;      bne slow_path
+       bra slow_path
+
+       ;
+       ; Wait for something to become ready
+       ;
+idling:
+       andcc #0xef
+       jsr _platform_idle
+       orcc #0x10
+
+       lda _nready
+       beq idling
+
+       ; Did multiple things wake up, if so we must follow the slow
+       ; path
+       cmpa #1
+       bne slow_path
+
+       ; Was the waker us ?
+       ldx U_DATA + U_DATA__U_PTAB
+       lda P_TAB__P_STATUS_OFFSET,x
+       cmpa #P_READY
+       ; No: follow the slow path
+       bne slow_path
+
+       ; We can use the fast path for returning.
+       ;
+       ; Mark ourself running with a new time slice allocation
+       ;
+       lda #P_RUNNING
+       sta P_TAB__P_STATUS_OFFSET,x
+       ldx #0
+       stx _runticks
+       ;
+       ; We idled and got the CPU back - fast path, and we know
+       ; we are not a pre-emption. In effect the switchout() becomes
+       ; a normal function call and we don't have to stash anything or
+       ; bank switch.
+       ;
+       andcc #0xef
+       puls x,y,u,pc
+
+
+slow_path:
        ; Stash the uarea into process memory bank
        jsr map_process_always