[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