summaryrefslogtreecommitdiffstats
path: root/flow/gsl/gslopnode.h
diff options
context:
space:
mode:
Diffstat (limited to 'flow/gsl/gslopnode.h')
-rw-r--r--flow/gsl/gslopnode.h247
1 files changed, 247 insertions, 0 deletions
diff --git a/flow/gsl/gslopnode.h b/flow/gsl/gslopnode.h
new file mode 100644
index 0000000..3e236e5
--- /dev/null
+++ b/flow/gsl/gslopnode.h
@@ -0,0 +1,247 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+#ifndef __GSL_ENGINE_NODE_H__
+#define __GSL_ENGINE_NODE_H__
+
+#include "gslengine.h"
+#include "gsloputil.h"
+#include "gslcommon.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+#define ENGINE_NODE(module) ((EngineNode*) (module))
+#define ENGINE_NODE_N_OSTREAMS(node) ((node)->module.klass->n_ostreams)
+#define ENGINE_NODE_N_ISTREAMS(node) ((node)->module.klass->n_istreams)
+#define ENGINE_NODE_N_JSTREAMS(node) ((node)->module.klass->n_jstreams)
+#define ENGINE_NODE_IS_CONSUMER(node) ((node)->is_consumer && \
+ (node)->output_nodes == NULL)
+#define ENGINE_NODE_IS_DEFERRED(node) (FALSE)
+#define ENGINE_NODE_IS_SCHEDULED(node) (ENGINE_NODE (node)->sched_tag)
+#define ENGINE_NODE_IS_CHEAP(node) (((node)->module.klass->mflags & GSL_COST_CHEAP) != 0)
+#define ENGINE_NODE_IS_EXPENSIVE(node) (((node)->module.klass->mflags & GSL_COST_EXPENSIVE) != 0)
+#define ENGINE_NODE_LOCK(node) gsl_rec_mutex_lock (&(node)->rec_mutex)
+#define ENGINE_NODE_UNLOCK(node) gsl_rec_mutex_unlock (&(node)->rec_mutex)
+
+
+/* --- debugging and messages --- */
+#define ENG_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_ENGINE, NULL)
+#define MAS_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_MASTER, NULL)
+#define JOB_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_JOBS, NULL)
+#define SCHED_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_SCHED, NULL)
+
+
+/* --- transactions --- */
+typedef union _EngineFlowJob EngineFlowJob;
+typedef enum {
+ ENGINE_JOB_NOP,
+ ENGINE_JOB_INTEGRATE,
+ ENGINE_JOB_DISCARD,
+ ENGINE_JOB_ICONNECT,
+ ENGINE_JOB_JCONNECT,
+ ENGINE_JOB_IDISCONNECT,
+ ENGINE_JOB_JDISCONNECT,
+ ENGINE_JOB_SET_CONSUMER,
+ ENGINE_JOB_UNSET_CONSUMER,
+ ENGINE_JOB_ACCESS,
+ ENGINE_JOB_ADD_POLL,
+ ENGINE_JOB_REMOVE_POLL,
+ ENGINE_JOB_FLOW_JOB,
+ ENGINE_JOB_DEBUG,
+ ENGINE_JOB_LAST
+} EngineJobType;
+struct _GslJob
+{
+ EngineJobType job_id;
+ GslJob *next;
+ union {
+ EngineNode *node;
+ struct {
+ EngineNode *dest_node;
+ guint dest_ijstream;
+ EngineNode *src_node;
+ guint src_ostream;
+ } connection;
+ struct {
+ EngineNode *node;
+ GslAccessFunc access_func;
+ gpointer data;
+ GslFreeFunc free_func;
+ } access;
+ struct {
+ GslPollFunc poll_func;
+ gpointer data;
+ GslFreeFunc free_func;
+ guint n_fds;
+ GPollFD *fds;
+ } poll;
+ struct {
+ EngineNode *node;
+ EngineFlowJob *fjob;
+ } flow_job;
+ gchar *debug;
+ } data;
+};
+struct _GslTrans
+{
+ GslJob *jobs_head;
+ GslJob *jobs_tail;
+ guint comitted : 1;
+ GslTrans *cqt_next; /* com-thread-queue */
+};
+typedef enum {
+ ENGINE_FLOW_JOB_NOP,
+ ENGINE_FLOW_JOB_SUSPEND,
+ ENGINE_FLOW_JOB_RESUME,
+ ENGINE_FLOW_JOB_ACCESS,
+ ENGINE_FLOW_JOB_LAST
+} EngineFlowJobType;
+typedef struct
+{
+ EngineFlowJobType fjob_id;
+ EngineFlowJob *next;
+ guint64 tick_stamp;
+} EngineFlowJobAny;
+typedef struct
+{
+ EngineFlowJobType fjob_id;
+ EngineFlowJob *next;
+ guint64 tick_stamp;
+ GslAccessFunc access_func;
+ gpointer data;
+ GslFreeFunc free_func;
+} EngineFlowJobAccess;
+union _EngineFlowJob
+{
+ EngineFlowJobType fjob_id;
+ EngineFlowJobAny any;
+ EngineFlowJobAccess access;
+};
+
+
+/* --- module nodes --- */
+typedef struct
+{
+ EngineNode *src_node;
+ guint src_stream; /* ostream of src_node */
+} EngineInput;
+typedef struct
+{
+ EngineNode *src_node;
+ guint src_stream; /* ostream of src_node */
+} EngineJInput;
+typedef struct
+{
+ gfloat *buffer;
+ guint n_outputs;
+} EngineOutput;
+struct _EngineNode /* fields sorted by order of processing access */
+{
+ GslModule module;
+
+ GslRecMutex rec_mutex; /* processing lock */
+ guint64 counter; /* <= GSL_TICK_STAMP */
+ EngineInput *inputs; /* [ENGINE_NODE_N_ISTREAMS()] */
+ EngineJInput **jinputs; /* [ENGINE_NODE_N_JSTREAMS()] */
+ EngineOutput *outputs; /* [ENGINE_NODE_N_OSTREAMS()] */
+
+ /* flow jobs */
+ EngineFlowJob *flow_jobs; /* active jobs */
+ EngineFlowJob *fjob_first, *fjob_last; /* trash list */
+
+ /* master-node-list */
+ EngineNode *mnl_next;
+ EngineNode *mnl_prev;
+ guint integrated : 1;
+ guint reconnected : 1;
+
+ guint is_consumer : 1;
+
+ /* scheduler */
+ guint sched_tag : 1;
+ guint sched_router_tag : 1;
+ guint sched_leaf_level;
+ EngineNode *toplevel_next; /* master-consumer-list, FIXME: overkill, using a GslRing is good enough */
+ GslRing *output_nodes; /* EngineNode* ring of nodes in ->outputs[] */
+};
+
+static void
+_engine_node_insert_flow_job (EngineNode *node,
+ EngineFlowJob *fjob)
+{
+ EngineFlowJob *last = NULL, *tmp = node->flow_jobs;
+
+ /* find next position */
+ while (tmp && tmp->any.tick_stamp <= fjob->any.tick_stamp)
+ {
+ last = tmp;
+ tmp = last->any.next;
+ }
+ /* insert before */
+ fjob->any.next = tmp;
+ if (last)
+ last->any.next = fjob;
+ else
+ node->flow_jobs = fjob;
+}
+
+static inline EngineFlowJob*
+_engine_node_pop_flow_job (EngineNode *node,
+ guint64 tick_stamp)
+{
+ EngineFlowJob *fjob = node->flow_jobs;
+
+ if_reject (fjob)
+ {
+ if (fjob->any.tick_stamp <= tick_stamp)
+ {
+ node->flow_jobs = fjob->any.next;
+
+ fjob->any.next = node->fjob_first;
+ node->fjob_first = fjob;
+ if (!node->fjob_last)
+ node->fjob_last = node->fjob_first;
+ }
+ else
+ fjob = NULL;
+ }
+
+ return fjob;
+}
+
+static inline guint64
+_engine_node_peek_flow_job_stamp (EngineNode *node)
+{
+ EngineFlowJob *fjob = node->flow_jobs;
+
+ if_reject (fjob)
+ return fjob->any.tick_stamp;
+
+ return GSL_MAX_TICK_STAMP;
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_ENGINE_NODE_H__ */