Index: Makefile.am
===================================================================
RCS file: /home/kde/arts/Makefile.am,v
retrieving revision 1.18
diff -u -b -r1.18 Makefile.am
--- Makefile.am	2002/02/14 01:08:43	1.18
+++ Makefile.am	2002/03/21 17:36:47
@@ -27,7 +27,7 @@
 	cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs 
 
 AUTOMAKE_OPTIONS = foreign 1.4
-COMPILE_FIRST = libltdl mcop mcop_mt mcopidl flow soundserver artsc examples tests doc 
+COMPILE_FIRST = libltdl mcop mcopidl flow mcop_mt soundserver artsc examples tests doc 
 SUBDIRS = $(COMPILE_FIRST) $(TOPSUBDIRS)
 EXTRA_DIST = admin
 
Index: flow/gslschedule.cc
===================================================================
RCS file: /home/kde/arts/flow/gslschedule.cc,v
retrieving revision 1.9
diff -u -b -r1.9 gslschedule.cc
--- flow/gslschedule.cc	2002/03/17 20:51:37	1.9
+++ flow/gslschedule.cc	2002/03/21 17:36:49
@@ -115,6 +115,7 @@
 
 bool GslMainLoop::waitOnTransNeedData = false;
 bool GslMainLoop::gslDataCalculated = false;
+namespace Arts { extern void *gslGlobalMutexTable; }
 
 
 using namespace std;
@@ -643,6 +644,7 @@
 	accessModule();
 	module->streamInit();
 	module->streamStart();
+	flowSystem->startedChanged();
 }
 
 void StdScheduleNode::stop()
@@ -652,6 +654,7 @@
 
 	accessModule();
 	module->streamEnd();
+	flowSystem->startedChanged();
 }
 
 void StdScheduleNode::requireFlow()
@@ -985,13 +988,21 @@
 StdFlowSystem::StdFlowSystem()
 {
 	_suspended = false;
+	needUpdateStarted = false;
 
-	// TODO: correct parameters
+	/* TODO: correct parameters */
+	static bool gsl_is_initialized = false;
+	if(!gsl_is_initialized)
+	{
+		gsl_is_initialized = true;
+
     g_thread_init(0);
-    gsl_init(0);
+		gsl_init(0, (GslMutexTable *)gslGlobalMutexTable);
     gsl_engine_init(false, 512, 44100);
+		if(gslGlobalMutexTable)
+			arts_debug("gsl: using Unix98 pthreads directly for mutexes and conditions");
 	/*gsl_engine_debug_enable(GslEngineDebugLevel(GSL_ENGINE_DEBUG_JOBS | GSL_ENGINE_DEBUG_SCHED));*/
-	//gsl_transact(gsl_job_process_check(gslCheck, 0, 0), 0);
+	}
 	gslMainLoop.initialize();
 }
 
@@ -1177,6 +1188,11 @@
 
 void StdFlowSystem::updateStarted()
 {
+	if(!needUpdateStarted)
+		return;
+
+	needUpdateStarted = false;
+
 	std::list<StdScheduleNode*>::iterator ni;
 	GslTrans *trans = 0;
 
@@ -1192,9 +1208,13 @@
 			node->gslRunning = node->running;
 		}
 	}
-
 	if(trans)
 		gsl_trans_commit(trans);
+}
+
+void StdFlowSystem::startedChanged()
+{
+	needUpdateStarted = true;
 }
 
 void StdFlowSystem::schedule(unsigned long samples)
Index: flow/gslschedule.h
===================================================================
RCS file: /home/kde/arts/flow/gslschedule.h,v
retrieving revision 1.3
diff -u -b -r1.3 gslschedule.h
--- flow/gslschedule.h	2002/03/08 20:30:19	1.3
+++ flow/gslschedule.h	2002/03/21 17:36:49
@@ -282,6 +282,7 @@
 protected:
 	std::list<StdScheduleNode *> nodes;
 	bool _suspended;
+	bool needUpdateStarted;
 public:
 	StdFlowSystem();
 
@@ -310,6 +311,7 @@
 	/* interface to StdScheduleNode */
 	void schedule(unsigned long samples);
 	void updateStarted();
+	void startedChanged();
 };
 
 };
Index: flow/gsl/Makefile.am
===================================================================
RCS file: /home/kde/arts/flow/gsl/Makefile.am,v
retrieving revision 1.13
diff -u -b -r1.13 Makefile.am
--- flow/gsl/Makefile.am	2002/02/21 14:24:45	1.13
+++ flow/gsl/Makefile.am	2002/03/21 17:36:49
@@ -1,5 +1,5 @@
 
-EXTRA_DIST = $(GSL_PRIVATE_H_SRC) $(GSL_H_SRC)
+EXTRA_DIST =
 
 include gslmakefile.inc
 
@@ -8,7 +8,7 @@
 AM_CFLAGS = -DGSL_WANT_GLIB_WRAPPER -DGSL_WANT_ARTS_THREADS
 AM_CXXFLAGS = -DGSL_WANT_GLIB_WRAPPER -DGSL_WANT_ARTS_THREADS
 
-INCLUDES = -I$(top_srcdir)/flow -I$(top_srcdir)/mcop $(all_includes) 
+INCLUDES = -I$(top_srcdir)/flow -I$(top_builddir)/flow -I$(top_srcdir)/mcop $(all_includes) 
 
 noinst_LTLIBRARIES = libgsl.la
 
Index: flow/gsl/configure.in.in
===================================================================
RCS file: configure.in.in
diff -N configure.in.in
--- /dev/null	Fri Feb  1 11:53:05 2002
+++ configure.in.in	Thu Mar 21 18:36:49 2002
@@ -0,0 +1,129 @@
+dnl Portability defines that help interoperate with classic and modern autoconfs
+ifdef([AC_TR_SH],[
+define([GLIB_TR_SH],[AC_TR_SH([$1])])
+define([GLIB_TR_CPP],[AC_TR_CPP([$1])])
+], [
+define([GLIB_TR_SH],
+       [patsubst(translit([[$1]], [*+], [pp]), [[^a-zA-Z0-9_]], [_])])
+define([GLIB_TR_CPP],
+       [patsubst(translit([[$1]],
+                          [*abcdefghijklmnopqrstuvwxyz],
+                          [PABCDEFGHIJKLMNOPQRSTUVWXYZ]),
+                 [[^A-Z0-9_]], [_])])
+])
+
+
+dnl GLIB_SIZEOF (INCLUDES, TYPE, ALIAS [, CROSS-SIZE])
+AC_DEFUN(GLIB_SIZEOF,
+[pushdef([glib_Sizeof], GLIB_TR_SH([glib_cv_sizeof_$3]))dnl
+AC_CACHE_CHECK([size of $2], glib_Sizeof,
+[AC_TRY_RUN([#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$1
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof($2));
+  exit(0);
+}],
+  [glib_Sizeof=`cat conftestval`  dnl''
+],
+  [glib_Sizeof=0],
+  ifelse([$4], [], [], [glib_Sizeof=$4]))])
+AC_DEFINE_UNQUOTED(GLIB_TR_CPP(glib_sizeof_$3), [$[]glib_Sizeof], [Size of $3])
+popdef([glib_Sizeof])dnl
+])
+
+AC_DEFUN(AC_GSL_REQUIREMENTS,
+[
+    dnl === Ogg/Vorbis check ===
+    ov_headers=0
+    AC_CHECK_LIB(vorbisfile, ov_read_float,
+      [AC_CHECK_HEADER(ogg/ogg.h, ov_headers=`expr $ov_headers + 1`)]
+      [AC_CHECK_HEADER(vorbis/vorbisfile.h, ov_headers=`expr $ov_headers + 1`)]
+      [AC_CHECK_HEADER(vorbis/vorbisenc.h, ov_headers=`expr $ov_headers + 1`)]
+      ,
+      ov_headers=0, -lvorbisenc -lvorbis -logg)
+    if test $ov_headers = 3 ; then
+      GSL_LIBS="$GSL_LIBS -lvorbisfile -lvorbisenc -lvorbis -logg"
+    else
+      :
+	  dnl AC_MSG_WARN([failed to detect Ogg/Vorbis library (>=1.0rc3) or headers])
+    fi
+
+    dnl === libmad MPEG decoder check ===
+    mad_detect=0
+    AC_CHECK_LIB(mad, mad_synth_frame,
+      [AC_CHECK_HEADER(mad.h, mad_detect=1)]
+      ,
+      mad_detect=0, -lmad)
+    if test $mad_detect = 1 ; then
+      GSL_LIBS="$GSL_LIBS -lmad"
+      GSL_HAVE_LIBMAD=1
+    else
+      dnl AC_MSG_WARN([failed to detect libmad (MPEG I-III audio decoder) or headers])
+      GSL_HAVE_LIBMAD=0
+    fi
+    AC_SUBST(GSL_HAVE_LIBMAD)
+
+    dnl === Check library requirements ===
+    AC_MSG_CHECKING([the required GSL-Loader library set])
+    if true; then dnl echo $GSL_LIBS | grep ".*-lvorbis.*" >/dev/null ; then
+      AC_MSG_RESULT([complete])
+    else
+      AC_MSG_RESULT([])
+      AC_MSG_ERROR([Ogg/Vorbis is missing, but required])
+    fi
+    AC_SUBST(GSL_LIBS)
+
+    dnl === sizeof types ===
+    GLIB_SIZEOF([#include <pthread.h>], pthread_mutex_t, pth_mutex_t)
+    GSL_SIZEOF_PTH_MUTEX_T="$glib_cv_sizeof_pth_mutex_t"
+    AC_SUBST(GSL_SIZEOF_PTH_MUTEX_T)
+    GLIB_SIZEOF([#include <pthread.h>], pthread_cond_t, pth_cond_t)
+    GSL_SIZEOF_PTH_COND_T="$glib_cv_sizeof_pth_cond_t"
+    AC_SUBST(GSL_SIZEOF_PTH_COND_T)
+    GLIB_SIZEOF([#include <inttypes.h>], intmax_t, std_intmax_t)
+    GSL_SIZEOF_STD_INTMAX_T="$glib_cv_sizeof_std_intmax_t"
+    AC_SUBST(GSL_SIZEOF_STD_INTMAX_T)
+
+    dnl === pthread_mutexattr_settype ===
+    AC_MSG_CHECKING([for pthread_mutexattr_settype()])
+    AC_TRY_COMPILE([
+      #define _XOPEN_SOURCE   600
+      #include <pthread.h>
+    ], [
+      int (*attr_settype) (pthread_mutexattr_t *__attr, int __kind) = pthread_mutexattr_settype;
+      int val = PTHREAD_MUTEX_RECURSIVE;
+      attr_settype = 0; val = 0;
+    ],
+      GSL_HAVE_MUTEXATTR_SETTYPE=1
+      AC_MSG_RESULT(yes)
+    ,
+      GSL_HAVE_MUTEXATTR_SETTYPE=0
+      AC_MSG_RESULT(no)
+    )
+    AC_SUBST(GSL_HAVE_MUTEXATTR_SETTYPE)
+])
+
+AC_DEFUN(AC_GSL_GLIB_REQUIREMENTS,
+[
+	AC_CHECK_FUNCS(getcwd)
+	AC_FUNC_ALLOCA
+
+	if test "x${ac_cv_working_alloca_h+set}" = xset ; then
+		glib_header_alloca_h="$ac_cv_working_alloca_h"
+	else
+		glib_header_alloca_h="$ac_cv_header_alloca_h"
+	fi
+    if test "x$glib_header_alloca_h" = "xyes"; then
+		AC_DEFINE(GLIB_HAVE_ALLOCA_H, 1, [Define if you have alloca.h])
+    fi
+])
+
+AC_GSL_REQUIREMENTS
+AC_GSL_GLIB_REQUIREMENTS
Index: flow/gsl/gslartsthreads.cc
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslartsthreads.cc,v
retrieving revision 1.9
diff -u -b -r1.9 gslartsthreads.cc
--- flow/gsl/gslartsthreads.cc	2002/02/25 11:02:40	1.9
+++ flow/gsl/gslartsthreads.cc	2002/03/21 17:36:50
@@ -79,6 +79,13 @@
   c->wait(*m);
 }
 
+EXTC void
+gsl_arts_cond_timed_wait (gpointer cond, gpointer mutex, GTimeVal *time)
+{
+  arts_assert(false);
+}
+
+
 class GslArtsThread : public Arts::Thread {
 protected:
   gpointer (*func)(gpointer data);
Index: flow/gsl/gslartsthreads.h
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslartsthreads.h,v
retrieving revision 1.2
diff -u -b -r1.2 gslartsthreads.h
--- flow/gsl/gslartsthreads.h	2002/01/17 19:54:49	1.2
+++ flow/gsl/gslartsthreads.h	2002/03/21 17:36:50
@@ -31,6 +31,7 @@
 #define g_cond_signal		gsl_arts_cond_signal
 #define g_cond_broadcast	gsl_arts_cond_broadcast
 #define g_cond_wait		gsl_arts_cond_wait
+#define g_cond_timed_wait	gsl_arts_cond_timed_wait
 
 #define g_thread_create_full	gsl_arts_thread_create_full
 #define g_thread_self		gsl_arts_thread_self
@@ -52,6 +53,7 @@
 void	  gsl_arts_cond_signal (gpointer cond);
 void	  gsl_arts_cond_broadcast (gpointer cond);
 void	  gsl_arts_cond_wait (gpointer cond, gpointer mutex);
+void	  gsl_arts_cond_timed_wait (gpointer cond, gpointer mutex, GTimeVal *abstime);
 
 GThread* gsl_arts_thread_create_full(gpointer (*func)(gpointer data),
                                   gpointer               data,
Index: flow/gsl/gslcommon.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslcommon.c,v
retrieving revision 1.9
diff -u -b -r1.9 gslcommon.c
--- flow/gsl/gslcommon.c	2002/03/20 21:54:03	1.9
+++ flow/gsl/gslcommon.c	2002/03/21 17:36:51
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <sys/poll.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 
 /* some systems don't have ERESTART (which is what linux returns for system
  * calls on pipes which are being interrupted). most propably just use EINTR,
@@ -418,9 +419,9 @@
   volatile gint abort;
   guint64       awake_stamp;
 } ThreadData;
-static GslMutex    global_thread;
+static GslMutex    global_thread = { 0, };
 static GslRing    *global_thread_list = NULL;
-static GslCond    *global_thread_cond = NULL;
+static GslCond     global_thread_cond = { 0, };
 static GslRing    *awake_tdata_list = NULL;
 static ThreadData *main_thread_tdata = NULL;
 
@@ -444,7 +445,7 @@
 
   GSL_SYNC_LOCK (&global_thread);
   global_thread_list = gsl_ring_prepend (global_thread_list, self);
-  gsl_cond_broadcast (global_thread_cond);
+  gsl_cond_broadcast (&global_thread_cond);
   GSL_SYNC_UNLOCK (&global_thread);
 
   tdata->func (tdata->data);
@@ -453,7 +454,7 @@
   global_thread_list = gsl_ring_remove (global_thread_list, self);
   if (tdata->awake_stamp)
     awake_tdata_list = gsl_ring_remove (awake_tdata_list, tdata);
-  gsl_cond_broadcast (global_thread_cond);
+  gsl_cond_broadcast (&global_thread_cond);
   GSL_SYNC_UNLOCK (&global_thread);
 
   close (tdata->wpipe[0]);
@@ -528,7 +529,7 @@
     {
       GSL_SYNC_LOCK (&global_thread);
       while (!gsl_ring_find (global_thread_list, gthread))
-	gsl_cond_wait (global_thread_cond, &global_thread);
+	gsl_cond_wait (&global_thread_cond, &global_thread);
       GSL_SYNC_UNLOCK (&global_thread);
     }
   else
@@ -628,7 +629,7 @@
   thread_wakeup_I (tdata);
 
   while (gsl_ring_find (global_thread_list, thread))
-    gsl_cond_wait (global_thread_cond, &global_thread);
+    gsl_cond_wait (&global_thread_cond, &global_thread);
   GSL_SYNC_UNLOCK (&global_thread);
 }
 
@@ -845,19 +846,23 @@
 /* --- GslMutex --- */
 static gboolean is_smp_system = FALSE;
 
-void
-gsl_mutex_init (GslMutex *mutex)
+static void
+default_mutex_init (GslMutex *mutex)
 {
   g_return_if_fail (mutex != NULL);
   
   mutex->mutex_pointer = g_mutex_new ();
 }
 
-void
-gsl_mutex_spin_lock (GslMutex *mutex)
+static int
+default_mutex_trylock (GslMutex *mutex)
 {
-  g_return_if_fail (mutex != NULL);
+  return g_mutex_trylock (mutex->mutex_pointer) ? 0 : -1;
+}
 
+static void
+default_mutex_lock (GslMutex *mutex)
+{
   /* spin locks should be held only very short times,
    * so frequently we should succeed here
    */
@@ -887,77 +892,57 @@
       g_mutex_lock (mutex->mutex_pointer);
     }
 }
-
-void
-gsl_mutex_sync_lock (GslMutex *mutex)
-{
-  g_return_if_fail (mutex != NULL);
-
-  /* syncronization locks should either require us to wait
-   * on another thread or are unlocked already.
-   */
-  if (g_mutex_trylock (mutex->mutex_pointer))
-    return;
 
-  /* already locked, share processor */
-#ifdef _POSIX_PRIORITY_SCHEDULING
-  sched_yield ();
-#endif
-
-  /* sharing didn't help, perform lengthy wait in mutex_lock() */
-  g_mutex_lock (mutex->mutex_pointer);
-}
-
-void
-gsl_mutex_unlock (GslMutex *mutex)
+static void
+default_mutex_unlock (GslMutex *mutex)
 {
-  g_return_if_fail (mutex != NULL);
-
   g_mutex_unlock (mutex->mutex_pointer);
 }
 
-void
-gsl_mutex_destroy (GslMutex *mutex)
+static void
+default_mutex_destroy (GslMutex *mutex)
 {
-  g_return_if_fail (mutex != NULL);
-
   g_mutex_free (mutex->mutex_pointer);
   memset (mutex, 0, sizeof (*mutex));
 }
-
 
-/* --- GslRecMutex --- */
-void
-gsl_rec_mutex_init (GslRecMutex *rec_mutex)
+static void
+default_rec_mutex_init (GslRecMutex *rec_mutex)
 {
-  g_return_if_fail (rec_mutex != NULL);
-
   rec_mutex->depth = 0;
   rec_mutex->owner = NULL;
   gsl_mutex_init (&rec_mutex->sync_mutex);
 }
 
-void
-gsl_rec_mutex_destroy (GslRecMutex *rec_mutex)
+static int
+default_rec_mutex_trylock (GslRecMutex *rec_mutex)
 {
-  g_return_if_fail (rec_mutex != NULL);
+  gpointer self = gsl_thread_self ();
 
-  if (rec_mutex->owner || rec_mutex->depth)
+  if (rec_mutex->owner == self)
     {
-      g_warning (G_STRLOC ": recursive mutex not unlocked during destruction");
-      return;
+      g_assert (rec_mutex->depth > 0);  /* paranoid */
+      rec_mutex->depth += 1;
+      return 0;
     }
-  gsl_mutex_destroy (&rec_mutex->sync_mutex);
-  g_assert (rec_mutex->owner == NULL && rec_mutex->depth == 0);
+  else
+    {
+      if (gsl_mutex_trylock (&rec_mutex->sync_mutex))
+	{
+	  g_assert (rec_mutex->owner == NULL && rec_mutex->depth == 0); /* paranoid */
+	  rec_mutex->owner = self;
+	  rec_mutex->depth = 1;
+	  return 0;
+	}
+    }
+  return -1;
 }
 
-void
-gsl_rec_mutex_lock (GslRecMutex *rec_mutex)
+static void
+default_rec_mutex_lock (GslRecMutex *rec_mutex)
 {
   gpointer self = gsl_thread_self ();
 
-  g_return_if_fail (rec_mutex != NULL);
-
   if (rec_mutex->owner == self)
     {
       g_assert (rec_mutex->depth > 0);  /* paranoid */
@@ -972,129 +957,130 @@
     }
 }
 
-void
-gsl_rec_mutex_unlock (GslRecMutex *rec_mutex)
+static void
+default_rec_mutex_unlock (GslRecMutex *rec_mutex)
 {
   gpointer self = gsl_thread_self ();
-
-  g_return_if_fail (rec_mutex != NULL);
 
-  g_assert (rec_mutex->owner == self && rec_mutex->depth > 0);
+  if (rec_mutex->owner == self && rec_mutex->depth > 0)
+    {
   rec_mutex->depth -= 1;
   if (!rec_mutex->depth)
     {
       rec_mutex->owner = NULL;
       GSL_SYNC_UNLOCK (&rec_mutex->sync_mutex);
     }
+    }
+  else
+    g_warning ("unable to unlock recursive mutex with self %p != %p or depth %u < 1",
+	       rec_mutex->owner, self, rec_mutex->depth);
 }
 
-gboolean
-gsl_rec_mutex_test_self (GslRecMutex *rec_mutex)
+static void
+default_rec_mutex_destroy (GslRecMutex *rec_mutex)
 {
-  gpointer self = gsl_thread_self ();
-
-  g_return_val_if_fail (rec_mutex != NULL, FALSE);
+  if (rec_mutex->owner || rec_mutex->depth)
+    {
+      g_warning (G_STRLOC ": recursive mutex still locked during destruction");
+      return;
+    }
+  gsl_mutex_destroy (&rec_mutex->sync_mutex);
+  g_assert (rec_mutex->owner == NULL && rec_mutex->depth == 0);
+}
 
-  return rec_mutex->owner == self && rec_mutex->depth > 0;
+static void
+default_cond_init (GslCond *cond)
+{
+  cond->cond_pointer = g_cond_new ();
 }
 
+static void
+default_cond_wait (GslCond  *cond,
+		   GslMutex *mutex)
+{
+  /* infinite wait */
+  g_cond_wait (cond->cond_pointer, mutex->mutex_pointer);
+}
 
-/* --- GslCond --- */
-GslCond*
-gsl_cond_new (void)
+static void
+default_cond_signal (GslCond *cond)
 {
-  gpointer gcond = g_cond_new ();
+  g_cond_signal (cond->cond_pointer);
+}
 
-  return gcond;
+static void
+default_cond_broadcast (GslCond *cond)
+{
+  g_cond_broadcast (cond->cond_pointer);
 }
 
-void
-gsl_cond_destroy (GslCond *cond)
+static void
+default_cond_destroy (GslCond *cond)
 {
-  gpointer gcond = cond;
+  g_cond_free (cond->cond_pointer);
+}
 
-  g_return_if_fail (cond != NULL);
+static void
+default_cond_wait_timed (GslCond  *cond,
+			 GslMutex *mutex,
+			 gulong    abs_secs,
+			 gulong    abs_usecs)
+{
+  GTimeVal gtime;
 
-  g_cond_free (gcond);
-}
+  gtime.tv_sec = abs_secs;
+  gtime.tv_usec = abs_usecs;
+  g_cond_timed_wait (cond->cond_pointer, mutex->mutex_pointer, &gtime);
+}
+
+GslMutexTable gsl_mutex_table = {
+  default_mutex_init,
+  default_mutex_lock,
+  default_mutex_trylock,
+  default_mutex_unlock,
+  default_mutex_destroy,
+  default_rec_mutex_init,
+  default_rec_mutex_lock,
+  default_rec_mutex_trylock,
+  default_rec_mutex_unlock,
+  default_rec_mutex_destroy,
+  default_cond_init,
+  default_cond_signal,
+  default_cond_broadcast,
+  default_cond_wait,
+  default_cond_wait_timed,
+  default_cond_destroy,
+};
 
-#if 0
 void
 gsl_cond_wait_timed (GslCond  *cond,
 		     GslMutex *mutex,
 		     glong     max_useconds)
 {
-  gpointer gmutex, gcond = cond;
-
-  g_return_if_fail (cond != NULL);
-  g_return_if_fail (mutex != NULL);
-
-  gmutex = mutex->mutex_pointer;
-
   if (max_useconds < 0)
-    g_cond_wait (gcond, gmutex);
+    gsl_cond_wait (cond, mutex);
   else
     {
-      glong my_sec;
-      GTimeVal gtime;
+      struct timeval now;
+      glong secs;
 
-      /* for some reason, g_cond_timed_wait() (pthread_cond_timedwait) insists
-       * on getting absolute timevalues ;(
-       */
-      g_get_current_time (&gtime);
-      my_sec = max_useconds / G_USEC_PER_SEC;
-      gtime.tv_sec += my_sec;
-      gtime.tv_usec += max_useconds - my_sec * G_USEC_PER_SEC;
-      if (gtime.tv_usec >= G_USEC_PER_SEC)
+      gettimeofday (&now, NULL);
+      secs = max_useconds / 1000000;
+      now.tv_sec += secs;
+      max_useconds -= secs * 1000000;
+      now.tv_usec += max_useconds;
+      if (now.tv_usec >= 1000000)
 	{
-	  gtime.tv_usec -= G_USEC_PER_SEC;
-	  gtime.tv_sec += 1;
+	  now.tv_usec -= 1000000;
+	  now.tv_sec += 1;
 	}
 
-      /* for linux on x86 with pthread_cond_timedwait(), this has 10ms
-       * resolution
-       */
-      g_cond_timed_wait (gcond, gmutex, &gtime);
+      /* linux on x86 with pthread has actually 10ms resolution */
+      gsl_mutex_table.cond_wait_timed (cond, mutex, now.tv_sec, now.tv_usec);
     }
 }
-#endif
-
-void
-gsl_cond_wait (GslCond  *cond,
-	       GslMutex *mutex)
-{
-  gpointer gmutex, gcond = cond;
-
-  g_return_if_fail (cond != NULL);
-  g_return_if_fail (mutex != NULL);
-
-  gmutex = mutex->mutex_pointer;
 
-  /* infinite wait */
-  g_cond_wait (gcond, gmutex);
-}
 
-void
-gsl_cond_signal (GslCond *cond)
-{
-  gpointer gcond = cond;
-
-  g_return_if_fail (cond != NULL);
-
-  g_cond_signal (gcond);
-}
-
-void
-gsl_cond_broadcast (GslCond *cond)
-{
-  gpointer gcond = cond;
-
-  g_return_if_fail (cond != NULL);
-
-  g_cond_broadcast (gcond);
-}
-
-
 /* --- GslMessage --- */
 const gchar*
 gsl_strerror (GslErrorType error)
@@ -1275,7 +1261,8 @@
 #define	ROUND(dblval)	((GslLong) ((dblval) + .5))
 
 void
-gsl_init (const GslConfigValue values[])
+gsl_init (const GslConfigValue values[],
+	  GslMutexTable       *mtable)
 {
   const GslConfigValue *config = values;
   static GslConfig pconfig = {	/* DEFAULTS */
@@ -1288,9 +1275,11 @@
     440,			/* kammer_freq */
   };
 
-  if (gsl_config)	/* ignore multiple invocations */
-    return;
-  g_assert (gsl_config++ == NULL);	/* dumb concurrency prevention */
+  g_return_if_fail (gsl_config == NULL);	/* assert single initialization */
+
+  /* get mutexes going first */
+  if (mtable)
+    gsl_mutex_table = *mtable;
 
   gsl_externvar_tick_stamp = 1;
 
@@ -1330,7 +1319,7 @@
   is_smp_system = GSL_CONFIG (n_processors) > 1;
   gsl_mutex_init (&global_memory);
   gsl_mutex_init (&global_thread);
-  global_thread_cond = gsl_cond_new ();
+  gsl_cond_init (&global_thread_cond);
   main_thread_tdata = create_tdata ();
   g_assert (main_thread_tdata != NULL);
   _gsl_init_data_handles ();
Index: flow/gsl/gslcommon.h
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslcommon.h,v
retrieving revision 1.6
diff -u -b -r1.6 gslcommon.h
--- flow/gsl/gslcommon.h	2002/02/10 15:04:49	1.6
+++ flow/gsl/gslcommon.h	2002/03/21 17:36:51
@@ -47,7 +47,9 @@
   /* kammer frequency, normally 440Hz, historically 435Hz */
   gfloat kammer_freq;
 } GslConfig;
-void			gsl_init	(const GslConfigValue	values[]);
+typedef struct _GslMutexTable GslMutexTable;
+void			gsl_init	(const GslConfigValue	values[],
+					 GslMutexTable	       *mtable);
 const GslConfig*	gsl_get_config	(void) G_GNUC_CONST;
 #define	GSL_CONFIG(value)	((gsl_get_config () [0]) . value)
 
@@ -136,33 +138,49 @@
 
 
 /* --- GslMutex --- */
-#define GSL_SPIN_LOCK(mutex)	 gsl_mutex_spin_lock (mutex)
-#define GSL_SPIN_UNLOCK(mutex)	 gsl_mutex_unlock (mutex)
-#define GSL_SYNC_LOCK(mutex)	 gsl_mutex_sync_lock (mutex)
-#define GSL_SYNC_UNLOCK(mutex)	 gsl_mutex_unlock (mutex)
-void	gsl_mutex_init		(GslMutex	*mutex);
-void	gsl_mutex_destroy	(GslMutex	*mutex);
-
-
-/* --- GslRecMutex --- */
-void	gsl_rec_mutex_init	(GslRecMutex	*rec_mutex);
-void	gsl_rec_mutex_destroy	(GslRecMutex	*rec_mutex);
-void	gsl_rec_mutex_lock	(GslRecMutex	*rec_mutex);
-void	gsl_rec_mutex_unlock	(GslRecMutex	*rec_mutex);
-
-
-/* --- GslCond --- */
-GslCond* gsl_cond_new		(void);
-#if 0
+#define	gsl_mutex_init(mutex)		(gsl_mutex_table.mutex_init (mutex))
+#define GSL_SPIN_LOCK(mutex)		(gsl_mutex_table.mutex_lock (mutex))
+#define GSL_SPIN_UNLOCK(mutex)		(gsl_mutex_table.mutex_unlock (mutex))
+#define GSL_SYNC_LOCK(mutex)		(gsl_mutex_table.mutex_lock (mutex))
+#define GSL_SYNC_UNLOCK(mutex)		(gsl_mutex_table.mutex_unlock (mutex))
+#define	gsl_mutex_trylock(mutex)	(!gsl_mutex_table.mutex_trylock (mutex))
+#define	gsl_mutex_destroy(mutex)	(gsl_mutex_table.mutex_destroy (mutex))
+#define	gsl_rec_mutex_init(rmutex)	(gsl_mutex_table.rec_mutex_init (rmutex))
+#define	gsl_rec_mutex_lock(rmutex)	(gsl_mutex_table.rec_mutex_lock (rmutex))
+#define	gsl_rec_mutex_unlock(rmutex)	(gsl_mutex_table.rec_mutex_unlock (rmutex))
+#define	gsl_rec_mutex_trylock(rmutex)	(!gsl_mutex_table.rec_mutex_trylock (rmutex))
+#define	gsl_rec_mutex_destroy(rmutex)	(gsl_mutex_table.rec_mutex_destroy (rmutex))
+#define	gsl_cond_init(cond)		(gsl_mutex_table.cond_init (cond))
+#define	gsl_cond_signal(cond)		(gsl_mutex_table.cond_signal (cond))
+#define	gsl_cond_broadcast(cond)	(gsl_mutex_table.cond_broadcast (cond))
+#define	gsl_cond_wait(cond, mutex)	(gsl_mutex_table.cond_wait ((cond), (mutex)))
+#define	gsl_cond_destroy(cond)		(gsl_mutex_table.cond_destroy (cond))
 void	 gsl_cond_wait_timed	(GslCond	*cond,
 				 GslMutex	*mutex,
 				 glong		 max_useconds);
-#endif
-void	 gsl_cond_wait		(GslCond	*cond,
+struct _GslMutexTable
+{
+  void	(*mutex_init)		(GslMutex	*mutex);
+  void	(*mutex_lock)		(GslMutex	*mutex);
+  int	(*mutex_trylock)	(GslMutex	*mutex); /* 0==has_lock */
+  void	(*mutex_unlock)		(GslMutex	*mutex);
+  void	(*mutex_destroy)	(GslMutex	*mutex);
+  void	(*rec_mutex_init)	(GslRecMutex	*mutex);
+  void	(*rec_mutex_lock)	(GslRecMutex	*mutex);
+  int	(*rec_mutex_trylock)	(GslRecMutex	*mutex); /* 0==has_lock */
+  void	(*rec_mutex_unlock)	(GslRecMutex	*mutex);
+  void	(*rec_mutex_destroy)	(GslRecMutex	*mutex);
+  void	(*cond_init)		(GslCond	*cond);
+  void	(*cond_signal)		(GslCond	*cond);
+  void	(*cond_broadcast)	(GslCond	*cond);
+  void	(*cond_wait)		(GslCond	*cond,
 				 GslMutex	*mutex);
-void	 gsl_cond_signal	(GslCond	*cond);
-void	 gsl_cond_broadcast	(GslCond	*cond);
-void	 gsl_cond_destroy	(GslCond	*cond);
+  void	(*cond_wait_timed)	(GslCond	*cond,
+				 GslMutex	*mutex,
+				 gulong		 abs_secs,
+				 gulong		 abs_usecs);
+  void	(*cond_destroy)		(GslCond	*cond);
+};
 
 
 /* --- misc --- */
@@ -173,16 +191,12 @@
 
 
 /* --- implementation details --- */
-void		gsl_mutex_spin_lock	(GslMutex	*mutex);
-void		gsl_mutex_sync_lock	(GslMutex	*mutex);
-void		gsl_mutex_unlock	(GslMutex	*mutex);
 gpointer	gsl_alloc_memblock	(gsize		 size);
 gpointer	gsl_alloc_memblock0	(gsize		 size);
 void		gsl_free_memblock	(gsize		 size,
 					 gpointer	 memblock);
 void		gsl_alloc_report	(void);
 const guint	gsl_alloc_upper_power2	(const gulong	 number);
-gboolean	gsl_rec_mutex_test_self	(GslRecMutex	*rec_mutex);
 void	       _gsl_tick_stamp_inc	(void);
 void	       _gsl_tick_stamp_set_leap (guint		 ticks);
 void	_gsl_init_data_handles		(void);
@@ -194,6 +208,7 @@
 #define		GSL_N_IO_RETRIES	(5)
 #define		_GSL_TICK_STAMP_VAL()	(gsl_externvar_tick_stamp + 0)
 extern volatile guint64	gsl_externvar_tick_stamp;
+extern GslMutexTable gsl_mutex_table;
 
 #ifdef __cplusplus
 }
Index: flow/gsl/gsldatacache.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gsldatacache.c,v
retrieving revision 1.4
diff -u -b -r1.4 gsldatacache.c
--- flow/gsl/gsldatacache.c	2002/01/17 19:54:49	1.4
+++ flow/gsl/gsldatacache.c	2002/03/21 17:36:52
@@ -64,7 +64,7 @@
 
 /* --- variables --- */
 static GslMutex	   dcache_global = { 0, };
-static GslCond	  *dcache_cond_node_filled = NULL;
+static GslCond	   dcache_cond_node_filled = { 0, };
 static GslRing	  *dcache_list = NULL;
 static guint       n_aged_nodes = 0;
 
@@ -73,9 +73,12 @@
 void
 _gsl_init_data_caches (void)
 {
-  g_assert (dcache_cond_node_filled == NULL);
+  static gboolean initialized = FALSE;
 
-  dcache_cond_node_filled = gsl_cond_new ();
+  g_assert (initialized == FALSE);
+  initialized++;
+
+  gsl_cond_init (&dcache_cond_node_filled);
   gsl_mutex_init (&dcache_global);
 }
 
@@ -345,7 +348,7 @@
 
   GSL_SPIN_LOCK (&dcache->mutex);
   dnode->data = node_data;
-  gsl_cond_broadcast (dcache_cond_node_filled);
+  gsl_cond_broadcast (&dcache_cond_node_filled);
   
   return dnode;
 }
@@ -374,7 +377,7 @@
 	  node->ref_count++;
 	  if (demand_load)
 	    while (!node->data)
-	      gsl_cond_wait (dcache_cond_node_filled, &dcache->mutex);
+	      gsl_cond_wait (&dcache_cond_node_filled, &dcache->mutex);
 	  GSL_SPIN_UNLOCK (&dcache->mutex);
 	  /* g_print("hit: %d :%d: %d\n", node->offset, offset, node->offset + dcache->node_size); */
 
Index: flow/gsl/gsldatahandle.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gsldatahandle.c,v
retrieving revision 1.5
diff -u -b -r1.5 gsldatahandle.c
Index: flow/gsl/gsldefs.h
===================================================================
RCS file: /home/kde/arts/flow/gsl/gsldefs.h,v
retrieving revision 1.4
diff -u -b -r1.4 gsldefs.h
--- flow/gsl/gsldefs.h	2002/02/10 15:04:49	1.4
+++ flow/gsl/gsldefs.h	2002/03/21 17:36:53
@@ -26,6 +26,10 @@
 #endif
 
 
+/* configure checks */
+#include <gsl/gslconfig.h>
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -35,7 +39,6 @@
 typedef struct _GslMagic		GslMagic;
 typedef struct _GslClass		GslClass;
 typedef struct _GslComplex		GslComplex;
-typedef struct _GslCond			GslCond;
 typedef struct _GslDataCache		GslDataCache;
 typedef struct _GslDataHandle		GslDataHandle;
 typedef struct _GslDataHandleFuncs	GslDataHandleFuncs;
@@ -51,6 +54,7 @@
 typedef struct _GslWaveChunkBlock	GslWaveChunkBlock;
 typedef struct _GslRecMutex		GslRecMutex;
 typedef struct _GslRing			GslRing;
+typedef union _GslCond			GslCond;
 typedef union _GslMutex			GslMutex;
 /* ssize_t/off_t type used within Gsl */
 typedef glong			  GslLong;
@@ -113,32 +117,30 @@
 #endif
 
 
-/* --- implementation specific --- */
-/*< private >*/
-/* FIXME: gslconfig.h stuff */
+/* --- implementation details --- */
 #define	GSL_ENGINE_MAX_POLLFDS	(128)
-#define GSL_SIZEOF_MUTEX        (8)
-#define GSL_SIZEOF_GTIME        (4)
-#define GSL_SIZEOF_GUINT        (4)
-#define GSL_SIZEOF_GSIZE        (4)
-#define GSL_SIZEOF_INTMAX	(8)
+union _GslCond
+{
+  gpointer cond_pointer;
+  guint8   cond_dummy[MAX (8, GSL_SIZEOF_PTH_COND_T)];
+};
 union _GslMutex
 {
   gpointer mutex_pointer;
-  guint8   mutex_dummy[GSL_SIZEOF_MUTEX];
+  guint8   mutex_dummy[MAX (8, GSL_SIZEOF_PTH_MUTEX_T)];
 };
 struct _GslRecMutex
 {
-  guint    depth;
-  gpointer owner;
   GslMutex sync_mutex;
+  gpointer owner;
+  guint    depth;
 };
 #if __GNUC__ >= 3 && defined __OPTIMIZE__
 #  define GSL_GCC_EXPECT(cond)	(__builtin_expect ((cond) != 0, 1))
 #  define GSL_GCC_REJECT(cond)	(__builtin_expect ((cond) != 0, 0))
 #else
-#  define GSL_GCC_EXPECT(cond)	(cond)
-#  define GSL_GCC_REJECT(cond)	(cond)
+#  define GSL_GCC_EXPECT(cond)	cond
+#  define GSL_GCC_REJECT(cond)	cond
 #endif
 
 #ifdef __cplusplus
@@ -146,4 +148,5 @@
 #endif /* __cplusplus */
 
 #endif /* __GSL_DEFS_H__ */
+
 /* vim:set ts=8 sw=2 sts=2: */
Index: flow/gsl/gslengine.h
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslengine.h,v
retrieving revision 1.7
diff -u -b -r1.7 gslengine.h
--- flow/gsl/gslengine.h	2002/03/17 05:03:51	1.7
+++ flow/gsl/gslengine.h	2002/03/21 17:36:53
@@ -80,10 +80,11 @@
   GslOStream	 *ostreams;	/* output streams */
 };
 /* streams, constructed by engine */
+#ifndef	__GSL_MASTER_C__	/* sync this with gslopmaster.c */
 struct _GslJStream
 {
   const gfloat **values;
-  guint          n_connections;
+  const guint    n_connections;
   guint		 user_flags : 16;
 };
 struct _GslIStream
@@ -98,6 +99,7 @@
   guint	      user_flags : 16;
   guint connected : 1;
 };
+#endif	/* !__GSL_MASTER_C__ */
 
 
 /* --- interface (UserThread functions) --- */
Index: flow/gsl/gslffttest.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslffttest.c,v
retrieving revision 1.1
diff -u -b -r1.1 gslffttest.c
--- flow/gsl/gslffttest.c	2001/12/13 21:52:04	1.1
+++ flow/gsl/gslffttest.c	2002/03/21 17:36:54
@@ -59,7 +59,7 @@
   
   /* initialize GSL */
   g_thread_init (NULL);
-  gsl_init (NULL);
+  gsl_init (NULL, NULL);
 
   /* initialize random numbers */
   gettimeofday (&tv, NULL);
Index: flow/gsl/gslglib.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslglib.c,v
retrieving revision 1.10
diff -u -b -r1.10 gslglib.c
--- flow/gsl/gslglib.c	2002/02/13 20:54:52	1.10
+++ flow/gsl/gslglib.c	2002/03/21 17:36:56
@@ -8,7 +8,7 @@
 #include <unistd.h>
 #include <stdio.h>
 
-#define	GLIB_SIZEOF_INTMAX	GSL_SIZEOF_INTMAX
+#define	GLIB_SIZEOF_INTMAX	(GSL_SIZEOF_STD_INTMAX_T ? GSL_SIZEOF_STD_INTMAX_T : 8 /* educated guess */)
 
 gpointer g_malloc         (gulong        n_bytes) { void*p = malloc(n_bytes); GSL_ASSERT(p!=0); return p; }
 gpointer g_malloc0        (gulong        n_bytes) { return memset(g_malloc(n_bytes),0,n_bytes); }
Index: flow/gsl/gslglib.h
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslglib.h,v
retrieving revision 1.10
diff -u -b -r1.10 gslglib.h
--- flow/gsl/gslglib.h	2002/02/15 14:42:41	1.10
+++ flow/gsl/gslglib.h	2002/03/21 17:36:57
@@ -74,6 +74,13 @@
 typedef unsigned long long int  guint64;
 #endif
 typedef struct _GString GString;
+typedef struct _GTimeVal        GTimeVal;
+
+struct _GTimeVal
+{
+  glong tv_sec;
+  glong tv_usec;
+};
 
 
 /* --- standard macros --- */
Index: flow/gsl/gslmakefile.inc
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslmakefile.inc,v
retrieving revision 1.6
diff -u -b -r1.6 gslmakefile.inc
--- flow/gsl/gslmakefile.inc	2002/02/21 14:24:45	1.6
+++ flow/gsl/gslmakefile.inc	2002/03/21 17:36:58
@@ -1,16 +1,37 @@
+# this makefile defines:
+#
+# GSL_C_SRC		C source files which need to be added to *_SOURCES
+# GSL_NOINST_PROGS	GSL test programs, needs to be added to noinst_PROGRAMS
+#
+# this makefile supports:
+#
+# GSL_cc_dummy		define to an empty .cc file if your linker needs to
+#			link GSL object files as c++ code
+# GSL_progs_ldadd	add link options to this varibale, which are required
+#			to link GSL_NOINST_PROGS targets
+# gslincludedir		directory to install public headers into if not empty
+#
+# this makefile introduces:
+#
+# gsltestoutput:	make target to generate a sample set of test data
+
+# make sure gslincludedir= is defined
 # GSL targets
-GSL_H_SRC =	gslcommon.h gsldatacache.h gsldatahandle.h gsldefs.h gslwavechunk.h \
-		gslmath.h gslfilter.h gsldatautils.h gsldatahandle-vorbis.h \
+GSL_H_SRC     =	gslcommon.h gsldatacache.h gsldatahandle.h gsldefs.h \
+		gslloader.h gslmath.h gslfilter.h gsldatautils.h gsldatahandle-vorbis.h \
 		gslconvert.h gslfft.h gslieee754.h gslsignal.h gslmagic.h \
-		gslengine.h gslwaveosc.h
-GSL_PRIVATE_H_SRC = gsloputil.h gslopmaster.h gslopnode.h gslopschedule.h gslloader.h
+		gslengine.h gslwaveosc.h gslwavechunk.h
 GSL_C_SRC = gsldatacache.c gsldatahandle.c gslwavechunk.c \
 		gslmath.c gslfilter.c gslcommon.c gsldatautils.c gslmagic.c \
 		gslloader-wav.c gslloader-gslwave.c \
 		gslconvert.c gslfft.c gslsignal.c gslloader.c gslwaveosc.c \
 		gslengine.c gsloputil.c gslopmaster.c gslopschedule.c
-# need configure test: gsldatahandle-vorbis.c gslloader-oggvorbis.c
-EXTRA_DIST += gslwaveosc-aux.c
+
+# not yet: gsldatahandle-vorbis.c gslloader-oggvorbis.c
+GSL_EXTRA_SRC =	gslconfig.h gsloputil.h gslopmaster.h gslopnode.h gslopschedule.h gslwaveosc-aux.c
+GSL_EXTRA_DAT = gsl.gnuplot gsl-mplan.txt gslarrows gslwave.header gslglib.c gslglib.h gsl-fftgen.pl
+EXTRA_DIST   +=	$(GSL_H_SRC) $(GSL_EXTRA_SRC) $(GSL_EXTRA_DAT)
+
 GSL_NOINST_PROGS = gslwchunk gsltests gslglibhashtest gslffttest
 gslwchunk_SOURCES = gslwchunk.c $(GSL_cc_dummy)
 gslwchunk_LDADD = $(GSL_progs_ldadd)
@@ -18,16 +39,42 @@
 gsltests_LDADD = $(GSL_progs_ldadd)
 gslffttest_SOURCES = gslffttest.c $(GSL_cc_dummy)
 gslffttest_LDADD = $(GSL_progs_ldadd)
-gslglibhashtest_SOURCES = gslglibhashtest.cc
+gslglibhashtest_SOURCES = gslglibhashtest.cc # C++ already
 gslglibhashtest_LDADD = $(GSL_progs_ldadd)
-EXTRA_DIST += gsl.gnuplot gsl-mplan.txt gslarrows gslglibhash.cc
-EXTRA_DIST += gslwave.header gsl/gslglib.c gsl/gslglib.h gsl-fftgen.pl
 
 gslfft.c: $(srcdir)/gsl-fftgen.pl $(srcdir)/gsl-fftconf.sh
 	$(srcdir)/gsl-fftconf.sh $(srcdir)/gsl-fftgen.pl \"gslfft.h\" >$@
+MAINTAINERCLEANFILES += gslfft.c
 
-.PHONY:	gsltestoutput
+gslconfig.h: $(top_srcdir)/configure Makefile
+	echo "/* Generated data from $< (by make $@) */" > xgen-gch \
+	&& echo >> xgen-gch \
+	&& echo "#define GSL_SIZEOF_PTH_MUTEX_T         (@GSL_SIZEOF_PTH_MUTEX_T@)" >> xgen-gch \
+	&& echo "#define GSL_SIZEOF_PTH_COND_T          (@GSL_SIZEOF_PTH_COND_T@)" >> xgen-gch \
+	&& echo "#define GSL_HAVE_MUTEXATTR_SETTYPE     (@GSL_HAVE_MUTEXATTR_SETTYPE@ && \\" >> xgen-gch \
+	&& echo "                                        GSL_SIZEOF_PTH_MUTEX_T && \\" >> xgen-gch \
+	&& echo "                                        GSL_SIZEOF_PTH_COND_T)" >> xgen-gch \
+	&& echo "#define GSL_SIZEOF_STD_INTMAX_T        (@GSL_SIZEOF_STD_INTMAX_T@)" >> xgen-gch \
+	&& echo "#define GSL_HAVE_LIBMAD                (@GSL_HAVE_LIBMAD@)" >> xgen-gch \
+	&& echo >> xgen-gch \
+	&& echo "/* Generated data ends here */" >> xgen-gch \
+	&& (cmp -s xgen-gch $@ || cp xgen-gch $@) \
+	&& rm -f xgen-gch
+CLEANFILES += gslconfig.h xgen-gch
+$(OBJECTS): gslconfig.h
 
+install-data-local:	gsl-install-data-local
+gsl-install-data-local:
+	$(mkinstalldirs) $(DESTDIR)$(gslincludedir)
+	@list='$(GSL_H_SRC)'; \
+	test -z "$(gslincludedir)" || for hfile in $$list ; do \
+	  if test -f "$$hfile"; then d= ; else d="$(srcdir)/"; fi; \
+	  echo " $(INSTALL_DATA) $$d$$hfile $(DESTDIR)$(gslincludedir)/$$hfile"; \
+	  $(INSTALL_DATA) $$d$$hfile $(DESTDIR)$(gslincludedir)/$$hfile; \
+        done
+
+.PHONY:	gsltestoutput gsl-install-data-local
+
 gsltestoutput:
 	@./gsltests blp     7 0.3		0.1211
 	@./gsltests bhp    12 1.8332		0.1033
@@ -57,4 +104,3 @@
 	@echo -n " dB(T2P10(Z(x))),"
 	@echo -n " dB(T2S10(Z(x))),"
 	@echo " -3"
-
Index: flow/gsl/gslopmaster.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslopmaster.c,v
retrieving revision 1.8
diff -u -b -r1.8 gslopmaster.c
--- flow/gsl/gslopmaster.c	2002/02/10 15:04:49	1.8
+++ flow/gsl/gslopmaster.c	2002/03/21 17:36:58
@@ -16,6 +16,7 @@
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#define	__GSL_MASTER_C__
 #include "gslopmaster.h"
 
 #include "gslcommon.h"
@@ -29,6 +30,31 @@
 #include <errno.h>
 
 
+
+/* force public constantness but allow us to change values
+ * in these structures.
+ * *** sync this with gslengine.h ***
+ */
+struct _GslJStream
+{
+  const gfloat      **values;
+  /* const */ guint   n_connections;
+  guint               user_flags : 16;
+};
+struct _GslIStream
+{
+  const gfloat     *values;
+  guint             user_flags : 16;
+  /* const */ guint connected : 1;
+};
+struct _GslOStream
+{
+  gfloat           *values;
+  guint             user_flags : 16;
+  /* const */ guint connected : 1;
+};
+
+
 /* --- time stamping (debugging) --- */
 #define	ToyprofStamp		struct timeval
 #define	toyprof_clock_name()	("Glibc gettimeofday(2)")
@@ -675,3 +701,4 @@
       run = gsl_thread_sleep (0);
     }
 }
+/* vim:set ts=8 sts=2 sw=2: */
Index: flow/gsl/gslopnode.h
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslopnode.h,v
retrieving revision 1.5
diff -u -b -r1.5 gslopnode.h
--- flow/gsl/gslopnode.h	2002/02/10 15:04:49	1.5
+++ flow/gsl/gslopnode.h	2002/03/21 17:36:58
@@ -40,7 +40,6 @@
 #define	OP_NODE_IS_EXPENSIVE(node)	(((node)->module.klass->mflags & GSL_COST_EXPENSIVE) != 0)
 #define	OP_NODE_LOCK(node)		gsl_rec_mutex_lock (&(node)->rec_mutex)
 #define	OP_NODE_UNLOCK(node)		gsl_rec_mutex_unlock (&(node)->rec_mutex)
-#define	OP_NODE_SELF_LOCKED(node)	(gsl_rec_mutex_test_self (&OP_NODE (node)->rec_mutex) > 0)
 
 
 /* --- transactions --- */
Index: flow/gsl/gsloputil.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gsloputil.c,v
retrieving revision 1.5
diff -u -b -r1.5 gsloputil.c
--- flow/gsl/gsloputil.c	2002/01/17 19:54:49	1.5
+++ flow/gsl/gsloputil.c	2002/03/21 17:36:59
@@ -21,6 +21,7 @@
 #include "gslcommon.h"
 #include "gslopnode.h"
 #include "gslopschedule.h"
+#include "gslsignal.h"
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -240,11 +241,13 @@
 {
   guint    n_nodes;
   gfloat **nodes;
+  guint8  *nodes_used;
 } ConstValuesArray;
-static const gfloat CONST_VALUES_EPSILON = 1e-5;	/* FIXME: assuming 16bit significant bits */
 
-static inline gfloat*
-const_values_lookup (ConstValuesArray *array,
+static const guint8 CONST_VALUES_EXPIRE = 16;           /* expire value after being unused for 16 times */
+
+static inline gfloat**
+const_values_lookup_nextmost (ConstValuesArray *array,
 		     gfloat	       key_value)
 {
   guint n_nodes = array->n_nodes;
@@ -252,28 +255,30 @@
   if (n_nodes > 0)
     {
       gfloat **nodes = array->nodes;
+      gfloat **check;
       
       nodes -= 1;
       do
 	{
-	  gfloat **check;
 	  guint i;
 	  register gfloat cmp;
 	  
 	  i = (n_nodes + 1) >> 1;
 	  check = nodes + i;
 	  cmp = key_value - **check;
-	  if (cmp > CONST_VALUES_EPSILON)
+	  if (cmp > GSL_SIGNAL_EPSILON)
 	    {
 	      n_nodes -= i;
 	      nodes = check;
 	    }
-	  else if (cmp < CONST_VALUES_EPSILON)
+	  else if (cmp < -GSL_SIGNAL_EPSILON)
 	    n_nodes = i - 1;
 	  else /* cmp ~==~ 0.0 */
-	    return *check;
+	    return check;   /* matched */
 	}
       while (n_nodes);
+
+      return check;  /* nextmost */
     }
   
   return NULL;
@@ -287,98 +292,113 @@
 
 static inline void
 const_values_insert (ConstValuesArray *array,
+		     guint             index,
 		     gfloat	      *value_block)
 {
-  gfloat **check;
-  
   if (array->n_nodes == 0)
     {
       guint new_size = upper_power2 (sizeof (gfloat*));
       
       array->nodes = g_realloc (array->nodes, new_size);
+      array->nodes_used = g_realloc (array->nodes_used, new_size / sizeof (gfloat*));
       array->n_nodes = 1;
-      check = array->nodes;
+
+      g_assert (index == 0);
     }
   else
     {
-      guint n_nodes = array->n_nodes;
-      gfloat **nodes = array->nodes;
-      gfloat cmp;
-      guint i;
+      guint n_nodes = array->n_nodes++;
       
-      nodes -= 1;
-      do
-	{
-	  i = (n_nodes + 1) >> 1;
-	  check = nodes + i;
-	  cmp = *value_block - **check;
-	  if (cmp > CONST_VALUES_EPSILON)
-	    {
-	      n_nodes -= i;
-	      nodes = check;
-	    }
-	  else if (cmp < CONST_VALUES_EPSILON)
-	    n_nodes = i - 1;
-	  else /* cmp ~==~ 0.0 */
-	    g_assert_not_reached ();
-	}
-      while (n_nodes);
-      /* grow */
-      if (cmp > 0)
-	check += 1;
-      i = check - array->nodes;
-      n_nodes = array->n_nodes++;
+      if (*array->nodes[index] < *value_block)
+	index++;
+      
       if (1)
 	{
 	  guint new_size = upper_power2 (array->n_nodes * sizeof (gfloat*));
 	  guint old_size = upper_power2 (n_nodes * sizeof (gfloat*));
 	  
 	  if (new_size != old_size)
+	    {
 	    array->nodes = g_realloc (array->nodes, new_size);
+	      array->nodes_used = g_realloc (array->nodes_used, new_size / sizeof(gfloat*));
+	    }
 	}
-      check = array->nodes + i;
-      g_memmove (check + 1, check, (n_nodes - i) * sizeof (gfloat*));
+      g_memmove (array->nodes + index + 1, array->nodes + index, (n_nodes - index) * sizeof (array->nodes[0]));
+      g_memmove (array->nodes_used + index + 1, array->nodes_used + index, (n_nodes - index) * sizeof (array->nodes_used[0]));
     }
-  *check = value_block;
+
+  array->nodes[index] = value_block;
+  array->nodes_used[index] = CONST_VALUES_EXPIRE;
 }
 
-static ConstValuesArray cvalue_array = { 0, NULL, };
+static ConstValuesArray cvalue_array = { 0, NULL, NULL };
 
 gfloat*
 gsl_engine_const_values (gfloat value)
 {
   extern const gfloat gsl_engine_master_zero_block[];
-  gfloat *block;
+  gfloat **block;
   
-  if (fabs (value) < CONST_VALUES_EPSILON)
+  if (fabs (value) < GSL_SIGNAL_EPSILON)
     return (gfloat*) gsl_engine_master_zero_block;
-  block = const_values_lookup (&cvalue_array, value);
-  if (!block)
+
+  block = const_values_lookup_nextmost (&cvalue_array, value);
+
+  /* found correct match? */
+  if (block && fabs (**block - value) < GSL_SIGNAL_EPSILON)
     {
+      cvalue_array.nodes_used[block - cvalue_array.nodes] = CONST_VALUES_EXPIRE;
+      return *block;
+    }
+  else
+    {
+      /* create new value block */
+      gfloat *values = g_new (gfloat, gsl_engine_block_size ());
       guint i;
       
-      block = g_new (gfloat, gsl_engine_block_size ());
       for (i = 0; i < gsl_engine_block_size (); i++)
-	block[i] = value;
-      const_values_insert (&cvalue_array, block);
+	values[i] = value;
+     
+      if (block)
+	const_values_insert (&cvalue_array, block - cvalue_array.nodes, values);
+      else
+	const_values_insert (&cvalue_array, 0, values);
+
+      return values;
     }
-  return block;
 }
 
 void
 _gsl_recycle_const_values (void)
 {
-  while (cvalue_array.n_nodes--)
-    g_free (cvalue_array.nodes[cvalue_array.n_nodes]);
-  cvalue_array.n_nodes = 0;
-}
+  gfloat **nodes = cvalue_array.nodes;
+  guint8 *used = cvalue_array.nodes_used;
+  guint count = cvalue_array.n_nodes, e = 0, i;
+  
+  for (i = 0; i < count; i++)
+    {
+      used[i]--;  /* invariant: use counts are never 0 */
 
+      if (used[i] == 0)
+	g_free (nodes[i]);
+      else /* preserve node */
+	{
+	  if (e < i)
+	    {
+	      nodes[e] = nodes[i];
+	      used[e] = used[i];
+	    }
+	  e++;
+	}
+    }
+  cvalue_array.n_nodes = e;
+}
 
 /* --- job transactions --- */
 static GslMutex       cqueue_trans = { 0, };
 static GslTrans      *cqueue_trans_pending_head = NULL;
 static GslTrans      *cqueue_trans_pending_tail = NULL;
-static GslCond       *cqueue_trans_cond = NULL;
+static GslCond        cqueue_trans_cond = { 0, };
 static GslTrans      *cqueue_trans_trash = NULL;
 static GslTrans      *cqueue_trans_active_head = NULL;
 static GslTrans      *cqueue_trans_active_tail = NULL;
@@ -403,7 +423,7 @@
     cqueue_trans_pending_head = trans;
   cqueue_trans_pending_tail = trans;
   GSL_SPIN_UNLOCK (&cqueue_trans);
-  gsl_cond_signal (cqueue_trans_cond);
+  gsl_cond_signal (&cqueue_trans_cond);
 }
 
 void
@@ -411,7 +431,7 @@
 {
   GSL_SPIN_LOCK (&cqueue_trans);
   while (cqueue_trans_pending_head || cqueue_trans_active_head)
-    gsl_cond_wait (cqueue_trans_cond, &cqueue_trans);
+    gsl_cond_wait (&cqueue_trans_cond, &cqueue_trans);
   GSL_SPIN_UNLOCK (&cqueue_trans);
 }
 
@@ -450,7 +470,7 @@
 	  cqueue_trans_pending_head = NULL;
 	  cqueue_trans_pending_tail = NULL;
 	  GSL_SPIN_UNLOCK (&cqueue_trans);
-	  gsl_cond_signal (cqueue_trans_cond);
+	  gsl_cond_signal (&cqueue_trans_cond);
 	}
       else
 	{
@@ -480,7 +500,7 @@
     {
       GSL_SPIN_LOCK (&cqueue_trans);
       if (!cqueue_trans_pending_head)
-	gsl_cond_wait_timed (cqueue_trans_cond,
+	gsl_cond_wait_timed (&cqueue_trans_cond,
 			     &cqueue_trans,
 			     max_useconds);
       GSL_SPIN_UNLOCK (&cqueue_trans);
@@ -548,7 +568,7 @@
 static OpSchedule       *pqueue_schedule = NULL;
 static guint             pqueue_n_nodes = 0;
 static guint             pqueue_n_cycles = 0;
-static GslCond		*pqueue_done_cond = NULL;
+static GslCond		 pqueue_done_cond = { 0, };
 static GslFlowJob       *pqueue_trash_fjobs_first = NULL;
 static GslFlowJob       *pqueue_trash_fjobs_last = NULL;
 
@@ -625,7 +645,6 @@
 _gsl_com_push_processed_node (OpNode *node)
 {
   g_return_if_fail (node != NULL);
-  g_return_if_fail (OP_NODE_SELF_LOCKED (node));        /* paranoid */
   g_return_if_fail (pqueue_n_nodes > 0);
   g_return_if_fail (OP_NODE_IS_SCHEDULED (node));
   
@@ -643,7 +662,7 @@
   pqueue_n_nodes -= 1;
   OP_NODE_UNLOCK (node);
   if (!pqueue_n_nodes && !pqueue_n_cycles && GSL_SCHEDULE_NONPOPABLE (pqueue_schedule))
-    gsl_cond_signal (pqueue_done_cond);
+    gsl_cond_signal (&pqueue_done_cond);
   GSL_SPIN_UNLOCK (&pqueue_mutex);
 }
 
@@ -657,7 +676,6 @@
 _gsl_com_push_processed_cycle (GslRing *cycle)
 {
   g_return_if_fail (cycle != NULL);
-  g_return_if_fail (OP_NODE_SELF_LOCKED (cycle->data));	/* paranoid */
   g_return_if_fail (pqueue_n_cycles > 0);
   g_return_if_fail (OP_NODE_IS_SCHEDULED (cycle->data));
 }
@@ -667,7 +685,7 @@
 {
   GSL_SPIN_LOCK (&pqueue_mutex);
   while (pqueue_n_nodes || pqueue_n_cycles || !GSL_SCHEDULE_NONPOPABLE (pqueue_schedule))
-    gsl_cond_wait (pqueue_done_cond, &pqueue_mutex);
+    gsl_cond_wait (&pqueue_done_cond, &pqueue_mutex);
   GSL_SPIN_UNLOCK (&pqueue_mutex);
 }
 
@@ -676,10 +694,16 @@
 void
 _gsl_init_engine_utils (void)
 {
-  g_assert (cqueue_trans_cond == NULL); /* single invocation */
+  static gboolean initialized = FALSE;
   
+  g_assert (initialized == FALSE); /* single invocation */
+  initialized++;
+
   gsl_mutex_init (&cqueue_trans);
-  cqueue_trans_cond = gsl_cond_new ();
+  gsl_cond_init (&cqueue_trans_cond);
   gsl_mutex_init (&pqueue_mutex);
-  pqueue_done_cond = gsl_cond_new ();
+  gsl_cond_init (&pqueue_done_cond);
 }
+
+
+/* vim:set ts=8 sts=2 sw=2: */
Index: flow/gsl/gsltests.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gsltests.c,v
retrieving revision 1.8
diff -u -b -r1.8 gsltests.c
--- flow/gsl/gsltests.c	2002/02/12 09:10:40	1.8
+++ flow/gsl/gsltests.c	2002/03/21 17:37:00
@@ -73,7 +73,7 @@
   shift_argv = argv;
   
   g_thread_init (NULL);
-  gsl_init (NULL);
+  gsl_init (NULL, NULL);
   
   arg = shift ();
   if (!arg)
Index: flow/gsl/gslwchunk.c
===================================================================
RCS file: /home/kde/arts/flow/gsl/gslwchunk.c,v
retrieving revision 1.4
diff -u -b -r1.4 gslwchunk.c
--- flow/gsl/gslwchunk.c	2002/02/10 15:04:49	1.4
+++ flow/gsl/gslwchunk.c	2002/03/21 17:37:01
@@ -199,7 +199,7 @@
   gint i, j, k;
 
   g_thread_init (NULL);
-  gsl_init (gslconfig);
+  gsl_init (gslconfig, NULL);
 
   if (0)
     {
Index: mcop/thread.cc
===================================================================
RCS file: /home/kde/arts/mcop/thread.cc,v
retrieving revision 1.6
diff -u -b -r1.6 thread.cc
--- mcop/thread.cc	2002/01/17 19:53:50	1.6
+++ mcop/thread.cc	2002/03/21 17:37:01
@@ -165,3 +165,5 @@
 SystemThreads::~SystemThreads()
 {
 }
+
+namespace Arts { void *gslGlobalMutexTable = 0; }
Index: mcop_mt/Makefile.am
===================================================================
RCS file: /home/kde/arts/mcop_mt/Makefile.am,v
retrieving revision 1.5
diff -u -b -r1.5 Makefile.am
--- mcop_mt/Makefile.am	2002/02/13 20:54:52	1.5
+++ mcop_mt/Makefile.am	2002/03/21 17:37:01
@@ -1,4 +1,6 @@
-INCLUDES = -I$(top_srcdir)/mcop $(all_includes)
+AM_CXXFLAGS = -DGSL_WANT_GLIB_WRAPPER -DGSL_WANT_ARTS_THREADS
+
+INCLUDES = -I$(top_srcdir)/mcop -I$(top_srcdir)/flow -I$(top_builddir)/flow $(all_includes)
 
 lib_LTLIBRARIES = libmcop_mt.la
 
Index: mcop_mt/threads_posix.cc
===================================================================
RCS file: /home/kde/arts/mcop_mt/threads_posix.cc,v
retrieving revision 1.9
diff -u -b -r1.9 threads_posix.cc
--- mcop_mt/threads_posix.cc	2002/03/21 13:23:30	1.9
+++ mcop_mt/threads_posix.cc	2002/03/21 17:37:01
@@ -27,6 +27,7 @@
 /* only compile this if we have libpthread available */
 #ifdef HAVE_LIBPTHREAD
 
+#define	_XOPEN_SOURCE	600	/* for full pthread facilities */
 #include <pthread.h>
 #include <semaphore.h>
 #include <debug.h>
@@ -41,6 +42,9 @@
 #undef PTHREAD_DEBUG
 
 namespace Arts {
+
+extern void *gslGlobalMutexTable;
+
 namespace PosixThreads {
 
 class ThreadCondition_impl;
@@ -323,6 +327,66 @@
 			arts_debug("SystemThreads init: pthread_key_delete failed");
 	}
 } initOnStartup;
+
+#include <gsl/gslcommon.h>
+/* -fast- locking for gsl on platforms with unix98 support */
+#if (GSL_HAVE_MUTEXATTR_SETTYPE > 0)
+static void pth_mutex_init (GslMutex *mutex)
+{
+	/* need NULL attribute here, which is the fast mutex on glibc
+	 * and cannot be chosen through the pthread_mutexattr_settype()
+	 */
+	pthread_mutex_init ((pthread_mutex_t*) mutex, NULL);
+}
+static void pth_rec_mutex_init (GslRecMutex *mutex)
+{
+	pthread_mutexattr_t attr;
+
+	pthread_mutexattr_init (&attr);
+	pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+	pthread_mutex_init ((pthread_mutex_t*) mutex, &attr);
+	pthread_mutexattr_destroy (&attr);
+}
+static void pth_rec_cond_init (GslCond *cond)
+{
+	pthread_cond_init ((pthread_cond_t*) cond, NULL);
+}
+static void pth_rec_cond_wait_timed (GslCond *cond, GslMutex *mutex,
+									 gulong abs_secs, gulong abs_usecs)
+{
+	struct timespec abstime;
+
+	abstime.tv_sec = abs_secs;
+	abstime.tv_nsec = abs_usecs * 1000;
+	pthread_cond_timedwait ((pthread_cond_t*) cond, (pthread_mutex_t*) mutex, &abstime);
+}
+static GslMutexTable pth_mutex_table = {
+	pth_mutex_init,
+	(void (*) (GslMutex*)) pthread_mutex_lock,
+	(int  (*) (GslMutex*)) pthread_mutex_trylock,
+	(void (*) (GslMutex*)) pthread_mutex_unlock,
+	(void (*) (GslMutex*)) pthread_mutex_destroy,
+	pth_rec_mutex_init,
+	(void (*) (GslRecMutex*)) pthread_mutex_lock,
+	(int  (*) (GslRecMutex*)) pthread_mutex_trylock,
+	(void (*) (GslRecMutex*)) pthread_mutex_unlock,
+	(void (*) (GslRecMutex*)) pthread_mutex_destroy,
+	pth_rec_cond_init,
+	(void (*)            (GslCond*)) pthread_cond_signal,
+	(void (*)            (GslCond*)) pthread_cond_broadcast,
+	(void (*) (GslCond*, GslMutex*)) pthread_cond_wait,
+	pth_rec_cond_wait_timed,
+	(void (*)            (GslCond*)) pthread_cond_destroy,
+};
+
+static class SetGslMutexTable {
+public:
+	SetGslMutexTable()
+	{
+		gslGlobalMutexTable = &pth_mutex_table;
+	}
+} initGslMutexTable;
+#endif
 
 }
 

