Date: Mon, 3 Aug 92 01:44:41 -0500 From: rcharif AT math DOT utexas DOT edu Posted-Date: Mon, 3 Aug 92 01:44:41 -0500 To: dj AT ctron DOT com Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Paging enhancement for go32 v1.07 Reply-To: rcharif AT math DOT utexas DOT edu Hi, I made a slight modification to the paging procedure in Go32 v1.07. I have remarked that go32 swapps to the paging file each time there is need for memory. If the page hasn't been written to, there is no need to page it out. It can simply be discarded and a disk access avoided. When the page is needed again it will brought from the executable file as if it is the first access. The limitation is that executing files from a floppy disk or a slow network will prove to be slower, but if the executable is on a local disk there is a performance improvement. In the modification I discard both code and data pages. Code pages are discarded if they belong to the executable file without any checking. Data pages are discarded if they have never been written to. (See the file paging.c for details). Another modification is that the paging routine will not page out the pages surrounding the current instruction pointer +-4 pages. The old routine, used to page out blindly and sometimes paged out the currently executed instruction. This resulted in unneeded and slow trafic. When I gathered statistics, I saw this happening with gcc most of the time. I included another modification to permit selective debugging in go32. (See build.h). The flags denoting the sections to be debugged can be given on the command line like the following : go32 -debug all program_name <-- to debug all go32 -debug program_name <-- To debug certain mask or in the GO32 environment variable with the following : set go32= debug all .... or set go32= debug .... The command line debug mask has priority over the one given in the go32 environment variable. The following masks (along their values) are used for now : DEBUG_POUT 1 view page out trafic DEBUG_PIN 2 view page in trafic DEBUG_POUT_DATA_DIRTY 4 view data pages flagging as dirty DEBUG_POUT_DISCARD 8 view discarding pages DEBUG_SKIP_EIP 16 view skipping current eip debug_mask_value is formed by adding the wanted mask's numerical value. An interesting value is 25. This permits to view the page out algoritm and compare the ratio page out / discard. I put a complete version of the modification on : math.utexas.edu:/pub/msdos/Go32Modif/paging user ftp login anonymous The following files are available : ModifDiff.zip : a diff -c3 of the modified files. Use patch to apply the modifications Go32Modified.zip : A complete version source + executable ModifiedFiles.zip : Source code of the modified source files I tried this modification with a relatively big program (5.6 Megabytes) and I found a significant improvement. I will be interested in your comments especially comparison with the basic go32. I hope that DJ will be able to insert this modification in future versions of go32. Regards, Rami El Charif Here is the diff file for the modification -------------------------------- --------------------- Cut Here --------------------------------------- diff -c3 d:\local\go32\org/build.h d:\local\go32\mod/build.h *** d:\local\go32\org/build.h Sun Aug 2 23:25:26 1992 --- d:\local\go32\mod/build.h Sun Aug 2 20:42:40 1992 *************** *** 13,15 **** --- 13,30 ---- */ /* moved to makefile */ + + #ifdef DEBUG_ON + + static char *_pFileName = __FILE__; + + extern unsigned long fDebug; + #define DEBUG(n) if (fDebug & n) + + #define DEBUG_POUT 1 + #define DEBUG_PIN 2 + #define DEBUG_POUT_DATA_DIRTY 4 + #define DEBUG_POUT_DISCARD 8 + #define DEBUG_SKIP_EIP 16 + + #endif diff -c3 d:\local\go32\org/control.c d:\local\go32\mod/control.c *** d:\local\go32\org/control.c Tue Jul 7 17:29:14 1992 --- d:\local\go32\mod/control.c Sun Aug 2 23:16:38 1992 *************** *** 38,43 **** --- 38,47 ---- extern transfer_buffer[]; extern word32 transfer_linear; + #ifdef DEBUG + unsigned long fDebug = 0; // Debug messages mask, see build.h + #endif + TSS *tss_ptr; int debug_mode = 0; int self_contained; *************** *** 186,192 **** --- 190,200 ---- usage(char *s) { + #ifdef DEBUG + printf("Usage: %s [-debug ] [program [options . . . ]]\n", s); + #else printf("Usage: %s [program [options . . . ]]\n", s); + #endif _exit(1); } *************** *** 350,355 **** --- 358,373 ---- if (emu_fn) free(emu_fn); emu_fn = strdup(val); } + else if (stricmp(sw, "debug") == 0) { + + if (!strcmpi(val, "all")) + fDebug = 0xffffffffL; + else + sscanf(val, "%li", (unsigned long *)&fDebug); + + printf("\nMessage Debugging enabled in go32 environment variable. Flag value = %lx\n" + , fDebug); + } } #if ! DEBUGGER #if ! TOPLINEINFO *************** *** 447,452 **** --- 465,485 ---- argc--; } + #ifdef DEBUG + // set debug flags. syntaxe go32 [-debug ] pgm_name + if (!strncmpi(argv[1], "-debug", 6)) { + + if (!strcmpi(argv[2], "all")) + fDebug = 0xffffffffL; + else + sscanf(argv[2], "%li", (unsigned long *)&fDebug); + + argv += 2; + argc -= 2; + printf("\nMessage Debugging enabled. Flag value = %lx\n", fDebug); + } + #endif + #if TOPLINEINFO for (i=0; i<80; i++) poke(screen_seg, i*2, 0x0720); *************** *** 490,496 **** *path = 0; if (stat(argv0, &stbuf)) /* not found */ { ! fprintf(stderr, "%s.exe version 1.07 Copyright (C) 1991 DJ Delorie\n", argv0); debug_mode = 1; if (argv[1] == 0) --- 523,529 ---- *path = 0; if (stat(argv0, &stbuf)) /* not found */ { ! fprintf(stderr, "%s.exe version 1.07 Copyright (C) 1991 DJ Delorie\n\r", argv0); debug_mode = 1; if (argv[1] == 0) diff -c3 d:\local\go32\org/makefile d:\local\go32\mod/makefile *** d:\local\go32\org/makefile Sat Aug 1 19:58:24 1992 --- d:\local\go32\mod/makefile Sun Aug 2 18:22:34 1992 *************** *** 1,16 **** # History:25,17 AFLAGS = /mx /zi /zd ! CFLAGS = -ms -M .c.obj: ! tcc $(CFLAGS) -DDEBUGGER=1 -DTOPLINEINFO=1 -DSOURCE_LIST -c $* ! -mv $*.obj d$*.obj ! tcc $(CFLAGS) -DDEBUGGER=0 -DTOPLINEINFO=1 -c $* .asm.obj: ! tasm $(AFLAGS) /DDEBUGGER=1 /DTOPLINEINFO=1 $*; ! mv $*.obj d$*.obj tasm $(AFLAGS) /DDEBUGGER=0 /DTOPLINEINFO=1 $*; OBJS =\ --- 1,16 ---- # History:25,17 AFLAGS = /mx /zi /zd ! CFLAGS = -ms -M -DVERBOSE=0 -DDEBUG_ON .c.obj: ! # bcc $(CFLAGS) -DDEBUGGER=1 -DTOPLINEINFO=1 -DSOURCE_LIST -c $*.c ! # -mv $*.obj d$*.obj ! bcc $(CFLAGS) -DDEBUGGER=0 -DTOPLINEINFO=1 -c $*.c .asm.obj: ! # tasm $(AFLAGS) /DDEBUGGER=1 /DTOPLINEINFO=1 $*; ! # -mv $*.obj d$*.obj tasm $(AFLAGS) /DDEBUGGER=0 /DTOPLINEINFO=1 $*; OBJS =\ *************** *** 37,43 **** xms.obj\ vcpi.obj ! all : go32t.exe stub.exe aout2exe.exe exe2aout.exe stub.exe: stub.c tcc stub.c --- 37,44 ---- xms.obj\ vcpi.obj ! all : go32.exe ! # stub.exe aout2exe.exe exe2aout.exe stub.exe: stub.c tcc stub.c *************** *** 44,52 **** tdstrip stub # Note: some tlinks require /3 here, some barf if you supply it. ! go32t.exe : $(OBJS) go32.lnk tlink /3 /l /c /v /s /m @go32.lnk ! tlink /3 /l /c /v /s /m @debug32.lnk bin2byte.exe : bin2byte.c tcc bin2byte.c --- 45,53 ---- tdstrip stub # Note: some tlinks require /3 here, some barf if you supply it. ! go32.exe : $(OBJS) go32.lnk tlink /3 /l /c /v /s /m @go32.lnk ! # tlink /3 /l /c /v /s /m @debug32.lnk bin2byte.exe : bin2byte.c tcc bin2byte.c *************** *** 65,91 **** # DEPENDENCIES ! debug.obj : build.h types.h gdt.h tss.h utils.h unassmbl.h syms.h paging.h npx.h mono.h eventque.h ! exphdlr.obj : build.h types.h gdt.h idt.h tss.h utils.h paging.h npx.h mono.h vcpi.h eventque.h ! control.obj : build.h types.h gdt.h idt.h tss.h valloc.h utils.h syms.h graphics.h mono.h vcpi.h ! graphics.obj : build.h types.h paging.h graphics.h tss.h gdt.h driver.h ! paging.obj : build.h types.h paging.h graphics.h tss.h idt.h gdt.h valloc.h dalloc.h utils.h aout.h mono.h vcpi.h ! syms.obj : build.h types.h syms.h tss.h stab.h stab.def aout.h utils.h ! unassmbl.obj : build.h types.h gdt.h idt.h tss.h utils.h unassmbl.h syms.h mono.h ! utils.obj : build.h types.h tss.h gdt.h utils.h npx.h ! valloc.obj : build.h types.h valloc.h xms.h mono.h vcpi.h xms.obj : xms.h ! dalloc.obj : build.h types.h valloc.h dalloc.h mono.h mono.obj : mono.h --- 66,92 ---- # DEPENDENCIES ! debug.obj : types.h gdt.h tss.h utils.h unassmbl.h syms.h paging.h npx.h mono.h eventque.h ! exphdlr.obj : types.h gdt.h idt.h tss.h utils.h paging.h npx.h mono.h vcpi.h eventque.h ! control.obj : types.h gdt.h idt.h tss.h valloc.h utils.h syms.h graphics.h mono.h vcpi.h ! graphics.obj : types.h paging.h graphics.h tss.h gdt.h driver.h ! paging.obj : types.h paging.h graphics.h tss.h idt.h gdt.h valloc.h dalloc.h utils.h aout.h mono.h vcpi.h ! syms.obj : types.h syms.h tss.h stab.h stab.def aout.h utils.h ! unassmbl.obj : types.h gdt.h idt.h tss.h utils.h unassmbl.h syms.h mono.h ! utils.obj : types.h tss.h gdt.h utils.h npx.h ! valloc.obj : types.h valloc.h xms.h mono.h vcpi.h xms.obj : xms.h ! dalloc.obj : types.h valloc.h dalloc.h mono.h mono.obj : mono.h diff -c3 d:\local\go32\org/paging.c d:\local\go32\mod/paging.c *** d:\local\go32\org/paging.c Tue Jul 7 17:29:16 1992 --- d:\local\go32\mod/paging.c Sun Aug 2 20:48:14 1992 *************** *** 34,40 **** #include "mono.h" #include "vcpi.h" ! #define VERBOSE 0 #if DEBUGGER --- 34,40 ---- #include "mono.h" #include "vcpi.h" ! //#define VERBOSE 0 #if DEBUGGER *************** *** 556,561 **** --- 556,578 ---- dread(paging_buffer, dblock); dfree(dblock); memput(vaddr, paging_buffer, 4096); + pt[pti] &= ~(word32)(PT_A | PT_D); // clean dirty an accessed bits (set by memput) + #ifdef DEBUG + DEBUG(DEBUG_POUT) { + + printf("\nPaging In %lx, flags = ", vaddr); + + printf("%c", (pt[pti] & PT_C) ? 'C' : ' '); + printf("%c", (pt[pti] & PT_S) ? 'S' : ' '); + printf("%c", (pt[pti] & PT_I) ? 'I' : ' '); + printf("%c", (pt[pti] & PT_D) ? 'D' : ' '); + printf("%c", (pt[pti] & PT_A) ? 'A' : ' '); + printf("%c", (pt[pti] & PT_U) ? 'U' : ' '); + printf("%c", (pt[pti] & PT_W) ? 'W' : ' '); + printf("%c", (pt[pti] & PT_P) ? 'P' : ' '); + printf("---"); + } + #endif } else { *************** *** 603,608 **** --- 620,642 ---- if (zaddr != -1) zero32(zaddr); memput(vtran, paging_buffer, vcnt); + pt[pti] &= ~(word32)(PT_A | PT_D); // clean dirty and accessed bits (set by memput) + #ifdef DEBUG + DEBUG(DEBUG_PIN) { + + printf("\nReading %lx, flags = ", vtran); + + printf("%c", (pt[pti] & PT_C) ? 'C' : ' '); + printf("%c", (pt[pti] & PT_S) ? 'S' : ' '); + printf("%c", (pt[pti] & PT_I) ? 'I' : ' '); + printf("%c", (pt[pti] & PT_D) ? 'D' : ' '); + printf("%c", (pt[pti] & PT_A) ? 'A' : ' '); + printf("%c", (pt[pti] & PT_U) ? 'U' : ' '); + printf("%c", (pt[pti] & PT_W) ? 'W' : ' '); + printf("%c", (pt[pti] & PT_P) ? 'P' : ' '); + printf("---"); + } + #endif } #if VERBOSE printf("\n"); *************** *** 631,686 **** if (where == VA_640) { for (pti = last_pti+1; pti != last_pti; pti = (pti+1)%1024) ! if ((vcpi_pt[pti] & (PT_P | PT_S)) == (PT_P | PT_S)) ! { ! dblock = dalloc(); ! memcpy(paging_buffer, (void far *)(pti << 24), 4096); ! dwrite(paging_buffer, dblock); ! #if VERBOSE ! printf ("out_640 %d\n", pti); #endif - vcpi_pt[pti] &= 0xfff & ~PT_P; /* no longer present */ - vcpi_pt[pti] |= (long)dblock << 12; #if TOPLINEINFO ! update_status(old_status, 79); #endif ! last_pti = pti; ! return pti; ! } return -1; } pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! do { ! if ((pd[last_po_pdi] & (PT_P | PT_S)) == (PT_P | PT_S)) ! { ! if ((pt[last_po_pti] & (PT_P | PT_S)) == (PT_P | PT_S)) ! { ! rv = pt[last_po_pti] >> 12; ! dblock = dalloc(); ! v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! memget(v, paging_buffer, 4096); ! dwrite(paging_buffer, dblock); #if VERBOSE ! printf ("out %d:%d\r", last_po_pdi, last_po_pti); #endif ! pt[last_po_pti] &= 0xfff & ~PT_P; /* no longer present */ ! pt[last_po_pti] |= (long)dblock << 12; #if TOPLINEINFO ! update_status(old_status, 79); #endif ! return rv; ! } ! } ! else /* imagine we just checked the last entry */ ! last_po_pti = 1023; ! if (++last_po_pti == 1024) ! { ! last_po_pti = 0; ! if (++last_po_pdi == 1024) ! last_po_pdi = 0; ! pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! } ! } while ((start_pdi != last_po_pdi) || (start_pti != last_po_pti)); #if TOPLINEINFO update_status(old_status, 79); #endif --- 665,905 ---- if (where == VA_640) { for (pti = last_pti+1; pti != last_pti; pti = (pti+1)%1024) ! if ((vcpi_pt[pti] & (PT_P | PT_S)) == (PT_P | PT_S)) { ! ! dblock = dalloc(); ! memcpy(paging_buffer, (void far *)(pti << 24), 4096); ! dwrite(paging_buffer, dblock); ! vcpi_pt[pti] &= 0xfff & ~PT_P; /* no longer present */ ! vcpi_pt[pti] |= (long)dblock << 12; ! ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "POut640"; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0600); ! } ! #endif ! #ifdef DEBUG ! DEBUG(DEBUG_POUT) { ! printf("\nPaging out 640 %lx, flags = ", ((word32)pti << 12)); ! ! printf("%c", (vcpi_pt[pti] & PT_C) ? 'C' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_S) ? 'S' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_I) ? 'I' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_D) ? 'D' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_A) ? 'A' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_U) ? 'U' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_W) ? 'W' : ' '); ! printf("%c", (vcpi_pt[pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } #endif #if TOPLINEINFO ! update_status(old_status, 79); #endif ! last_pti = pti; ! return pti; ! } return -1; } pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! ! ! do { ! if ((pd[last_po_pdi] & (PT_P | PT_S)) == (PT_P | PT_S)) { ! ! // ! // Don't page out around current instruction. ! // Take a limit of +-4 pages ! // ! v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! if ((v >= a_tss.tss_eip-0x4000) && (v <= a_tss.tss_eip+0x4000)) { ! ! #ifdef DEBUG ! DEBUG(DEBUG_SKIP_EIP) ! printf("\n++++++++++++++++ Skipping eip, addr = %lx, eip = %lx" ! , v, a_tss.tss_eip ! ); ! #endif ! last_po_pti += 6; ! if (last_po_pti >= 1024) { ! ! last_po_pti %= 1024; ! if (++last_po_pdi == 1024) ! last_po_pdi = 0; ! pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! } ! } ! ! if ((pt[last_po_pti] & (PT_P | PT_S)) == (PT_P | PT_S)) { ! ! // v = ((word32)last_po_pdi << 22) | ((word32)last_po_pti << 12); ! ! //--------------------- TEXT ----------------------------- ! // Text is read only, so discard page ! // ! if ((v >= areas[A_text].first_addr) && ! (v <= areas[A_text].last_addr) ) { ! ! rv = pt[last_po_pti] >> 12; ! pt[last_po_pti] &= 0xfff & ~(PT_A | PT_D | PT_P | PT_I); ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DISCARD) { ! printf("\nDiscarding Text %lx, flags = ", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } ! #endif ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "Discard"; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0400); ! } ! #endif ! } ! // ! //--------------------- DATA ----------------------------- ! // Candidate is a data page that is NOT a split page data / bss ! // ! else if ((v >= areas[A_data].first_addr) && ! (v <= areas[A_data].last_addr) && ! ((v & 0xfffff000L) != (areas[A_bss].first_addr & 0xfffff000L)) ! ) { ! // ! // Selected page was modified before. Can't be discarded ! // ! if (pt[last_po_pti] & PT_PageOnceDirty) { ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DATA_DIRTY) ! printf("\n------- Encountered Data page DIRTY %lx", v); ! #endif ! goto PageItOut; // I can't believe I am using goto ! } ! // ! // Selected page was just modified. Can't be discarded ! // ! else if (pt[last_po_pti] & PT_D) { ! pt[last_po_pti] |= PT_PageOnceDirty; ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DATA_DIRTY) { ! printf("\n---------------- Marking Data page Once DIRTY %lx, flags =", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } ! #endif ! goto PageItOut; ! } ! // ! // Page was never written to. Discard it ! // ! else { ! ! rv = pt[last_po_pti] >> 12; ! pt[last_po_pti] &= 0xfff & ~(PT_A | PT_D | PT_P | PT_I | PT_PageOnceDirty); ! ! #ifdef DEBUG ! DEBUG(DEBUG_POUT_DISCARD) { ! printf("\nDiscarding Data %lx, flags = ", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("+++++++++++++++ "); ! } ! #endif ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "Dsc Dta"; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0400); ! } ! #endif ! } ! } ! // ! // Page out to swap file ! // ! else { ! ! PageItOut: ! rv = pt[last_po_pti] >> 12; ! dblock = dalloc(); ! memget(v, paging_buffer, 4096); ! dwrite(paging_buffer, dblock); ! pt[last_po_pti] &= 0xfff & ~(PT_A | PT_D | PT_P); /* no longer present */ ! pt[last_po_pti] |= (long)dblock << 12; ! ! #ifdef DEBUG ! DEBUG(DEBUG_POUT) { ! printf("\nPaging out %lx, flags = ", v); ! ! printf("%c", (pt[last_po_pti] & PT_C) ? 'C' : ' '); ! printf("%c", (pt[last_po_pti] & PT_S) ? 'S' : ' '); ! printf("%c", (pt[last_po_pti] & PT_I) ? 'I' : ' '); ! printf("%c", (pt[last_po_pti] & PT_D) ? 'D' : ' '); ! printf("%c", (pt[last_po_pti] & PT_A) ? 'A' : ' '); ! printf("%c", (pt[last_po_pti] & PT_U) ? 'U' : ' '); ! printf("%c", (pt[last_po_pti] & PT_W) ? 'W' : ' '); ! printf("%c", (pt[last_po_pti] & PT_P) ? 'P' : ' '); ! printf("---"); ! } ! #endif ! #if TOPLINEINFO ! { ! register int i; ! char *pStr = "POut "; ! for (i=0; pStr[i]; i++) ! poke(screen_seg, i*2+50, pStr[i] | 0x0600); ! } ! #endif #if VERBOSE ! printf ("out %d:%d\r", last_po_pdi, last_po_pti); #endif ! } #if TOPLINEINFO ! update_status(old_status, 79); #endif ! return rv; ! } ! } ! else /* imagine we just checked the last entry */ ! last_po_pti = 1023; ! ! if (++last_po_pti == 1024) { ! last_po_pti = 0; ! if (++last_po_pdi == 1024) ! last_po_pdi = 0; ! pt = (word32 far *)((word32)(pd_seg[last_po_pdi]) << 24); ! } ! } while ((start_pdi != last_po_pdi) || (start_pti != last_po_pti)); ! #if TOPLINEINFO update_status(old_status, 79); #endif *************** *** 698,703 **** --- 917,928 ---- unsigned pn; unsigned ptb; void far *fp; + + #ifdef DEBUG + DEBUG(DEBUG_POUT) + printf("\nPage Out everything -------------------"); + #endif + while ((pn=page_out(-1)) != 0xffff) { vfree(); *************** *** 732,737 **** --- 957,969 ---- unsigned ptb; word32 far *pt; unsigned pta; + + + #ifdef DEBUG + DEBUG(DEBUG_PIN) + printf("\nPage In everything -------------------"); + #endif + valloc_initted = 0; pta = valloc(VA_640); pd = (word32 far *)((word32)pta << 24); diff -c3 d:\local\go32\org/paging.h d:\local\go32\mod/paging.h *** d:\local\go32\org/paging.h Tue Jul 7 17:29:20 1992 --- d:\local\go32\mod/paging.h Sun Aug 2 18:20:54 1992 *************** *** 25,30 **** --- 25,32 ---- #define PT_S 0x400 /* Swappable (else not) */ #define PT_C 0x800 /* Candidate for swapping */ + #define PT_PageOnceDirty PT_C // Page was modified by user at least once + #define EMU_TEXT 0xb0000000 /* If not present and initialized, page is in swap file. ---- END CUT HERE -----------------------------------------------------