(lwpProc): Members lowmark and himark are confusing, replace by

ustack, usize.
(lwpCreate): Initialize them.
(lwpStackCheckInit, lwpStackCheck, lwpStackCheckUsed): Rewrite using
them.  lwpStackCheckUsed() was off by LWP_REDZONE when stack grows
down.

(lwpDestroy): Don't bother to clear memory to be freed.
This commit is contained in:
Markus Armbruster 2005-12-10 17:26:22 +00:00
parent bd7b1f480a
commit 2218a7a9a1
2 changed files with 53 additions and 107 deletions

View file

@ -155,7 +155,7 @@ lwpCreate(int priority, void (*entry)(void *), int stacksz, int flags, char *nam
return NULL; /* STKALIGN not power of 2 */ return NULL; /* STKALIGN not power of 2 */
if (!(newp = malloc(sizeof(struct lwpProc)))) if (!(newp = malloc(sizeof(struct lwpProc))))
return 0; return 0;
/* Make size a multiple of sizeof(long) to things aligned */ /* Make size a multiple of sizeof(long) to keep things aligned */
stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long); stacksz = (stacksz + sizeof(long) - 1) & -sizeof(long);
/* Add a red zone on each side of the stack for LWP_STACKCHECK */ /* Add a red zone on each side of the stack for LWP_STACKCHECK */
redsize = flags & LWP_STACKCHECK ? LWP_REDZONE : 0; redsize = flags & LWP_STACKCHECK ? LWP_REDZONE : 0;
@ -175,35 +175,34 @@ lwpCreate(int priority, void (*entry)(void *), int stacksz, int flags, char *nam
* ptr block size * ptr block size
* -------------------------------------- * --------------------------------------
* waste x * waste x
* lowmark -> red zone LWP_REDZONE * red zone LWP_REDZONE
* sp -> extra LWP_EXTRASTACK * sp -> extra LWP_EXTRASTACK
* stack stacksz * ustack -> stack stacksz
* himark -> red zone LWP_EXTRASTACK * red zone LWP_REDZONE
* waste STKALIGN - 1 - x * waste STKALIGN - 1 - x
* sp is aligned to a multiple of STKALIGN. * sp is aligned to a multiple of STKALIGN.
*/ */
sp = s + redsize + stacksz; sp = s + redsize + stacksz;
sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN); sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN);
newp->lowmark = sp + LWP_EXTRASTACK; newp->ustack = sp - stacksz;
newp->himark = sp - stacksz - redsize;
} else { } else {
/* /*
* Stack layout for stack growing upward: * Stack layout for stack growing upward:
* ptr block size * ptr block size
* -------------------------------------- * --------------------------------------
* waste x * waste x
* himark -> red zone LWP_REDZONE * red zone LWP_REDZONE
* extra LWP_EXTRASTACK
* sp -> stack stacksz * sp -> stack stacksz
* lowmark -> red zone LWP_EXTRASTACK * ustack -> extra LWP_EXTRASTACK
* red zone LWP_REDZONE
* waste STKALIGN - 1 - x * waste STKALIGN - 1 - x
* sp is aligned to a multiple of STKALIGN. * sp is aligned to a multiple of STKALIGN.
*/ */
sp = s + redsize + LWP_EXTRASTACK; sp = s + redsize + LWP_EXTRASTACK;
sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN); sp = (char *)0 + (((sp + STKALIGN - 1) - (char *)0) & -STKALIGN);
newp->lowmark = sp - LWP_EXTRASTACK - redsize; newp->ustack = sp - LWP_EXTRASTACK;
newp->himark = sp + size;
} }
newp->usize = stacksz + LWP_EXTRASTACK;
if (LWP_MAX_PRIO <= priority) if (LWP_MAX_PRIO <= priority)
priority = LWP_MAX_PRIO - 1; priority = LWP_MAX_PRIO - 1;
if (LwpMaxpri < (newp->pri = priority)) if (LwpMaxpri < (newp->pri = priority))
@ -213,8 +212,8 @@ lwpCreate(int priority, void (*entry)(void *), int stacksz, int flags, char *nam
newp->dead = 0; newp->dead = 0;
if (flags & LWP_STACKCHECK) if (flags & LWP_STACKCHECK)
lwpStackCheckInit(newp); lwpStackCheckInit(newp);
lwpStatus(newp, "creating process structure sbtm: %p", lwpStatus(newp, "creating process structure %p (sbtm %p)",
newp->sbtm); newp, newp->sbtm);
lwpReady(newp); lwpReady(newp);
lwpReady(LwpCurrent); lwpReady(LwpCurrent);
#ifdef UCONTEXT #ifdef UCONTEXT
@ -237,17 +236,9 @@ lwpDestroy(struct lwpProc *proc)
lwpStackCheck(proc); lwpStackCheck(proc);
} }
lwpStatus(proc, "destroying sbtm: %p", proc->sbtm); lwpStatus(proc, "destroying sbtm: %p", proc->sbtm);
proc->entry = 0;
proc->ud = 0;
proc->argv = 0;
free(proc->sbtm); free(proc->sbtm);
free(proc->name); free(proc->name);
free(proc->desc); free(proc->desc);
proc->name = 0;
proc->desc = 0;
proc->sbtm = 0;
proc->lowmark = 0;
proc->himark = 0;
free(proc); free(proc);
} }
@ -401,15 +392,11 @@ lwpInitSystem(int pri, char **ctxptr, int flags)
static void static void
lwpStackCheckInit(struct lwpProc *newp) lwpStackCheckInit(struct lwpProc *newp)
{ {
register int i; int *p;
register long *lp; int *lim = (int *)((char *)newp->sbtm + newp->size);
int lim = newp->size / sizeof(long); for (p = newp->sbtm; p < lim; p++)
if (!newp || !newp->sbtm) *p = LWP_CHECKMARK;
return;
for (lp = newp->sbtm, i = 0; i < lim; i++, lp++) {
*lp = LWP_CHECKMARK;
}
} }
/* lwpStackCheck /* lwpStackCheck
@ -420,57 +407,32 @@ lwpStackCheckInit(struct lwpProc *newp)
static void static void
lwpStackCheck(struct lwpProc *newp) lwpStackCheck(struct lwpProc *newp)
{ {
register int end, amt; int *btm = (int *)(newp->ustack - LWP_REDZONE);
register unsigned int i; int *top = (int *)(newp->ustack + newp->usize + LWP_REDZONE);
register long *lp; int n = LWP_REDZONE / sizeof(int);
register int growsDown; int i, lo_clean, hi_clean, marker, overflow, underflow;
int marker;
if (CANT_HAPPEN(!newp || !newp->himark || !newp->lowmark)) for (i = 0; i < n && btm[i] == LWP_CHECKMARK; i++) ;
return; lo_clean = i;
growsDown = growsdown(&marker);
for (lp = newp->himark, i = 0; i < LWP_REDZONE / sizeof(long); for (i = 1; i <= n && top[-i] == LWP_CHECKMARK; i++) ;
i++, lp++) { hi_clean = i - 1;
if (*lp == LWP_CHECKMARK)
continue; if (growsdown(&marker)) {
/* Stack overflow. */ overflow = n - lo_clean;
if (growsDown) { underflow = n - hi_clean;
end = i; } else {
while (i < LWP_REDZONE / sizeof(long)) { overflow = n - hi_clean;
if (*lp++ != LWP_CHECKMARK) underflow = n - lo_clean;
end = i;
i++;
}
amt = (end + 1) * sizeof(long);
} else {
amt = (i + 1) * sizeof(long);
}
logerror("Thread %s stack overflow %d bytes (of %u)",
newp->name, amt,
newp->size - 2 * LWP_REDZONE - (int)STKALIGN);
abort();
} }
for (lp = newp->lowmark, i = 0; i < LWP_REDZONE / sizeof(long); if (overflow)
i++, lp++) { logerror("Thread %s stack overflow %d bytes",
if (*lp == LWP_CHECKMARK) newp->name, overflow * sizeof(int));
continue; if (underflow)
/* Stack underflow. */ logerror("Thread %s stack underflow %d bytes",
if (growsDown) { newp->name, underflow * sizeof(int));
end = i; if (overflow || underflow)
while (i < LWP_REDZONE / sizeof(long)) {
if (*lp++ != LWP_CHECKMARK)
end = i;
i++;
}
amt = (end + 1) * sizeof(long);
} else {
amt = (LWP_REDZONE - i + 1) * sizeof(long);
}
logerror("Thread %s stack underflow %d bytes (of %u)",
newp->name, amt,
newp->size - 2 * LWP_REDZONE - (int)STKALIGN);
abort(); abort();
}
} }
/* lwpStackCheckUsed /* lwpStackCheckUsed
@ -480,36 +442,20 @@ lwpStackCheck(struct lwpProc *newp)
static void static void
lwpStackCheckUsed(struct lwpProc *newp) lwpStackCheckUsed(struct lwpProc *newp)
{ {
register int i; int *base = (int *)newp->ustack;
register long *lp; int *lim = (int *)(newp->ustack + newp->usize);
register int lim; int total = (lim + 1 - base) * sizeof(int);
int marker; int marker, used, *p;
if (!newp || !newp->sbtm)
return;
lim = newp->size / sizeof(long);
if (growsdown(&marker)) { if (growsdown(&marker)) {
/* Start at the bottom and find first non checkmark. */ for (p = base; p < lim && *p == LWP_CHECKMARK; ++p) ;
for (lp = newp->sbtm, i = 0; i < lim; i++, lp++) { used = (lim - p) * sizeof(int);
if (*lp != LWP_CHECKMARK) {
break;
}
}
} else { } else {
/* Start at the top and find first non checkmark. */ for (p = lim - 1; p >= base && *p == LWP_CHECKMARK; --p) ;
lp = newp->sbtm; used = (p - base + 1) * sizeof(int);
lp += newp->size / sizeof(long);
lp--;
for (i = 0; i < lim; i++, lp--) {
if (*lp != LWP_CHECKMARK) {
break;
}
}
} }
lwpStatus(newp, "Thread stack %lu used %lu left %lu total", lwpStatus(newp, "Thread stack %d used, %d left, %d total",
labs((char *)lp - (char *)newp->lowmark) - LWP_REDZONE, used, total - used, total);
labs((char *)newp->himark - (char *)lp) - LWP_REDZONE,
labs((char *)newp->himark - (char *)newp->lowmark) - LWP_REDZONE);
} }
#endif #endif

View file

@ -42,8 +42,10 @@ struct lwpProc {
#else /* !UCONTEXT */ #else /* !UCONTEXT */
jmp_buf context; /* processor context area */ jmp_buf context; /* processor context area */
#endif /* !UCONTEXT */ #endif /* !UCONTEXT */
void *sbtm; /* bottom of stack attached to it */ void *sbtm; /* stack buffer attached to it */
int size; /* size of stack */ int size; /* size of stack buffer */
char *ustack; /* lowest usable stack address */
int usize; /* size of usable stack */
void (*entry)(void *); /* entry point */ void (*entry)(void *); /* entry point */
int dead; /* whether the process can be rescheduled */ int dead; /* whether the process can be rescheduled */
int pri; /* which scheduling queue we're on */ int pri; /* which scheduling queue we're on */
@ -52,8 +54,6 @@ struct lwpProc {
int argc; /* initial arguments */ int argc; /* initial arguments */
char **argv; char **argv;
void *ud; /* user data */ void *ud; /* user data */
void *lowmark; /* start of low buffer around stack */
void *himark; /* start of upper buffer around stack */
char *name; /* process name and description */ char *name; /* process name and description */
char *desc; char *desc;
int flags; int flags;