[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: some more 110h4 clues...



ok i'm back...  some mails i sent got lost but before i resend anything
i have some new diffs.  (please post answers, or use the Reply-To: for now.)

Torsten Scherer writes:

>  To further specify my last comment:

 thanx!  i'm sorry for all the trouble, i still have no '030 to test MMU
stuff myself... :/  i hope i this is better.

1. exec vs. memoryprotection, use parents MMU context in fork_restore;
look for links to the same region in fork and when calculatig process
size and also don't count sleeping fork parents memory twice...

Index: dosmem.c
@@ -474,6 +478,7 @@
 		char cbuf[128], *tail = ptr2;
 		if (overlay) {
 			static char fbuf[PATH_MAX];
+			cbuf[127] = 0;
 			ptr1 = strncpy (fbuf, ptr1, PATH_MAX-2);
 			tail = strncpy (cbuf, ptr2, 127);
 		}
@@ -1331,7 +1336,8 @@
 		savemem->mflags |= M_FSAVED;
 		for (i = 0; i < curproc->num_reg; i++) {
 			m = curproc->mem[i];
-			if (m && !(m->mflags & (M_FSAVED|M_SHTEXT))) {
+			if (m && !(m->mflags & (M_SEEN|M_FSAVED|M_SHTEXT))) {
+				m->mflags |= M_SEEN; /* save links only once */
 				if (i != 1 || txtsize == 0) {
 				    quickmove(saveplace, (char *)m->loc, m->len);
 				    saveplace += m->len;
@@ -1343,6 +1349,10 @@
 				}
 			}
 		}
+		for (i = 0; i < curproc->num_reg; i++) {
+			if (curproc->mem[i])
+				curproc->mem[i]->mflags &= ~M_SEEN;
+		}
 	}
 				
 	p->ctxt[CURRENT] = p->ctxt[SYSCALL];
@@ -1399,6 +1409,7 @@
 	long txtsize = p->txtsize;
 	char *saveplace;
 	int i;
+	extern int no_mem_prot;
 
 	if (!savemem) {
 		for (i = 0; i < p->num_reg; i++) {
@@ -1414,9 +1425,15 @@
 	saveplace = (char *)savemem->loc;
 
 	TRACE(("do_vfork: parent restoring memory"));
+#if 1
+	if (p != curproc && !no_mem_prot)
+/* memprot doesn't like it?  try p's mmu context... */
+		set_mmu (p->ctxt[CURRENT].crp, p->ctxt[CURRENT].tc);
+#endif
 	for (i = 0; i < p->num_reg; i++) {
 		m = p->mem[i];
-		if (m && !(m->mflags & (M_FSAVED|M_SHTEXT))) {
+		if (m && !(m->mflags & (M_SEEN|M_FSAVED|M_SHTEXT))) {
+			m->mflags |= M_SEEN;
 			if (i != 1 || txtsize == 0) {
 			    quickmove((char *)m->loc, saveplace, m->len);
 			    saveplace += m->len;
@@ -1428,6 +1445,14 @@
 			}
 		}
 	}
+	for (i = 0; i < p->num_reg; i++) {
+		if (p->mem[i])
+			p->mem[i]->mflags &= ~M_SEEN;
+	}
+#if 1
+	if (p != curproc && !no_mem_prot)
+		set_mmu (curproc->ctxt[CURRENT].crp, curproc->ctxt[CURRENT].tc);
+#endif
 	detach_region(p, savemem);
 }
 
Index: mem.c
@@ -407,6 +407,8 @@
 	rfreelist = m;
 }
 
+#if 0
+/*notused*/
 /*
  * change_prot_status: change the status of a region to 'newmode'.  We're
  * given its starting address, not its region structure pointer, so we have
@@ -438,6 +440,7 @@
     mark_region(*mr,newmode);
     return E_OK;
 }
+#endif
 
 /*
  * virtaddr
@@ -602,7 +605,9 @@
  * text regions.
  */
 	nfirstp = NULL;
+#if 0
 retry:
+#endif
 	n = *map;
 retry2:
 	s = nlast = NULL;
@@ -1247,14 +1257,16 @@
 		for (i = 0; i < execproc->num_reg; i++) {
 			m = execproc->mem[i];
 			if (m && m->links == 0xfffe) {
+				execproc->mem[i] = 0;
+				execproc->addr[i] = 0;
 				if (m->mflags & M_SHTEXT_T) {
+					TRACE (("create_base: keeping sticky text segment (%lx, len %lx)",
+						m->loc, m->len));
 					m->links = 0xffff;
 				} else {
 					m->links = 0;
 					free_region(m);
 				}
-				execproc->mem[i] = 0;
-				execproc->addr[i] = 0;
 			}
 		}
 	}
@@ -1281,7 +1293,7 @@
 			if (!s->text) {
 				s->text = m;
 				if (protmode != PROT_P)
-					change_prot_status (curproc, m->loc, PROT_P);
+					mark_region(m, PROT_P);
 				m = 0;
 			}
 		}
@@ -1778,8 +1790,23 @@
 			m = p->mem[i];
 			if (m) {
 				m->links--;
+#if 1
+				if (m->links <= 0) {
+					if (!m->links) {
+						if (m->mflags & M_SHTEXT_T) {
+							TRACE (("exec_region: keeping sticky text segment (%lx, len %lx)",
+								m->loc, m->len));
+							m->links = 0xffff;
+						} else
+							free_region(m);
+					} else
+						ALERT ("exec_region: region %lx bogus link count %d, not freed (len %lx)",
+							m->loc, m->links, m->len);
+				}
+#else
 				if (m->links <= 0)
 					free_region(m);
+#endif
 			}
 		}
 		if (p->num_reg > NUM_REGIONS) {
@@ -1899,8 +1926,16 @@
 
 	size = 0;
 	for (i = 0; i < p->num_reg; i++) {
-		if (p->mem[i])
+		if (p->mem[i]) {
+			if (p->mem[i]->mflags & (M_SEEN|M_FSAVED))
+				continue;	/* count links only once */
+			p->mem[i]->mflags |= M_SEEN;
 			size += p->mem[i]->len;
+		}
+	}
+	for (i = 0; i < p->num_reg; i++) {
+		if (p->mem[i])
+			p->mem[i]->mflags &= ~M_SEEN;
 	}
 	return size;
 }
@@ -2016,8 +2051,8 @@
 	FORCE("%s memory dump: starting at region %lx",
 		(map == ker ? "ker" : (map == core ? "core" : "alt")), m);
 	while (m) {
-	    FORCE("%ld bytes at %lx (%d links); next region %lx", m->len, m->loc,
-		    m->links, m->next);
+	    FORCE("%ld bytes at %lx (%d links, mflags %x); next %lx", m->len, m->loc,
+		    m->links, m->mflags, m->next);
 	    m = m->next;
 	}
 #else
Index: mem.h
@@ -28,6 +28,7 @@
 #define M_SHTEXT_T	0x20	/* `sticky bit' for shared text regions */
 #define M_FSAVED	0x40	/* region is saved memory of a forked process */
 #define M_KEEP		0x0100	/* don't free on process termination */
+#define M_SEEN		0x8000	/* for memused() to find links */
 
 /* dummy type for virtual addresses */
 typedef struct vaddr {

2. GEM/toswin memleaks:  only link M_KEEP regions to rootproc when its
the last link, then Mfree still works after a fork.  this was the only
real leak, the rootproc growing and growing mostly was a result of the
process size caculation...

Index: dosmem.c
@@ -849,7 +854,7 @@
 			curproc->mem[i] = 0; curproc->addr[i] = 0;
 			if (m) {
 		/* don't free specially allocated memory */
-				if (m->mflags & M_KEEP) {
+				if (m->mflags & M_KEEP && m->links <= 1) {
 					if (curproc != rootproc)
 					    attach_region(rootproc, m);
 				}

3. pipe FIONREAD: delay writer-died error condition until pipe is empty.
(can this cause problems?  i think not, and it helps for example toswin,
processes last words no longer appear 1-char-at-a-time...)

Index: pipefs.c
@@ -767,14 +767,18 @@
 	case FIONREAD:
 			p = (f->flags & O_HEAD) ? this->outp : this->inp;
 			assert(p != 0);
-			if (p->writers <= 0 || p->writers == VIRGIN_PIPE) {
-				DEBUG(("pipe FIONREAD: no writers"));
+			if (p->writers == VIRGIN_PIPE) {
+				DEBUG(("pipe FIONREAD: no writers yet"));
 				r = -1;
 			} else {
 				r = p->tail - p->head;
 				if (r < 0) r += PIPESIZ;
 				if (is_terminal(f))
 					r = r >> 2;	/* r /= 4 */
+				if (!r && p->writers <= 0) {
+					DEBUG(("pipe FIONREAD: no writers"));
+					r = -1;
+				}
 			}
 			*((long *) buf) = r;
 			break;

4. sleep: shouldn't we keep the ipl-too-high checks?  it can still happen
outside selects...

Index: proc.c
@@ -9,7 +9,7 @@
 #include "mint.h"
 #include "xbra.h"
 
-static void do_wakeup_things P_((void));
+static void do_wakeup_things P_((short sr));
 
 extern short proc_clock;
 
@@ -419,7 +419,8 @@
  */
 
 static void
-do_wakeup_things()
+do_wakeup_things(sr)
+short sr;
 {
 /*
  * check for stack underflow, just in case
@@ -429,31 +430,35 @@
 
 	p = curproc;
 
-	if ( p->pid != 0 &&
-	     ((long)&foo) < (long)p->stack + ISTKSIZE + 512 ) {
-		ALERT("stack underflow");
-		handle_sig(SIGBUS);
-	}
+	if ((sr & 0x700) < 0x500) {
+/* skip all this if int level is too high */
 
+		if ( p->pid != 0 &&
+		     ((long)&foo) < (long)p->stack + ISTKSIZE + 512 ) {
+			ALERT("stack underflow");
+			handle_sig(SIGBUS);
+		}
+
 /* see if process' time limit has been exceeded */
 
-	if (p->maxcpu) {
-		if (p->maxcpu <= p->systime + p->usrtime) {
-			DEBUG(("cpu limit exceeded"));
-			raise(SIGXCPU);
+		if (p->maxcpu) {
+			if (p->maxcpu <= p->systime + p->usrtime) {
+				DEBUG(("cpu limit exceeded"));
+				raise(SIGXCPU);
+			}
 		}
-	}
 
 /*
  * check for alarms and similar time out stuff (see timeout.c)
  */
 
-	checkalarms();
-	if (p->sigpending)
-		check_sigs();		/* check for signals */
+		checkalarms();
+		if (p->sigpending)
+			check_sigs();		/* check for signals */
+	}
 
 	if (p->slices >= 0) {
-	proc_clock = TIME_SLICE;	/* get a fresh time slice */
+		proc_clock = TIME_SLICE;	/* get a fresh time slice */
 	} else {
 		proc_clock = -p->slices;	/* slices set by run_next */
 		p->curpri = p->pri;
@@ -507,7 +512,7 @@
 	    (que == READY_Q && !sys_q[READY_Q])) {
 /* we're just going to wake up again right away! */
 		spl(sr);
-		do_wakeup_things();
+		do_wakeup_things(sr);
 		return (onsigs != curproc->nsigs);
 	}
 
@@ -573,7 +578,7 @@
 #endif
 			*((void **)0x44eL) = curproc->logbase;
 #endif
-		do_wakeup_things();
+		do_wakeup_things(sr);
 		return (onsigs != curproc->nsigs);
 	}
 /*

5. some lost tabs, etc. :)

Index: biosfs.c
@@ -1388,7 +1388,7 @@
 			}
 		}
 		return 0;
-	}
+	    }
 	case TIOCOUTQ:
 	    {
 		int oldmap;
@@ -1412,7 +1412,7 @@
  		else
 			*r = 0;
 		return 0;
-	}
+	    }
 	case TIOCGWINSZ:
 		if (f->fc.aux != 2)
 		  return EINVFN;
Index: dosmem.c
@@ -1176,7 +1181,7 @@
 			TRACE(("Pwaitpid(ptracer): returning status to tracing process"));
 			p->ptracer = NULL;
 			if (p->ppid != -1)
-			return r;
+				return r;
 		}
 		else {
 		/* Hmmm, the real parent got here first */
Index: fasttext.c
@@ -1381,7 +1381,7 @@
 		/* avoid collisions with other processes */
 			if (tty->rsel)
 				return 2;
-				tty->rsel = p;
+			tty->rsel = p;
 		}
 		return 0;
 	} else if (mode == O_WRONLY) {
Index: proc.c
@@ -291,11 +291,11 @@
 
 	for (p = proclist; p; p = p->gl_next) {
 		if (p->slices >= 0) {
-		p->curpri = p->pri;
-		p->slices = SLICES(p->curpri);
+			p->curpri = p->pri;
+			p->slices = SLICES(p->curpri);
+		}
 	}
 }
-}
 
 /*
  * more priority code stuff:
Index: timeout.c
@@ -216,7 +216,7 @@
 {
 	TIMEOUT *cur, **prev;
 	short sr = spl7();
-	
+
 	prev = &tlist;
 	for (cur = tlist; cur; cur = cur->next) {
 		if (cur == this && (cur->proc == curproc)) {
Index: tty.c
@@ -691,16 +691,16 @@
 /* we may be in the middle of an escape sequence */
 	scan = (tty->state & TS_ESC);
 	if (scan != 0) {
-			tab = tty->xkey ? tty->xkey : vt52xkey;
-			r = (unsigned char) tab[scan++];
-			if (r) {
-				c = UNDEF;
-				if (tab[scan] == 0) scan = 0;
-			}
-			else
-				scan = 0;
-			tty->state = (tty->state & ~TS_ESC) | scan;
+		tab = tty->xkey ? tty->xkey : vt52xkey;
+		r = (unsigned char) tab[scan++];
+		if (r) {
+			c = UNDEF;
+			if (tab[scan] == 0) scan = 0;
 		}
+		else
+			scan = 0;
+		tty->state = (tty->state & ~TS_ESC) | scan;
+	}
 
 	while (c != UNDEF) {
 		ret = (*f->dev->read)(f, (char *)&r, 4L);

(6. debugging stuff, probably not worth adding to the release...)
btw when i took out this F_KEEP everything i tried worked as before,
anyone knows when its really needed?

Index: dosmem.c
@@ -120,7 +120,11 @@
 	if (((mode & F_PROTMODE) == 0) &&
 	    (curproc->ctxt[SYSCALL].pc > 0x00e00000L) &&
 	    (curproc->ctxt[SYSCALL].pc < 0x00efffffL)) {
+#if 0
+		mode |= (F_PROT_S + 0x10);
+#else
 		mode |= (F_PROT_S + 0x10) | F_KEEP;
+#endif
 		TRACE(("m_xalloc: VDI special (call from ROM)"));
 	}
 /*
Index: main.c
@@ -480,6 +480,7 @@
 	int isGEMDOS;
 {
 	short save_sr;
+	BASEPAGE *calltosbp;
 
 	if (in_kernel) return;
 
@@ -491,10 +492,16 @@
 	*((long *) 0x84L) = (long)old_dos.next;
 	*((long *) 0xb4L) = (long)old_bios.next;
 	*((long *) 0xb8L) = (long)old_xbios.next;
+	calltosbp = *tosbp;
 	*tosbp = _base;
 
 	in_kernel = 1;
 	spl(save_sr);
+#if 1
+	if (isGEMDOS && calltosbp != curproc->base)
+		ALERT("enter_kernel: syscall with tosbp (%lx: %lx) != curproc->base (%lx)",
+			tosbp, calltosbp, curproc->base);
+#endif
 }
 
 /*
Index: mem.c
@@ -1156,6 +1161,11 @@
 			for (i = 0; i < parent->num_reg; i++) {
 				m = parent->mem[i];
 				if (m && (m->mflags & M_FSAVED)) {
+#if 1
+					if (m->links != 1)
+						ALERT ("create_base: fork parent saved region %lx link count != 1 (%d, len %lx)",
+							m->loc, m->links, m->len);
+#endif
 					m->links = 0xfffe;
 					savemem = m;
 					break;

 oh and yes, i'm still using gcc 2.3.3pl2 too :)

 cheers
	Juergen
-- 
J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
								...ohne Gewehr
PGP public key fingerprint =  8A 18 58 54 03 7B FC 12  1F 8B 63 C7 19 27 CF DA