mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
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:
parent
89994cf808
commit
aff80e14d7
2 changed files with 42 additions and 30 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue