Files
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

134 lines
3.6 KiB
C

#include <lwp/common.h>
#include <lwp/queue.h>
#include <machlwp/machdep.h>
#include <lwp/cntxt.h>
#include <lwp/lwperror.h>
#include <lwp/process.h>
#include <lwp/schedule.h>
#include <lwp/alloc.h>
#include <lwp/condvar.h>
#include <lwp/monitor.h>
#include <sys/mman.h>
#ifndef lint
SCCSID(@(#) stack.c 1.1 92/07/30 Copyr 1987 Sun Micro);
#endif lint
typedef struct freestk_t {
caddr_t free_next; /* next stack in chain */
stkalign_t *free_bottom; /* address of memory for freeing */
} freestk_t;
STATIC bool_t CacheInit = FALSE; /* TRUE if cache stack allocated */
STATIC int StkType; /* cookie for process stack caches */
STATIC int StkAllocSize; /* actual size (bytes) of cached stacks */
#ifndef KERNEL
thread_t __Reaper = {CHARNULL, 0}; /* reaper thread */
#endif KERNEL
void return_stk();
#define REDZONE (sizeof (stkalign_t *) * 3) /* bytes in software redzone */
/*
* establish a cache of non-redzone-protected stacks. Add enough room
* for any overhead.
*/
int
lwp_setstkcache(minstksz, numstks)
register int minstksz; /* minimum size (in bytes) of cached stacks */
int numstks; /* number of cached stacks */
{
extern int maxasynchio_cached;
LWPINIT();
ERROR(CacheInit, LE_REUSE);
CacheInit = TRUE;
if (numstks == 0) {
numstks = 1;
}
/* add in sizeof stkalign_t * for reaper info */
minstksz += (REDZONE + sizeof (stkalign_t *) + STKOVERHEAD);
StkAllocSize = minstksz;
StkType = __allocinit((unsigned)minstksz, maxasynchio_cached, IFUNCNULL, FALSE);
return (minstksz);
}
/*
* return a new, cached, software-red-zone-protected stack.
* the redzone checking is enabled by routines in lwputil.c
* and is eitherd done at context switch time or at procedure call
* time (the latter by using the CHECK macro).
*/
stkalign_t *
lwp_newstk()
{
register caddr_t sp;
register stkalign_t *bottom;
if (!CacheInit) {
__panic("stack cache not initialized"); /* use default?? */
/* NOTREACHED */
}
GETCHUNK((caddr_t), sp, StkType); /* sp points to low mem */
bottom = (stkalign_t *)sp;
sp += StkAllocSize - sizeof (freestk_t); /* room for info to free stk */
((freestk_t *)sp)->free_bottom = bottom;
((freestk_t *)sp)->free_next = 0;
bzero((caddr_t)bottom, REDZONE); /* set up software redzone */
return ((stkalign_t *)sp);
}
/*
* lwp_datastk() -- PRIMITIVE.
* return a new, cached, red-zone-protected stack, suitable for
* use with lwp_create(). Also, initialize area above stack with
* "data" consisting of "dsize" bytes and return the location of
* "data" in "addr". We align data universally.
* Usage:
* sp = lwp_datastk(buf, sizeof (buf), &loc);
* lwp_create(&th, pc, prio, 0, sp, 1, loc);
*/
stkalign_t *
lwp_datastk(data, dsize, addr)
register caddr_t data;
register int dsize;
caddr_t *addr;
{
register caddr_t sp, stack;
register stkalign_t *bottom;
if (!CacheInit) {
__panic("stack cache not initialized"); /* use default?? */
/* NOTREACHED */
}
GETCHUNK((caddr_t), sp, StkType); /* sp points to low mem */
bottom = (stkalign_t *)sp;
/* subtract the stkalign_t to account for any alignment we may do */
sp += StkAllocSize - sizeof (freestk_t) - dsize - sizeof (stkalign_t);
/* align so freestk_t will fit ok. STACKALIGN is general. */
sp = (caddr_t)STACKALIGN(sp);
((freestk_t *)sp)->free_bottom = bottom;
((freestk_t *)sp)->free_next = 0;
stack = sp;
sp += sizeof (freestk_t);
/* align to any type */
sp = (caddr_t)STACKALIGN(sp + sizeof (stkalign_t));
*addr = sp;
if (data != CHARNULL) {
bcopy(data, sp, (u_int)dsize);
}
return ((stkalign_t *)stack);
}
void
return_stk(sp)
caddr_t sp;
{
register freestk_t *freestk;
freestk = (freestk_t *)sp;
FREECHUNK(StkType, freestk->free_bottom);
}