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]->priv = NULL;
|
||||||
ctx->cothreads[0]->flags = COTHREAD_STARTED;
|
ctx->cothreads[0]->flags = COTHREAD_STARTED;
|
||||||
ctx->cothreads[0]->sp = (void *) CURRENT_STACK_FRAME;
|
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",
|
GST_INFO (GST_CAT_COTHREADS, "0th cothread is %p at sp:%p",
|
||||||
ctx->cothreads[0], ctx->cothreads[0]->sp);
|
ctx->cothreads[0], ctx->cothreads[0]->sp);
|
||||||
|
@ -256,11 +254,25 @@ cothread_create (cothread_context *ctx)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
/* The mmap is necessary on Linux/i386, and possibly others, since the
|
||||||
* kernel is picky about when we can expand our stack. */
|
* kernel is picky about when we can expand our stack. */
|
||||||
GST_DEBUG (GST_CAT_COTHREADS, "mmaping %p, size 0x%08x", cothread,
|
GST_DEBUG (GST_CAT_COTHREADS, "mmaping %p, size 0x%08x", cothread,
|
||||||
COTHREAD_STACKSIZE);
|
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,
|
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
GST_DEBUG (GST_CAT_COTHREADS, "coming out of mmap");
|
GST_DEBUG (GST_CAT_COTHREADS, "coming out of mmap");
|
||||||
|
@ -268,21 +280,11 @@ cothread_create (cothread_context *ctx)
|
||||||
perror ("mmap'ing cothread stack space");
|
perror ("mmap'ing cothread stack space");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (mmaped != cothread) {
|
if (mmaped != (void *)cothread + page_size * 2) {
|
||||||
g_warning ("could not mmap requested memory for cothread");
|
g_warning ("could not mmap requested memory for cothread");
|
||||||
return NULL;
|
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;
|
cothread->magic_number = COTHREAD_MAGIC_NUMBER;
|
||||||
GST_DEBUG (GST_CAT_COTHREADS, "create cothread %d with magic number 0x%x",
|
GST_DEBUG (GST_CAT_COTHREADS, "create cothread %d with magic number 0x%x",
|
||||||
slot, cothread->magic_number);
|
slot, cothread->magic_number);
|
||||||
|
@ -291,9 +293,8 @@ cothread_create (cothread_context *ctx)
|
||||||
cothread->flags = 0;
|
cothread->flags = 0;
|
||||||
cothread->priv = NULL;
|
cothread->priv = NULL;
|
||||||
cothread->sp = ((guchar *) cothread + COTHREAD_STACKSIZE);
|
cothread->sp = ((guchar *) cothread + COTHREAD_STACKSIZE);
|
||||||
cothread->sp -= 16; /* necessary for PowerPC */
|
cothread->stack_size = COTHREAD_STACKSIZE - page_size * 2;
|
||||||
cothread->top_sp = cothread->sp; /* for debugging purposes
|
cothread->stack_base = (void *)cothread + 2 * page_size;
|
||||||
to detect stack overruns */
|
|
||||||
|
|
||||||
GST_INFO (GST_CAT_COTHREADS,
|
GST_INFO (GST_CAT_COTHREADS,
|
||||||
"created cothread #%d in slot %d: %p at sp:%p",
|
"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->func = func;
|
||||||
thread->argc = argc;
|
thread->argc = argc;
|
||||||
thread->argv = argv;
|
thread->argv = argv;
|
||||||
thread->pc = (void *) func;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -438,8 +438,6 @@ void
|
||||||
cothread_stop (cothread_state * thread)
|
cothread_stop (cothread_state * thread)
|
||||||
{
|
{
|
||||||
thread->flags &= ~COTHREAD_STARTED;
|
thread->flags &= ~COTHREAD_STARTED;
|
||||||
thread->pc = 0;
|
|
||||||
thread->sp = thread->top_sp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -496,6 +494,8 @@ cothread_stub (void)
|
||||||
|
|
||||||
GST_DEBUG_ENTER ("");
|
GST_DEBUG_ENTER ("");
|
||||||
|
|
||||||
|
GST_DEBUG (GST_CAT_COTHREADS, "stack addr %p\n", &ctx);
|
||||||
|
|
||||||
thread->flags |= COTHREAD_STARTED;
|
thread->flags |= COTHREAD_STARTED;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -685,14 +685,12 @@ cothread_switch (cothread_state * thread)
|
||||||
enter = setjmp (current->jmp);
|
enter = setjmp (current->jmp);
|
||||||
if (enter != 0) {
|
if (enter != 0) {
|
||||||
GST_DEBUG (GST_CAT_COTHREADS,
|
GST_DEBUG (GST_CAT_COTHREADS,
|
||||||
"enter cothread #%d %d %p<->%p (%d) %p",
|
"enter cothread #%d %d sp=%p jmpbuf=%p",
|
||||||
current->cothreadnum, enter, current->sp, current->top_sp,
|
current->cothreadnum, enter, current->sp, current->jmp);
|
||||||
(char*) current->top_sp - (char*) current->sp, current->jmp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GST_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d %p<->%p (%d) %p",
|
GST_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d sp=%p jmpbuf=%p",
|
||||||
current->cothreadnum, enter, current->sp, current->top_sp,
|
current->cothreadnum, enter, current->sp, current->jmp);
|
||||||
(char *) current->top_sp - (char *) current->sp, current->jmp);
|
|
||||||
enter = 1;
|
enter = 1;
|
||||||
|
|
||||||
if (current->flags & COTHREAD_DESTROYED) {
|
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);
|
GST_DEBUG (GST_CAT_COTHREADS, "set stack to %p", thread->sp);
|
||||||
/* restore stack pointer and other stuff of new cothread */
|
/* restore stack pointer and other stuff of new cothread */
|
||||||
if (thread->flags & COTHREAD_STARTED) {
|
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 */
|
/* switch to it */
|
||||||
longjmp (thread->jmp, 1);
|
longjmp (thread->jmp, 1);
|
||||||
}
|
}
|
||||||
else {
|
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_SETUP_STACK ((char*)thread->sp);
|
||||||
GST_ARCH_SET_SP (thread->sp);
|
GST_ARCH_SET_SP (thread->sp);
|
||||||
/* start it */
|
/* start it */
|
||||||
GST_ARCH_CALL (cothread_stub);
|
GST_ARCH_CALL (cothread_stub);
|
||||||
|
#endif
|
||||||
|
|
||||||
GST_DEBUG (GST_CAT_COTHREADS, "exit thread ");
|
GST_DEBUG (GST_CAT_COTHREADS, "exit thread ");
|
||||||
ctx->current = 0;
|
ctx->current = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,8 @@ struct _cothread_state {
|
||||||
int flags;
|
int flags;
|
||||||
void *sp;
|
void *sp;
|
||||||
jmp_buf jmp;
|
jmp_buf jmp;
|
||||||
/* is this needed any more? */
|
void *stack_base;
|
||||||
void *top_sp;
|
unsigned long stack_size;
|
||||||
void *pc;
|
|
||||||
|
|
||||||
int magic_number;
|
int magic_number;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue