Commit c50aa691 authored by Benjamin Otte's avatar Benjamin Otte
Browse files

add actions. see ChangeLog for details

Original commit message from CVS:
add actions. see ChangeLog for details
parent 27c43157
2005-05-29 Benjamin Otte <in7y118@public.uni-hamburg.de>
ORGANIZATIONAL CHANGES:
* configure.ac:
remove leftover valgrind stuff, fix GST_OBJ_*FLAGS
* gst/cothreads.c:
* gst/cothreads.h:
remove cothreads
* gst/thread.h:
* gst/thread.c:
remove GstThread
* gst/gstschedulerfactory.h:
* gst/gstschedulerfactory.c:
* gst/registries/gstlibxmlregistry.c:
split out registry specific stuff from gstscheduler.[ch]
* gst/Makefile.am:
* gst/gst.h:
remove cothread.[ch] and gstthread.[ch], add gstaction.[ch] and
gstschedulerfactory.[ch]
* gst/gstcompat.h:
add a gst_bin_iterate macro, remove old 0.5 macros
* gst/gst.c: (gst_register_core_elements):
remove registering GstThread
* gst/gst_private.h:
add some functions here that shouldn't be exported
* gst/gstclock.c: (gst_clock_class_init):
remove thread initing, it's done in gst.c
* gst/gstclock.h:
* gst/gsttypes.h:
move some more types to gsttypes.h: GstRealPad(Class),
GstClockTime and GstAction
NEW SCHEDULING MODEL:
* gst/gstaction.h:
* gst/gstaction.c:
implement actions. These were formally known as triggers. They
implement the different callback types used by elements.
* gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_element_sched),
(gst_bin_unset_element_sched), (gst_bin_iterate):
* gst/gstbin.h:
- remove gst_bin_iterate
- remove code for decoupled elements
* gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad),
(gst_element_reset_actions), (gst_element_change_state),
(gst_element_found_tags_for_pad):
add action support. Adding/removing pads adds/removes their actions
from the element automatically. Allow resetting actions which sets
all actions to their initial state.
* gst/gstelement.c:
* gst/gstelement.h:
remove lots of functions related to the old scheduling code, like
_yield, _interrupt etc
* gst/gstpad.c: (gst_pad_push), (gst_real_pad_set_active),
(gst_real_pad_is_active), (gst_real_pad_set_initially_active),
(gst_src_pad_set_action_handler),
(gst_sink_pad_set_action_handler):
add functions to interact with pad actions.
* gst/gstpad.c:
* gst/gstpad.h:
remove lots of stuff related to old scheduling, like DECOUPLED, the
active property, chainhandlers etc
* gst/gstpipeline.c: (gst_pipeline_class_init),
(gst_pipeline_dispose):
remove old scheduling specific calls
* gst/gstscheduler.c: (gst_scheduler_class_init),
(gst_scheduler_init), (gst_scheduler_dispose),
(gst_scheduler_real_add_element),
(gst_scheduler_real_remove_element), (gst_scheduler_marshal),
(gst_scheduler_add_element), (gst_scheduler_remove_element),
(gst_scheduler_state_transition), (gst_scheduler_get_clock),
(gst_scheduler_set_clock), (gst_scheduler_auto_clock),
(gst_scheduler_pad_push):
* gst/gstscheduler.h:
remove old scheduling code and add new one, which is basically
add_action, remove_action (obvious), toggle_active (to indicate
changing the activity state of an action) and update_values (to
indicate that an action changed the values it was configured with
ELEMENTS:
* gst/gstqueue.c:
* gst/gstqueue.h:
nearly reimplement. Throw out all the threading specific code.
* gst/elements/gstfakesink.c: (gst_fakesink_init),
(gst_fakesink_request_new_pad), (gst_fakesink_chain):
* gst/elements/gstfdsink.c: (gst_fdsink_init), (gst_fdsink_chain):
* gst/elements/gstfdsrc.c: (gst_fdsrc_init), (gst_fdsrc_get):
* gst/elements/gstfilesink.c: (gst_filesink_init),
(gst_filesink_handle_event), (gst_filesink_chain):
* gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_get):
replace get/chainfunction with a src/sinkpad action.
* gst/elements/gstfakesrc.c: (gst_fakesrc_class_init),
(gst_fakesrc_init), (gst_fakesrc_request_new_pad),
(gst_fakesrc_update_functions), (gst_fakesrc_set_property),
(gst_fakesrc_get_property), (gst_fakesrc_get):
* gst/elements/gstfakesrc.h:
replace getfunction with a srcpad action. Remove "loopbased"
property.
* gst/elements/gstidentity.c: (gst_identity_base_init),
(gst_identity_class_init), (gst_identity_init),
(gst_identity_push), (gst_identity_chain), (gst_identity_wakeup),
(gst_identity_set_property), (gst_identity_get_property),
(gst_identity_change_state):
* gst/elements/gstidentity.h:
make this a PUSH-based element. Remove "loopbased" property and
other scheduling specific stuff.
* gst/elements/gsttee.c: (gst_tee_base_init), (gst_tee_class_init),
(gst_tee_init), (gst_tee_request_new_pad), (gst_tee_get),
(gst_tee_chain), (gst_tee_change_state):
* gst/elements/gsttee.h:
implement using pad actions
* gst/elements/gsttypefindelement.c: (gst_type_find_element_init),
(push_buffer_store), (stop_typefinding),
(gst_type_find_element_wakeup),
(gst_type_find_element_handle_event),
(gst_type_find_element_chain):
* gst/elements/gsttypefindelement.h:
make this a push-based element
SCHEDULERS:
* gst/schedulers/Makefile.am:
* gst/schedulers/cothreads_compat.h:
* gst/schedulers/entryscheduler.c:
* gst/schedulers/faircothreads.c:
* gst/schedulers/faircothreads.h:
* gst/schedulers/fairscheduler.c:
* gst/schedulers/gstbasicscheduler.c:
* gst/schedulers/gstoptimalscheduler.c:
* gst/schedulers/gthread-cothreads.h:
remove
* gst/schedulers/gstsimplescheduler.c:
implement a simple scheduler. It's supposed to be as simple as
possible (code-size). It's as fast as opt in 0.8.
LIBS:
* libs/gst/bytestream/Makefile.am:
* libs/gst/bytestream/gstbytestream.c:
* libs/gst/bytestream/gstbytestream.h:
remove bytestream
* libs/gst/bytestream/filepad.c: (gst_file_pad_init),
(gst_file_pad_chain), (gst_file_pad_parent_set):
make this a sinkpad-action using pad.
TOOLS:
* tools/Makefile.am:
* tools/gst-md5sum.1.in:
* tools/gst-md5sum.c:
* tools/gst-xmlinspect.1.in:
* tools/gst-xmlinspect.c:
* tools/gst-xmllaunch.1.in:
remove gst-xml-* tools and gst-md5sum.
* tools/gst-inspect.c: (print_element_flag_info),
(print_implementation_info), (print_pad_info):
fix to show current scheduling information.
* tools/gst-launch.c: (fault_handler_sighandler),
(fault_handler_sigaction), (fault_spin), (print_tag),
(play_handler), (should_quit), (quit_cb), (launch_poll), (main):
implement new scheduling.
* tools/gst-typefind.c: (have_type_handler), (main):
make work with new scheduling
TESTSUITE:
* tests/Makefile.am:
* tests/lat.c:
* tests/muxing/Makefile.am:
* tests/muxing/case1.c:
* tests/sched/.cvsignore:
* tests/sched/Makefile.am:
* tests/sched/dynamic-pipeline.c:
* tests/sched/interrupt1.c:
* tests/sched/interrupt2.c:
* tests/sched/interrupt3.c:
* tests/sched/runtestcases:
* tests/sched/runxml.c:
* tests/sched/sched-stress.c:
* tests/sched/testcases:
* tests/sched/testcases1.tc:
* tests/threadstate/.cvsignore:
* tests/threadstate/Makefile.am:
* tests/threadstate/test1.c:
* tests/threadstate/test2.c:
* tests/threadstate/threadstate1.c:
* tests/threadstate/threadstate2.c:
* tests/threadstate/threadstate3.c:
* tests/threadstate/threadstate4.c:
* tests/threadstate/threadstate5.c:
* testsuite/Makefile.am:
* testsuite/bytestream/Makefile.am:
* testsuite/cleanup/Makefile.am:
* testsuite/clock/Makefile.am:
* testsuite/clock/clock1.c: (main):
* testsuite/dlopen/loadgst.c: (do_test):
* testsuite/elements/fake.c: (main):
* testsuite/elements/struct_i386.h:
* testsuite/elements/tee.c: (main):
* testsuite/ghostpads/ghostpads.c: (main):
* testsuite/pad/Makefile.am:
* testsuite/pad/getnopush.c: (gst_test_src_get),
(gst_test_src_init), (main):
* testsuite/parse/parse1.c:
* testsuite/schedulers/142183-2.c: (main):
* testsuite/schedulers/143777-2.c: (main):
* testsuite/schedulers/143777.c: (main):
* testsuite/schedulers/147819.c: (handoff_identity1),
(handoff_identity2), (main):
* testsuite/schedulers/Makefile.am:
* testsuite/schedulers/group_link.c: (main):
* testsuite/schedulers/queue_link.c: (main):
* testsuite/schedulers/relink.c: (cb_handoff), (main):
* testsuite/schedulers/unlink.c: (main):
* testsuite/schedulers/unref.c: (cb_handoff), (main):
* testsuite/schedulers/useless_iteration.c: (main):
- make work with new scheduling (mostly by making fakesrc only send
a fixed number of buffers so we hit EOS and uising the _iterate
compat macro.
- remove tests that test the old scheduling model
- remove tests that test threading
2005-05-17 Benjamin Otte <in7y118@public.uni-hamburg.de>
* gst/gstobject.c: (gst_object_ref), (gst_object_unref):
......
common @ 67b7e6c0
Subproject commit 131c2632127e6f061b5270d8f80651782a4fdd13
Subproject commit 67b7e6c0db99415e0440d0c576495641b53e976a
......@@ -560,15 +560,14 @@ AC_SUBST(GST_PKG_DEPS)
dnl flags shared for all internal objects (core libs, elements, applications)
dnl we disable deprecated internally
dnl XML, GLib, popt, GST_INT, VALGRIND, and the right include for CFLAGS
dnl XML, GLib, popt, GST_INT, and the right include for CFLAGS
dnl no need to add XML, GLib, popt explicitly since libgstreamer pulls them in
GST_INT_CFLAGS="$GLIB_CFLAGS $XML_CFLAGS $GST_PKG_CFLAGS \
$GST_INT_CFLAGS $GST_ERROR_CFLAGS -DGST_DISABLE_DEPRECATED"
dnl Private vars for libgst only
GST_LIB_CFLAGS="$GST_PKG_CFLAGS $GST_INT_CFLAGS \
$VALGRIND_CFLAGS -I\$(top_srcdir)"
GST_LIB_LIBS="$XML_LIBS $GLIB_LIBS -lpopt $GST_PKG_LIBS $LTLIBINTL $VALGRIND_LIBS -lm"
GST_LIB_CFLAGS="$GST_PKG_CFLAGS $GST_INT_CFLAGS -I\$(top_srcdir)"
GST_LIB_LIBS="$XML_LIBS $GLIB_LIBS -lpopt $GST_PKG_LIBS $LTLIBINTL -lm"
GST_LIB_LDFLAGS="$GST_LT_LDFLAGS -version-info $GST_LIBVERSION $EXPORT_LDFLAGS"
AC_SUBST(GST_LIB_CFLAGS)
AC_SUBST(GST_LIB_LIBS)
......@@ -576,10 +575,11 @@ AC_SUBST(GST_LIB_LDFLAGS)
dnl Vars for all internal objects built on libgstreamer
GST_OBJ_CFLAGS="$GST_INT_CFLAGS -I\$(top_srcdir)/libs -I\$(top_srcdir)"
GST_OBJ_LIBS="\$(top_builddir)/gst/libgstreamer-$GST_MAJORMINOR.la"
AC_SUBST(GST_OBJ_CFLAGS, "$GST_OBJ_CFLAGS")
AC_SUBST(GST_OBJ_LIBS, "$GST_OBJ_LIBS")
GST_OBJ_LIBS="\$(top_builddir)/gst/libgstreamer-$GST_MAJORMINOR.la $GLIB_LIBS $LTLIBINTL"
GST_OBJ_LDFLAGS="$GST_LT_LDFLAGS -version-info $GST_LIBVERSION $EXPORT_LDFLAGS"
AC_SUBST(GST_OBJ_CFLAGS)
AC_SUBST(GST_OBJ_LIBS)
AC_SUBST(GST_OBJ_LDFLAGS)
dnl specific additional LDFLAGS for plugins
GST_PLUGIN_LDFLAGS="-module -avoid-version $EXPORT_LDFLAGS"
......@@ -646,10 +646,7 @@ tests/Makefile
tests/bufspeed/Makefile
tests/instantiate/Makefile
tests/memchunk/Makefile
tests/muxing/Makefile
tests/seeking/Makefile
tests/sched/Makefile
tests/threadstate/Makefile
testsuite/Makefile
testsuite/bins/Makefile
testsuite/bytestream/Makefile
......
lib_LTLIBRARIES = libgstreamer-@GST_MAJORMINOR@.la
AS_LIBTOOL_LIB = libgstreamer-@GST_MAJORMINOR@
if GST_DISABLE_OMEGA_COTHREADS
noinst_LTLIBRARIES =
else
noinst_LTLIBRARIES = libcothreads.la
endif
#GST_INSTRUMENT_FLAGS = -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION
......@@ -82,6 +77,7 @@ EXTRA_libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gst.c \
gstobject.c \
gstaction.c \
gstbin.c \
gstbuffer.c \
gstcaps.c \
......@@ -104,11 +100,11 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gstqueue.c \
gstquery.c \
gstscheduler.c \
gstschedulerfactory.c \
gststructure.c \
gstsystemclock.c \
gsttag.c \
gsttaginterface.c \
gstthread.c \
$(GST_TRACE_SRC) \
gsttypefind.c \
$(GST_URI_SRC) \
......@@ -150,6 +146,7 @@ libgstreamer_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINO
gst_headers = \
gst.h \
gstaction.h \
gstobject.h \
gstbin.h \
gstbuffer.h \
......@@ -174,11 +171,11 @@ gst_headers = \
gstqueue.h \
gstquery.h \
gstscheduler.h \
gstschedulerfactory.h \
gststructure.h \
gstsystemclock.h \
gsttag.h \
gsttaginterface.h \
gstthread.h \
gsttrace.h \
gsttypefind.h \
gsttypes.h \
......@@ -201,16 +198,7 @@ noinst_HEADERS = \
gst-i18n-app.h \
gst_private.h \
gstdata_private.h \
gstarch.h \
cothreads.h
if GST_DISABLE_OMEGA_COTHREADS
#libcothreads_la_SOURCES =
#libcothreads_la_CFLAGS =
else
libcothreads_la_SOURCES = cothreads.c
libcothreads_la_CFLAGS = $(libgstreamer_@GST_MAJORMINOR@_la_CFLAGS)
endif
gstarch.h
gstmarshal.h: gstmarshal.list
......
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* cothreads.c: Cothreading routines
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gst_private.h"
#include <glib.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include "cothreads.h"
#include "gstarch.h"
#include "gstinfo.h"
#include "gstutils.h"
#ifdef HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
#ifndef MAP_ANONYMOUS
#ifdef MAP_ANON
/* older glibc's have MAP_ANON instead of MAP_ANONYMOUS */
#define MAP_ANONYMOUS MAP_ANON
#else
/* make due without. If this fails, we need to open and map /dev/zero */
#define MAP_ANONYMOUS 0
#endif
#endif
#define STACK_SIZE 0x200000
#define COTHREAD_MAGIC_NUMBER 0xabcdef
#define COTHREAD_MAXTHREADS 16
#define COTHREAD_STACKSIZE (STACK_SIZE/COTHREAD_MAXTHREADS)
static void cothread_destroy (cothread_state * cothread);
struct _cothread_context
{
cothread_state *cothreads[COTHREAD_MAXTHREADS]; /* array of cothread states */
int ncothreads;
int current;
unsigned long stack_top;
GHashTable *data;
GThread *thread;
};
/* Disabling this define allows you to shut off a few checks in
* cothread_switch. This likely will speed things up fractionally */
#define COTHREAD_PARANOID
/* this _cothread_ctx_key is used as a GThread key to the thread's context
* a GThread key is a "pointer" to memory space that is/can be different
* (ie. private) for each thread. The key itself is shared among threads,
* so it only needs to be initialized once.
*/
static GStaticPrivate _cothread_ctx_key = G_STATIC_PRIVATE_INIT;
/*
* This should only after context init, since we do checking.
*/
static cothread_context *
cothread_get_current_context (void)
{
cothread_context *ctx;
ctx = g_static_private_get (&_cothread_ctx_key);
g_assert (ctx);
#ifdef COTHREAD_PARANOID
g_assert (ctx->thread == g_thread_self ());
#endif
return ctx;
}
/**
* cothread_context_init:
*
* Create and initialize a new cothread context
*
* Returns: the new cothread context
*/
cothread_context *
cothread_context_init (void)
{
char __csf;
void *current_stack_frame = &__csf; /* Get pointer inside current stack frame */
cothread_context *ctx;
/* if there already is a cotread context for this thread,
* just return it */
ctx = g_static_private_get (&_cothread_ctx_key);
if (ctx) {
GST_CAT_INFO (GST_CAT_COTHREADS,
"returning private _cothread_ctx_key %p", ctx);
return ctx;
}
/*
* initalize the whole of the cothreads context
*/
ctx = (cothread_context *) g_malloc (sizeof (cothread_context));
/* we consider the initiating process to be cothread 0 */
ctx->ncothreads = 1;
ctx->current = 0;
ctx->data = g_hash_table_new (g_str_hash, g_str_equal);
ctx->thread = g_thread_self ();
GST_CAT_INFO (GST_CAT_COTHREADS, "initializing cothreads");
/* set this thread's context pointer */
GST_CAT_INFO (GST_CAT_COTHREADS,
"setting private _cothread_ctx_key to %p in thread %p", ctx,
g_thread_self ());
g_static_private_set (&_cothread_ctx_key, ctx, NULL);
g_assert (ctx == cothread_get_current_context ());
/* clear the cothread data */
memset (ctx->cothreads, 0, sizeof (ctx->cothreads));
/* FIXME this may not be 64bit clean
* could use casts to uintptr_t from inttypes.h
* if only all platforms had inttypes.h
*/
/* stack_top is the address of the first byte past our stack segment. */
/* FIXME: an assumption is made that the stack segment is STACK_SIZE
* aligned. */
ctx->stack_top = ((gulong) current_stack_frame | (STACK_SIZE - 1)) + 1;
GST_CAT_DEBUG (GST_CAT_COTHREADS, "stack top is 0x%08lx", ctx->stack_top);
/*
* initialize the 0th cothread
*/
ctx->cothreads[0] = (cothread_state *) g_malloc0 (sizeof (cothread_state));
ctx->cothreads[0]->ctx = ctx;
ctx->cothreads[0]->cothreadnum = 0;
ctx->cothreads[0]->func = NULL;
ctx->cothreads[0]->argc = 0;
ctx->cothreads[0]->argv = NULL;
ctx->cothreads[0]->priv = NULL;
ctx->cothreads[0]->flags = COTHREAD_STARTED;
ctx->cothreads[0]->sp = (void *) current_stack_frame;
GST_CAT_INFO (GST_CAT_COTHREADS, "0th cothread is %p at sp:%p",
ctx->cothreads[0], ctx->cothreads[0]->sp);
return ctx;
}
/**
* cothread_context_free:
* @ctx: the cothread context to free
*
* Free the cothread context.
*/
void
cothread_context_free (cothread_context * ctx)
{
gint i;
g_return_if_fail (ctx != NULL);
g_assert (ctx->thread == g_thread_self ());
g_assert (ctx->current == 0);
GST_CAT_INFO (GST_CAT_COTHREADS, "free cothread context");
for (i = 1; i < COTHREAD_MAXTHREADS; i++) {
if (ctx->cothreads[i]) {
cothread_destroy (ctx->cothreads[i]);
}
}
if (ctx->cothreads[0]) {
g_free (ctx->cothreads[0]);
ctx->cothreads[0] = NULL;
}
g_hash_table_destroy (ctx->data);
/* make sure we free the private key for cothread context */
GST_CAT_INFO (GST_CAT_COTHREADS,
"setting private _cothread_ctx_key to NULL in thread %p",
g_thread_self ());
g_static_private_set (&_cothread_ctx_key, NULL, NULL);
g_free (ctx);
}
/**
* cothread_create:
* @ctx: the cothread context
*
* Create a new cothread state in the given context
*
* Returns: the new cothread state or NULL on error
*/
cothread_state *
cothread_create (cothread_context * ctx)
{
cothread_state *cothread;
void *mmaped = NULL;
gint slot = 0;
unsigned long page_size;
g_return_val_if_fail (ctx != NULL, NULL);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "manager sef %p, cothread self %p",
ctx->thread, g_thread_self ());
if (ctx->ncothreads == COTHREAD_MAXTHREADS) {
/* this is pretty fatal */
g_warning ("cothread_create: attempt to create > COTHREAD_MAXTHREADS");
return NULL;
}
/* find a free spot in the stack, note slot 0 has the main thread */
for (slot = 1; slot < ctx->ncothreads; slot++) {
if (ctx->cothreads[slot] == NULL)
break;
else if (ctx->cothreads[slot]->flags & COTHREAD_DESTROYED &&
slot != ctx->current) {
cothread_destroy (ctx->cothreads[slot]);
break;
}
}
GST_CAT_DEBUG (GST_CAT_COTHREADS, "Found free cothread slot %d", slot);
/* cothread stack space of the thread is mapped in reverse, with cothread 0
* stack space at the top */
cothread =
(cothread_state *) (ctx->stack_top - (slot + 1) * COTHREAD_STACKSIZE);
GST_CAT_DEBUG (GST_CAT_COTHREADS, "cothread pointer is %p", cothread);
#if 0
/* This tests to see whether or not we can grow down the stack */
{
unsigned long ptr;
for (ptr = ctx->stack_top - 4096; ptr > (unsigned long) cothread;
ptr -= 4096) {
GST_CAT_DEBUG (GST_CAT_COTHREADS, "touching location 0x%08lx", ptr);
*(volatile unsigned int *) ptr = *(volatile unsigned int *) ptr;
GST_CAT_DEBUG (GST_CAT_COTHREADS, "ok (0x%08x)", *(unsigned int *) ptr);
}
}
#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_CAT_DEBUG (GST_CAT_COTHREADS, "mmaping %p, size 0x%08x", 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_CAT_DEBUG (GST_CAT_COTHREADS, "coming out of mmap");
if (mmaped == MAP_FAILED) {
perror ("mmap'ing cothread stack space");
return NULL;
}
if (mmaped != (void *) cothread + page_size * 2) {
g_warning ("could not mmap requested memory for cothread");