refactor cothread stack mmap code. Add makecontext() as an option for initial stack preparation.

Original commit message from CVS:
refactor cothread stack mmap code.  Add makecontext() as an option
for initial stack preparation.
This commit is contained in:
David Schleef 2002-12-05 01:50:31 +00:00
parent 89994cf808
commit aff80e14d7
2 changed files with 42 additions and 30 deletions

View file

@ -166,8 +166,6 @@ cothread_context_init (void)
ctx->cothreads[0]->priv = NULL;
ctx->cothreads[0]->flags = COTHREAD_STARTED;
ctx->cothreads[0]->sp = (void *) CURRENT_STACK_FRAME;
ctx->cothreads[0]->top_sp = ctx->cothreads[0]->sp;
ctx->cothreads[0]->pc = 0;
GST_INFO (GST_CAT_COTHREADS, "0th cothread is %p at sp:%p",
ctx->cothreads[0], ctx->cothreads[0]->sp);
@ -256,11 +254,25 @@ cothread_create (cothread_context *ctx)
}
#endif
#ifdef _SC_PAGESIZE
page_size = sysconf(_SC_PAGESIZE);
#else
page_size = getpagesize();
#endif
/* The mmap is necessary on Linux/i386, and possibly others, since the
* kernel is picky about when we can expand our stack. */
GST_DEBUG (GST_CAT_COTHREADS, "mmaping %p, size 0x%08x", cothread,
COTHREAD_STACKSIZE);
mmaped = mmap ((void *) cothread, COTHREAD_STACKSIZE,
/* Remap with a guard page. This decreases our stack size by 8 kB (for
* 4 kB pages) and also wastes almost 4 kB for the cothreads
* structure */
munmap((void *)cothread, COTHREAD_STACKSIZE);
mmaped = mmap ((void *) cothread, page_size,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
mmaped = mmap (((void *) cothread) + page_size * 2,
COTHREAD_STACKSIZE - page_size * 2,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
GST_DEBUG (GST_CAT_COTHREADS, "coming out of mmap");
@ -268,21 +280,11 @@ cothread_create (cothread_context *ctx)
perror ("mmap'ing cothread stack space");
return NULL;
}
if (mmaped != cothread) {
if (mmaped != (void *)cothread + page_size * 2) {
g_warning ("could not mmap requested memory for cothread");
return NULL;
}
#ifdef _SC_PAGESIZE
page_size = sysconf(_SC_PAGESIZE);
#else
page_size = getpagesize();
#endif
/* Unmap a guard page. This decreases our stack size by 8 kB (for
* 4 kB pages) and also wastes almost 4 kB for the cothreads
* structure */
munmap((void *)cothread + page_size, page_size);
cothread->magic_number = COTHREAD_MAGIC_NUMBER;
GST_DEBUG (GST_CAT_COTHREADS, "create cothread %d with magic number 0x%x",
slot, cothread->magic_number);
@ -291,9 +293,8 @@ cothread_create (cothread_context *ctx)
cothread->flags = 0;
cothread->priv = NULL;
cothread->sp = ((guchar *) cothread + COTHREAD_STACKSIZE);
cothread->sp -= 16; /* necessary for PowerPC */
cothread->top_sp = cothread->sp; /* for debugging purposes
to detect stack overruns */
cothread->stack_size = COTHREAD_STACKSIZE - page_size * 2;
cothread->stack_base = (void *)cothread + 2 * page_size;
GST_INFO (GST_CAT_COTHREADS,
"created cothread #%d in slot %d: %p at sp:%p",
@ -425,7 +426,6 @@ cothread_setfunc (cothread_state * thread, cothread_func func, int argc, char **
thread->func = func;
thread->argc = argc;
thread->argv = argv;
thread->pc = (void *) func;
}
/**
@ -438,8 +438,6 @@ void
cothread_stop (cothread_state * thread)
{
thread->flags &= ~COTHREAD_STARTED;
thread->pc = 0;
thread->sp = thread->top_sp;
}
/**
@ -496,6 +494,8 @@ cothread_stub (void)
GST_DEBUG_ENTER ("");
GST_DEBUG (GST_CAT_COTHREADS, "stack addr %p\n", &ctx);
thread->flags |= COTHREAD_STARTED;
while (TRUE) {
@ -685,14 +685,12 @@ cothread_switch (cothread_state * thread)
enter = setjmp (current->jmp);
if (enter != 0) {
GST_DEBUG (GST_CAT_COTHREADS,
"enter cothread #%d %d %p<->%p (%d) %p",
current->cothreadnum, enter, current->sp, current->top_sp,
(char*) current->top_sp - (char*) current->sp, current->jmp);
"enter cothread #%d %d sp=%p jmpbuf=%p",
current->cothreadnum, enter, current->sp, current->jmp);
return;
}
GST_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d %p<->%p (%d) %p",
current->cothreadnum, enter, current->sp, current->top_sp,
(char *) current->top_sp - (char *) current->sp, current->jmp);
GST_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d sp=%p jmpbuf=%p",
current->cothreadnum, enter, current->sp, current->jmp);
enter = 1;
if (current->flags & COTHREAD_DESTROYED) {
@ -702,15 +700,30 @@ cothread_switch (cothread_state * thread)
GST_DEBUG (GST_CAT_COTHREADS, "set stack to %p", thread->sp);
/* restore stack pointer and other stuff of new cothread */
if (thread->flags & COTHREAD_STARTED) {
GST_DEBUG (GST_CAT_COTHREADS, "in thread %p", thread->jmp);
GST_DEBUG (GST_CAT_COTHREADS, "via longjmp() jmpbuf %p", thread->jmp);
/* switch to it */
longjmp (thread->jmp, 1);
}
else {
#ifdef HAVE_MAKECONTEXT
ucontext_t ucp;
GST_DEBUG (GST_CAT_COTHREADS, "making context");
g_assert(thread != cothread_main(ctx));
getcontext(&ucp);
ucp.uc_stack.ss_sp = (void *)thread->stack_base;
ucp.uc_stack.ss_size = thread->stack_size;
makecontext(&ucp, cothread_stub, 0);
setcontext(&ucp);
#else
GST_ARCH_SETUP_STACK ((char*)thread->sp);
GST_ARCH_SET_SP (thread->sp);
/* start it */
GST_ARCH_CALL (cothread_stub);
#endif
GST_DEBUG (GST_CAT_COTHREADS, "exit thread ");
ctx->current = 0;
}

View file

@ -51,9 +51,8 @@ struct _cothread_state {
int flags;
void *sp;
jmp_buf jmp;
/* is this needed any more? */
void *top_sp;
void *pc;
void *stack_base;
unsigned long stack_size;
int magic_number;
};