merged schedulers

Original commit message from CVS:
merged schedulers
- new file cothreads_compat.h to provide linking to desired cothreads package
- changes in basic and fast scheduler to use cothreads_compat.h
- updated Makefile to build the basic and the fast scheduler from both packages
- removed gststandardscheduler.c - it is not needed anymore

Available schedulers are now 'basic', 'standard', 'fastbasic' and 'faststandard' where the basic ones are built with old cothreads and the standard ones with the new cothreads.
This commit is contained in:
Benjamin Otte 2002-05-06 19:23:37 +00:00
parent 2b12a668da
commit 72dd13b5bd
6 changed files with 224 additions and 1386 deletions

2
common

@ -1 +1 @@
Subproject commit e5997d9e2b4e162ad423f9b9ec3ac9b29e12bb05
Subproject commit 8d060610bbe0af2f159b40c8b23076896b4104a5

View file

@ -1,21 +1,26 @@
plugindir = $(libdir)/gst
plugin_LTLIBRARIES = libgstbasicscheduler.la libgststandardscheduler.la libgstfastscheduler.la
plugin_LTLIBRARIES = libgstbasicscheduler.la libgststandardscheduler.la libgstfastbasicscheduler.la libgstfaststandardscheduler.la
libgstbasicscheduler_la_SOURCES = gstbasicscheduler.c
libgstbasicscheduler_la_CFLAGS = $(GST_CFLAGS)
libgstbasicscheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_BASIC
libgstbasicscheduler_la_LIBADD = ../libcothreads.la
libgstbasicscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgststandardscheduler_la_SOURCES = gststandardscheduler.c
libgststandardscheduler_la_CFLAGS = $(GST_CFLAGS) -I$(top_srcdir)/libs/ext/cothreads
libgststandardscheduler_la_SOURCES = gstbasicscheduler.c
libgststandardscheduler_la_CFLAGS = $(GST_CFLAGS) -I$(top_srcdir)/libs/ext/cothreads -D_COTHREADS_STANDARD
libgststandardscheduler_la_LIBADD = $(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la
libgststandardscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstfastscheduler_la_SOURCES = gstfastscheduler.c
libgstfastscheduler_la_CFLAGS = $(GST_CFLAGS)
libgstfastscheduler_la_LIBADD = ../libcothreads.la
libgstfastscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstfastbasicscheduler_la_SOURCES = gstfastscheduler.c
libgstfastbasicscheduler_la_CFLAGS = $(GST_CFLAGS) -D_COTHREADS_BASIC
libgstfastbasicscheduler_la_LIBADD = ../libcothreads.la
libgstfastbasicscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstfaststandardscheduler_la_SOURCES = gstfastscheduler.c
libgstfaststandardscheduler_la_CFLAGS = $(GST_CFLAGS) -I$(top_srcdir)/libs/ext/cothreads -D_COTHREADS_STANDARD
libgstfaststandardscheduler_la_LIBADD = $(top_builddir)/libs/ext/cothreads/cothreads/libcothreads-gthreads.la
libgstfaststandardscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
## this is a REALLY evil hack
## but we need to keep it as long as we have libs/gst and libs/ext

View file

@ -0,0 +1,133 @@
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
* gstscheduler.c: Default scheduling code for most cases
*
* 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.
*/
/* use the old cothreads implementation in gst/cothreads.[ch] */
#if defined(_COTHREADS_BASIC)
#include "../cothreads.h"
/* the name of this cothreads type */
#define COTHREADS_NAME "basic"
#define COTHREADS_NAME_CAPITAL "Basic"
/* unify the structs
*
* "cothread" and "cothread_context" need to vbe defined
*/
typedef cothread_state cothread;
/* define functions
* the macros are prepended with "do_"
*/
#define do_cothreads_init(x) /* NOP */
#define do_cothread_switch(to) cothread_switch(to)
#define do_cothread_create(new_thread, context, func, argc, argv) \
G_STMT_START{ \
new_thread = cothread_create (context); \
if (new_thread) { \
cothread_setfunc (new_thread, (func), (argc), (argv)); \
}\
}G_STMT_END
#define do_cothread_reset(cothread, context, func, argc, argv) \
cothread_setfunc ((cothread), (func), (argc), (argv))
#define do_cothread_destroy(cothread) cothread_free(cothread)
#define do_cothread_context_init() (cothread_context_init ())
#define do_cothread_context_destroy(context) cothread_context_free (context)
#define do_cothread_lock(cothread) cothread_lock(cothread)
#define do_cothread_unlock(cothread) cothread_unlock(cothread)
#define do_cothread_get_current() (cothread_current())
#define do_cothread_get_main(context) (cothread_current_main())
/* use the new cothreads implementation in libs/ext/cothreads */
#elif defined(_COTHREADS_STANDARD)
#include <cothreads/cothreads.h>
#include <errno.h>
/* the name of this cothreads */
#define COTHREADS_NAME "standard"
#define COTHREADS_NAME_CAPITAL "Standard"
/* unify the structs
*
* "cothread" and "cothread_context" need to vbe defined
*/
typedef cothread cothread_context;
/* define functions
* the macros are prepended with "do_"
*/
#define do_cothreads_init(x) G_STMT_START{ \
if (!cothreads_initialized()) \
cothreads_init(x); \
}G_STMT_END
#define do_cothread_switch(to) G_STMT_START{ \
cothread *from = cothread_self (); \
if (from == (to)) { \
GST_DEBUG (GST_CAT_COTHREAD_SWITCH, "trying to switch to the same cothread (%p), not allowed", \
(to)); \
g_warning ("trying to switch to the same cothread, not allowed"); \
} else { \
GST_INFO (GST_CAT_COTHREAD_SWITCH, "switching from cothread %p to cothread %p", \
from, (to)); \
cothread_switch (from, (to)); \
GST_INFO (GST_CAT_COTHREAD_SWITCH, "we're in cothread %p now", from); \
} \
}G_STMT_END
#define do_cothread_create(new_thread, context, func, argc, argv) \
G_STMT_START{ \
new_thread = cothread_create ((func), 0, (void**) (argv), (context)); \
}G_STMT_END
#define do_cothread_reset(cothread, context, func, argc, argv) \
cothread_reset ((cothread), (func), (argc), (void **) (argv), (context))
#define do_cothread_destroy(cothread) cothread_destroy(cothread)
#define do_cothread_context_init() (cothread_create (NULL, 0, NULL, NULL))
#define do_cothread_context_destroy(context) cothread_destroy (context)
#define do_cothread_lock(cothread) /* FIXME */
#define do_cothread_unlock(cothread) /* FIXME */
#define do_cothread_get_current() (cothread_self())
#define do_cothread_get_main(context) (context)
/* bail out with an error if no cothreads package is defined */
#else
#error "No cothreads package defined"
#endif

View file

@ -22,13 +22,13 @@
/*#define GST_DEBUG_ENABLED */
#include <gst/gst.h>
#include <../cothreads.h>
#include "cothreads_compat.h"
typedef struct _GstSchedulerChain GstSchedulerChain;
#define GST_PAD_THREADSTATE(pad) (cothread_state*) (GST_PAD_CAST (pad)->sched_private)
#define GST_ELEMENT_THREADSTATE(elem) (cothread_state*) (GST_ELEMENT_CAST (elem)->sched_private)
#define GST_BIN_THREADCONTEXT(bin) (cothread_context*) (GST_BIN_CAST (bin)->sched_private)
#define GST_PAD_THREADSTATE(pad) (cothread*) (GST_PAD_CAST (pad)->sched_private)
#define GST_ELEMENT_THREADSTATE(elem) (cothread*) (GST_ELEMENT_CAST (elem)->sched_private)
#define GST_ELEMENT_COTHREAD_STOPPING GST_ELEMENT_SCHEDULER_PRIVATE1
#define GST_ELEMENT_IS_COTHREAD_STOPPING(element) GST_FLAG_IS_SET((element), GST_ELEMENT_COTHREAD_STOPPING)
@ -85,6 +85,8 @@ struct _GstBasicScheduler {
gint num_chains;
GstBasicSchedulerState state;
cothread_context *context;
};
struct _GstBasicSchedulerClass {
@ -138,7 +140,7 @@ gst_basic_scheduler_get_type (void)
NULL
};
_gst_basic_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, "GstBasicScheduler", &scheduler_info, 0);
_gst_basic_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, "Gst"COTHREADS_NAME_CAPITAL"Scheduler", &scheduler_info, 0);
}
return _gst_basic_scheduler_type;
}
@ -175,6 +177,8 @@ gst_basic_scheduler_class_init (GstBasicSchedulerClass * klass)
gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_basic_scheduler_iterate);
gstscheduler_class->show = GST_DEBUG_FUNCPTR (gst_basic_scheduler_show);
do_cothreads_init(NULL);
}
static void
@ -199,15 +203,15 @@ plugin_init (GModule *module, GstPlugin *plugin)
gst_plugin_set_longname (plugin, "A basic scheduler");
factory = gst_scheduler_factory_new ("basic",
"A basic scheduler, it uses cothreads",
factory = gst_scheduler_factory_new (COTHREADS_NAME,
"A basic scheduler, it uses "COTHREADS_NAME" cothreads",
gst_basic_scheduler_get_type());
if (factory != NULL) {
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
}
else {
g_warning ("could not register scheduler: basic");
g_warning ("could not register scheduler: "COTHREADS_NAME);
}
return TRUE;
}
@ -215,7 +219,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstbasicscheduler",
"gst"COTHREADS_NAME"scheduler",
plugin_init
};
@ -363,7 +367,7 @@ gst_basic_scheduler_chainhandler_proxy (GstPad * pad, GstBuffer * buf)
while (GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) != NULL && --loop_count) {
GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to empty bufpen %d",
GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)), loop_count);
cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
do_cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
/* we may no longer be the same pad, check. */
if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
@ -382,7 +386,7 @@ gst_basic_scheduler_chainhandler_proxy (GstPad * pad, GstBuffer * buf)
GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) = buf;
GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p",
GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
do_cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
GST_DEBUG (GST_CAT_DATAFLOW, "done switching");
}
@ -401,7 +405,7 @@ gst_basic_scheduler_select_proxy (GstPad * pad, GstBuffer * buf)
GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad = pad;
cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
do_cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
GST_DEBUG (GST_CAT_DATAFLOW, "done switching");
}
@ -421,7 +425,7 @@ gst_basic_scheduler_gethandler_proxy (GstPad * pad)
GST_DEBUG (GST_CAT_DATAFLOW, "switching to \"%s\": %p to fill bufpen",
GST_ELEMENT_NAME (GST_ELEMENT (GST_PAD_PARENT (pad))),
GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
do_cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
/* we may no longer be the same pad, check. */
if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
@ -459,7 +463,7 @@ gst_basic_scheduler_pullregionfunc_proxy (GstPad * pad, GstRegionType type, guin
while (GST_RPAD_BUFPEN (pad) == NULL) {
GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to fill bufpen",
GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
do_cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)));
/* we may no longer be the same pad, check. */
if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
@ -487,7 +491,7 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain)
GST_DEBUG (GST_CAT_SCHEDULING, "chain is using COTHREADS");
g_assert (GST_BIN_THREADCONTEXT (bin) != NULL);
g_assert (chain->sched->context != NULL);
/* walk through all the chain's elements */
elements = chain->elements;
@ -583,8 +587,8 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain)
/* need to set up the cothread now */
if (wrapper_function != NULL) {
if (GST_ELEMENT_THREADSTATE (element) == NULL) {
GST_ELEMENT_THREADSTATE (element) = cothread_create (GST_BIN_THREADCONTEXT (bin));
cothread_set_private (GST_ELEMENT_THREADSTATE (element), element);
do_cothread_create (GST_ELEMENT_THREADSTATE (element), chain->sched->context,
wrapper_function, 0, (char **) element);
if (GST_ELEMENT_THREADSTATE (element) == NULL) {
gst_element_error (element, "could not create cothread for \"%s\"",
GST_ELEMENT_NAME (element), NULL);
@ -593,10 +597,12 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain)
GST_DEBUG (GST_CAT_SCHEDULING, "created cothread %p for '%s'",
GST_ELEMENT_THREADSTATE (element),
GST_ELEMENT_NAME (element));
} else {
do_cothread_reset (GST_ELEMENT_THREADSTATE (element), chain->sched->context,
wrapper_function, 0, (char **) element);
GST_DEBUG (GST_CAT_SCHEDULING, "set wrapper function for '%s' to &%s",
GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function));
}
cothread_setfunc (GST_ELEMENT_THREADSTATE (element), wrapper_function, 0, (char **) element);
GST_DEBUG (GST_CAT_SCHEDULING, "set wrapper function for '%s' to &%s",
GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function));
}
}
@ -722,7 +728,7 @@ gst_basic_scheduler_chain_remove_element (GstSchedulerChain * chain, GstElement
}
/* we have to check for a threadstate here because a queue doesn't have one */
if (GST_ELEMENT_THREADSTATE (element)) {
cothread_free (GST_ELEMENT_THREADSTATE (element));
do_cothread_destroy (GST_ELEMENT_THREADSTATE (element));
GST_ELEMENT_THREADSTATE (element) = NULL;
}
@ -875,12 +881,11 @@ gst_basic_scheduler_chain_recursive_add (GstSchedulerChain * chain, GstElement *
static void
gst_basic_scheduler_setup (GstScheduler *sched)
{
GstBin *bin = GST_BIN (sched->parent);
/* first create thread context */
if (GST_BIN_THREADCONTEXT (bin) == NULL) {
if (GST_BASIC_SCHEDULER_CAST (sched)->context == NULL) {
GST_DEBUG (GST_CAT_SCHEDULING, "initializing cothread context");
GST_BIN_THREADCONTEXT (bin) = cothread_context_init ();
GST_BASIC_SCHEDULER_CAST (sched)->context = do_cothread_context_init ();
}
}
@ -891,15 +896,16 @@ gst_basic_scheduler_reset (GstScheduler *sched)
GList *elements = GST_BASIC_SCHEDULER_CAST (sched)->elements;
while (elements) {
/* FIXME: wingo, do we need to destroy the cothreads here? */
GST_ELEMENT_THREADSTATE (elements->data) = NULL;
elements = g_list_next (elements);
}
ctx = GST_BIN_THREADCONTEXT (GST_SCHEDULER_PARENT (sched));
ctx = GST_BASIC_SCHEDULER_CAST (sched)->context;
cothread_context_free (ctx);
do_cothread_context_destroy (ctx);
GST_BIN_THREADCONTEXT (GST_SCHEDULER_PARENT (sched)) = NULL;
GST_BASIC_SCHEDULER_CAST (sched)->context = NULL;
}
static void
@ -1040,21 +1046,21 @@ static void
gst_basic_scheduler_lock_element (GstScheduler * sched, GstElement * element)
{
if (GST_ELEMENT_THREADSTATE (element))
cothread_lock (GST_ELEMENT_THREADSTATE (element));
do_cothread_lock (GST_ELEMENT_THREADSTATE (element));
}
static void
gst_basic_scheduler_unlock_element (GstScheduler * sched, GstElement * element)
{
if (GST_ELEMENT_THREADSTATE (element))
cothread_unlock (GST_ELEMENT_THREADSTATE (element));
do_cothread_unlock (GST_ELEMENT_THREADSTATE (element));
}
static void
gst_basic_scheduler_yield (GstScheduler *sched, GstElement *element)
{
if (GST_ELEMENT_IS_COTHREAD_STOPPING (element)) {
cothread_switch (cothread_current_main ());
do_cothread_switch (do_cothread_get_main (((GstBasicScheduler *) sched)->context));
}
}
@ -1062,7 +1068,7 @@ static gboolean
gst_basic_scheduler_interrupt (GstScheduler *sched, GstElement *element)
{
GST_FLAG_SET (element, GST_ELEMENT_COTHREAD_STOPPING);
cothread_switch (cothread_current_main ());
do_cothread_switch (do_cothread_get_main (((GstBasicScheduler *) sched)->context));
return FALSE;
}
@ -1081,7 +1087,7 @@ gst_basic_scheduler_error (GstScheduler *sched, GstElement *element)
GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_ERROR;
cothread_switch (cothread_current_main ());
do_cothread_switch (do_cothread_get_main (((GstBasicScheduler *) sched)->context));
}
}
@ -1182,7 +1188,7 @@ gst_basic_scheduler_pad_select (GstScheduler * sched, GList * padlist)
if (pad != NULL) {
GstRealPad *peer = GST_RPAD_PEER (pad);
cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (peer)));
do_cothread_switch (GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (peer)));
pad = GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad;
@ -1256,7 +1262,7 @@ gst_basic_scheduler_iterate (GstScheduler * sched)
GST_DEBUG (GST_CAT_DATAFLOW, "set COTHREAD_STOPPING flag on \"%s\"(@%p)",
GST_ELEMENT_NAME (entry), entry);
if (GST_ELEMENT_THREADSTATE (entry)) {
cothread_switch (GST_ELEMENT_THREADSTATE (entry));
do_cothread_switch (GST_ELEMENT_THREADSTATE (entry));
/* if something changed, return - go on else */
if (GST_FLAG_IS_SET(bsched, GST_BASIC_SCHEDULER_CHANGE))
return GST_SCHEDULER_STATE_RUNNING;

View file

@ -22,13 +22,13 @@
/*#define GST_DEBUG_ENABLED */
#include <gst/gst.h>
#include <../cothreads.h>
#include "cothreads_compat.h"
typedef struct _GstSchedulerChain GstSchedulerChain;
#define GST_PAD_THREADSTATE(pad) (cothread_state*) (GST_PAD_CAST (pad)->sched_private)
#define GST_ELEMENT_THREADSTATE(elem) (cothread_state*) (GST_ELEMENT_CAST (elem)->sched_private)
#define GST_BIN_THREADCONTEXT(bin) (cothread_context*) (GST_BIN_CAST (bin)->sched_private)
#define GST_PAD_THREADSTATE(pad) (cothread*) (GST_PAD_CAST (pad)->sched_private)
#define GST_ELEMENT_THREADSTATE(elem) (cothread*) (GST_ELEMENT_CAST (elem)->sched_private)
#define GST_ELEMENT_COTHREAD_STOPPING GST_ELEMENT_SCHEDULER_PRIVATE1
#define GST_ELEMENT_IS_COTHREAD_STOPPING(element) GST_FLAG_IS_SET((element), GST_ELEMENT_COTHREAD_STOPPING)
@ -85,6 +85,7 @@ struct _GstFastScheduler {
GstFastSchedulerState state;
cothread_context *context;
};
struct _GstFastSchedulerClass {
@ -136,7 +137,7 @@ gst_fast_scheduler_get_type (void)
NULL
};
_gst_fast_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, "GstFastScheduler", &scheduler_info, 0);
_gst_fast_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, "GstFast"COTHREADS_NAME_CAPITAL"Scheduler", &scheduler_info, 0);
}
return _gst_fast_scheduler_type;
}
@ -170,6 +171,8 @@ gst_fast_scheduler_class_init (GstFastSchedulerClass * klass)
gstscheduler_class->pad_disconnect = GST_DEBUG_FUNCPTR (gst_fast_scheduler_pad_disconnect);
gstscheduler_class->pad_select = GST_DEBUG_FUNCPTR (gst_fast_scheduler_pad_select);
gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_fast_scheduler_iterate);
do_cothreads_init(NULL);
}
static void
@ -194,8 +197,8 @@ plugin_init (GModule *module, GstPlugin *plugin)
gst_plugin_set_longname (plugin, "A fast scheduler");
factory = gst_scheduler_factory_new ("fast",
"A fast scheduler, it uses cothreads",
factory = gst_scheduler_factory_new ("fast"COTHREADS_NAME,
"A fast scheduler, it uses "COTHREADS_NAME" cothreads",
gst_fast_scheduler_get_type());
if (factory != NULL) {
@ -210,7 +213,7 @@ plugin_init (GModule *module, GstPlugin *plugin)
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"gstfastscheduler",
"gstfast"COTHREADS_NAME_CAPITAL"scheduler",
plugin_init
};
@ -246,7 +249,7 @@ gst_fast_scheduler_chainfunc_proxy (GstPad *pad, GstBuffer *buffer)
while (GST_RPAD_BUFPEN (pad) != NULL) {
if (GST_ELEMENT_THREADSTATE (element)) {
cothread_switch (GST_ELEMENT_THREADSTATE (element));
do_cothread_switch (GST_ELEMENT_THREADSTATE (element));
}
else {
g_assert_not_reached();
@ -266,7 +269,7 @@ gst_fast_scheduler_getfunc_proxy (GstPad *pad)
while (GST_RPAD_BUFPEN (peer) == NULL) {
if (GST_ELEMENT_THREADSTATE (element)) {
cothread_switch (GST_ELEMENT_THREADSTATE (element));
do_cothread_switch (GST_ELEMENT_THREADSTATE (element));
}
else {
g_assert_not_reached();
@ -285,24 +288,27 @@ gst_fast_scheduler_cothreaded_element (GstBin * bin, GstElement *element)
{
cothread_func wrapper_function;
GList *pads;
GstFastScheduler *sched;
GST_DEBUG (GST_CAT_SCHEDULING, "element is using COTHREADS\n");
g_assert (GST_BIN_THREADCONTEXT (bin) != NULL);
sched = (GstFastScheduler *) GST_ELEMENT_SCHED (bin);
g_assert (GST_IS_FAST_SCHEDULER (sched));
wrapper_function = GST_DEBUG_FUNCPTR (gst_fast_scheduler_loopfunc_wrapper);
if (GST_ELEMENT_THREADSTATE (element) == NULL) {
GST_ELEMENT_THREADSTATE (element) = cothread_create (GST_BIN_THREADCONTEXT (bin));
do_cothread_create (GST_ELEMENT_THREADSTATE (element), sched->context, wrapper_function, 0, (char **) element);
if (GST_ELEMENT_THREADSTATE (element) == NULL) {
gst_element_error (element, "could not create cothread for \"%s\"",
GST_ELEMENT_NAME (element), NULL);
return FALSE;
}
GST_DEBUG (GST_CAT_SCHEDULING, "created cothread %p for '%s'\n",
GST_DEBUG (GST_CAT_SCHEDULING, "created cothread %p for '%s' with wrapper function &%s\n",
GST_ELEMENT_THREADSTATE (element),
GST_ELEMENT_NAME (element));
cothread_setfunc (GST_ELEMENT_THREADSTATE (element), wrapper_function, 0, (char **) element);
GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function));
}
} else {
do_cothread_reset (GST_ELEMENT_THREADSTATE (element), sched->context, wrapper_function, 0, (char **) element);
GST_DEBUG (GST_CAT_SCHEDULING, "set wrapper function for '%s' to &%s\n",
GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function));
}
@ -478,7 +484,7 @@ gst_fast_scheduler_chain_remove_element (GstSchedulerChain * chain, GstElement *
}
/* we have to check for a threadstate here because a queue doesn't have one */
if (GST_ELEMENT_THREADSTATE (element)) {
cothread_free (GST_ELEMENT_THREADSTATE (element));
do_cothread_destroy (GST_ELEMENT_THREADSTATE (element));
GST_ELEMENT_THREADSTATE (element) = NULL;
}
@ -622,31 +628,29 @@ gst_fast_scheduler_chain_recursive_add (GstSchedulerChain * chain, GstElement *
static void
gst_fast_scheduler_setup (GstScheduler *sched)
{
GstBin *bin = GST_BIN (sched->parent);
GstFastScheduler *fast = GST_FAST_SCHEDULER_CAST (sched);
/* first create thread context */
if (GST_BIN_THREADCONTEXT (bin) == NULL) {
if (fast->context == NULL) {
GST_DEBUG (GST_CAT_SCHEDULING, "initializing cothread context\n");
GST_BIN_THREADCONTEXT (bin) = cothread_context_init ();
fast->context = do_cothread_context_init ();
}
}
static void
gst_fast_scheduler_reset (GstScheduler *sched)
{
cothread_context *ctx;
GList *elements = GST_FAST_SCHEDULER_CAST (sched)->elements;
GstFastScheduler *fast = GST_FAST_SCHEDULER_CAST (sched);
GList *elements = fast->elements;
while (elements) {
GST_ELEMENT_THREADSTATE (elements->data) = NULL;
elements = g_list_next (elements);
}
ctx = GST_BIN_THREADCONTEXT (GST_SCHEDULER_PARENT (sched));
cothread_context_free (ctx);
do_cothread_context_destroy (fast->context);
GST_BIN_THREADCONTEXT (GST_SCHEDULER_PARENT (sched)) = NULL;
fast->context = NULL;
}
static void
@ -785,29 +789,29 @@ static void
gst_fast_scheduler_lock_element (GstScheduler * sched, GstElement * element)
{
if (GST_ELEMENT_THREADSTATE (element))
cothread_lock (GST_ELEMENT_THREADSTATE (element));
do_cothread_lock (GST_ELEMENT_THREADSTATE (element));
}
static void
gst_fast_scheduler_unlock_element (GstScheduler * sched, GstElement * element)
{
if (GST_ELEMENT_THREADSTATE (element))
cothread_unlock (GST_ELEMENT_THREADSTATE (element));
do_cothread_unlock (GST_ELEMENT_THREADSTATE (element));
}
static void
gst_fast_scheduler_yield (GstScheduler *sched, GstElement *element)
{
if (GST_ELEMENT_IS_COTHREAD_STOPPING (element)) {
cothread_switch (cothread_current_main ());
do_cothread_switch (do_cothread_get_main (GST_FAST_SCHEDULER_CAST (sched)->context));
}
}
static gboolean
gst_fast_scheduler_interrupt (GstScheduler *sched, GstElement *element)
{
if (cothread_current () != cothread_current_main()) {
cothread_switch (cothread_current_main ());
if (do_cothread_get_current () != do_cothread_get_main (GST_FAST_SCHEDULER_CAST (sched)->context)) {
do_cothread_switch (do_cothread_get_main (GST_FAST_SCHEDULER_CAST (sched)->context));
return FALSE;
}
GST_FLAG_SET (element, GST_ELEMENT_INTERRUPTED);
@ -958,7 +962,7 @@ gst_fast_scheduler_iterate (GstScheduler * sched)
GST_ELEMENT_NAME (entry), entry);
if (GST_ELEMENT_THREADSTATE (entry)) {
cothread_switch (GST_ELEMENT_THREADSTATE (entry));
do_cothread_switch (GST_ELEMENT_THREADSTATE (entry));
}
else {
GST_DEBUG (GST_CAT_DATAFLOW, "cothread switch not possible, element has no threadstate\n");

File diff suppressed because it is too large Load diff