Merged eb/omni -r4315:4327 into trunk.
authoreb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Tue, 30 Jan 2007 02:12:05 +0000 (02:12 +0000)
committereb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Tue, 30 Jan 2007 02:12:05 +0000 (02:12 +0000)
Extracted omnithread from gnuradio-core and made it a top-level
component.  This allows mblock to use it without a dependency on
gnuradio-core.  Completes ticket:132

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@4328 221aa14e-8319-0410-a670-987f0aec2ac5

37 files changed:
Makefile.common
config/grc_gnuradio_core.m4
config/grc_mblock.m4
config/grc_omnithread.m4 [new file with mode: 0644]
configure.ac
gnuradio-core/gnuradio-core.pc.in
gnuradio-core/src/lib/Makefile.am
gnuradio-core/src/lib/omnithread/Makefile.am [deleted file]
gnuradio-core/src/lib/omnithread/dir.mk [deleted file]
gnuradio-core/src/lib/omnithread/mach.cc [deleted file]
gnuradio-core/src/lib/omnithread/nt.cc [deleted file]
gnuradio-core/src/lib/omnithread/omnithread.h [deleted file]
gnuradio-core/src/lib/omnithread/ot_VxThread.h [deleted file]
gnuradio-core/src/lib/omnithread/ot_mach.h [deleted file]
gnuradio-core/src/lib/omnithread/ot_nt.h [deleted file]
gnuradio-core/src/lib/omnithread/ot_posix.h [deleted file]
gnuradio-core/src/lib/omnithread/ot_pthread_nt.h [deleted file]
gnuradio-core/src/lib/omnithread/ot_solaris.h [deleted file]
gnuradio-core/src/lib/omnithread/posix.cc [deleted file]
gnuradio-core/src/lib/omnithread/solaris.cc [deleted file]
gnuradio-core/src/lib/omnithread/threaddata.cc [deleted file]
gnuradio-core/src/lib/omnithread/vxWorks.cc [deleted file]
omnithread/Makefile.am [new file with mode: 0644]
omnithread/dir.mk [new file with mode: 0644]
omnithread/mach.cc [new file with mode: 0644]
omnithread/nt.cc [new file with mode: 0644]
omnithread/omnithread.h [new file with mode: 0644]
omnithread/ot_VxThread.h [new file with mode: 0644]
omnithread/ot_mach.h [new file with mode: 0644]
omnithread/ot_nt.h [new file with mode: 0644]
omnithread/ot_posix.h [new file with mode: 0644]
omnithread/ot_pthread_nt.h [new file with mode: 0644]
omnithread/ot_solaris.h [new file with mode: 0644]
omnithread/posix.cc [new file with mode: 0644]
omnithread/solaris.cc [new file with mode: 0644]
omnithread/threaddata.cc [new file with mode: 0644]
omnithread/vxWorks.cc [new file with mode: 0644]

index e7d928682c435d4b9ec5ea821ce906da367176c3..56d7f5caa0d9c07d93681354b1e6ef1513921a69 100644 (file)
@@ -50,7 +50,6 @@ GNURADIO_INCLUDES = -I$(top_srcdir)/gnuradio-core/src/lib/runtime \
                    -I$(top_srcdir)/gnuradio-core/src/lib/reed-solomon \
                    -I$(top_srcdir)/gnuradio-core/src/lib/io \
                    -I$(top_srcdir)/gnuradio-core/src/lib/g72x \
-                   -I$(top_srcdir)/gnuradio-core/src/lib/omnithread \
                    -I$(top_srcdir)/gnuradio-core/src/lib/swig \
                    -I$(top_builddir)/gnuradio-core/src/lib/swig \
                    $(FFTW3F_CFLAGS)
@@ -58,6 +57,7 @@ GNURADIO_INCLUDES = -I$(top_srcdir)/gnuradio-core/src/lib/runtime \
 
 # These used to be set in PKGCONFIG but now point to the current
 # build tree.
+# FIXME shouldn't -lfftw3f -lm just be extracted from libgnuradio-core.la ???
 GNURADIO_CORE_LIBS = -L$(top_builddir)/gnuradio-core/src/lib \
                      -lgnuradio-core -lfftw3f -lm
 
@@ -69,15 +69,17 @@ GNURADIO_I = $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
 USRP_INCLUDES = -I$(top_srcdir)/usrp/host/lib \
                -I$(top_srcdir)/usrp/firmware/include
 
-USRP_LIBS = -L$(top_builddir)/usrp/host/lib \
-           -lusrp
+USRP_LIBS = -L$(top_builddir)/usrp/host/lib -lusrp
 
 PMT_INCLUDES = -I$(top_srcdir)/pmt/src/lib
 PMT_LIBS = -L$(top_builddir)/pmt/src/lib -lpmt
 
+OMNITHREAD_INCLUDES = -I$(top_srcdir)/omnithread
+OMNITHREAD_LIBS = -L$(top_builddir)/omnithread -lgromnithread
+
 # This used to be set in configure.ac but is now defined here for all 
 # Makefiles when this fragment is included.
-STD_DEFINES_AND_INCLUDES=$(DEFINES) $(GNURADIO_INCLUDES) $(BOOST_CFLAGS)
+STD_DEFINES_AND_INCLUDES=$(DEFINES) $(OMNITHREAD_INCLUDES) $(GNURADIO_INCLUDES) $(BOOST_CFLAGS)
 
 # Fix for BSD make not defining $(RM).  We define it now in configure.ac
 # using AM_PATH_PROG, but now here have to add a -f to be like GNU make
index da91f61ee127a42053649b62754a1c8660310549..6b9c8542eba2ef462be331434fb0fa9b414ba27c 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+dnl Copyright 2001,2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
 dnl 
 dnl This file is part of GNU Radio
 dnl 
@@ -37,7 +37,6 @@ AC_DEFUN([GRC_GNURADIO_CORE],[
         gnuradio-core/src/lib/gengen/Makefile \
         gnuradio-core/src/lib/io/Makefile \
         gnuradio-core/src/lib/missing/Makefile \
-        gnuradio-core/src/lib/omnithread/Makefile \
         gnuradio-core/src/lib/reed-solomon/Makefile \
         gnuradio-core/src/lib/runtime/Makefile \
         gnuradio-core/src/lib/swig/Makefile \
@@ -55,6 +54,16 @@ AC_DEFUN([GRC_GNURADIO_CORE],[
     ])
     
     passed=yes
+    # Don't do gnuradio-core if omnithread skipped
+    # There *has* to be a better way to check if a value is in a string
+    for dir in $skipped_dirs
+    do
+       if test x$dir = xomnithread; then
+           AC_MSG_RESULT([Component gnuradio-core requires omnithread, which is not being built.])
+           passed=no
+       fi
+    done
+
     GRC_BUILD_CONDITIONAL([gnuradio-core],[
         dnl run_tests is created from run_tests.in.  Make it executable.
         AC_CONFIG_COMMANDS([run_tests_core], [chmod +x gnuradio-core/src/python/gnuradio/gr/run_tests])
index a8fba4e03ccedd4e1dd00aa48e7c75b8df945eb9..6e4bc4afe1cfbfc89c66f09ce09ad060e42011cf 100644 (file)
@@ -28,6 +28,16 @@ AC_DEFUN([GRC_MBLOCK],[
     ])
 
     passed=yes
+    # Don't do mblock if omnithread skipped
+    # There *has* to be a better way to check if a value is in a string
+    for dir in $skipped_dirs
+    do
+       if test x$dir = xomnithread; then
+           AC_MSG_RESULT([Component mblock requires omnithread, which is not being built.])
+           passed=no
+       fi
+    done
+
     # Don't do mblock if pmt skipped
     # There *has* to be a better way to check if a value is in a string
     for dir in $skipped_dirs
diff --git a/config/grc_omnithread.m4 b/config/grc_omnithread.m4
new file mode 100644 (file)
index 0000000..627ccdc
--- /dev/null
@@ -0,0 +1,33 @@
+dnl Copyright 2001,2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GRC_OMNITHREAD],[
+    GRC_ENABLE([omnithread])
+
+    AC_CONFIG_FILES([ \
+        omnithread/Makefile \
+    ])
+    
+    passed=yes
+    GRC_BUILD_CONDITIONAL([omnithread],[
+        dnl run_tests is created from run_tests.in.  Make it executable.
+       dnl AC_CONFIG_COMMANDS([run_tests_omnithread], [chmod +x omnithread/run_tests])
+
+    ])
+])
index 924ad88ae36c1e0958c40f971751df674af6a3da..7fc963c392ecbf7a172dd879a5132c2bb2679f12 100644 (file)
@@ -184,6 +184,7 @@ AC_ARG_ENABLE(
 )
 
 build_dirs="config"
+GRC_OMNITHREAD                 dnl must come before gnuradio-core and mblock
 GRC_GNURADIO_CORE
 GRC_USRP
 GRC_GR_USRP                    dnl this must come after GRC_USRP
index cc6c03ac5ea4ecf3484777e2be4c6da5646e1b27..9a8f6736eba96731eaac798780163f5105a8e4fb 100644 (file)
@@ -7,5 +7,5 @@ Name: gnuradio-core
 Description: GNU Software Radio toolkit
 Requires:
 Version: @VERSION@
-Libs: -L${libdir} -lgnuradio-core @FFTW3F_LIBS@
+Libs: -L${libdir} -lgnuradio-core @FFTW3F_LIBS@ @OMNITHREAD_LIBS@
 Cflags: -I${includedir} @DEFINES@ @PTHREAD_CFLAGS@
index 96a8917006ad61a9167c670ffba3c08103009f3e..70a4de08ec061a6998cf73b399962e3257146745 100644 (file)
@@ -24,7 +24,7 @@ include $(top_srcdir)/Makefile.common
 ## Process this file with automake to produce Makefile.in
 
 # We've got to build . before swig
-SUBDIRS = missing runtime filter general gengen g72x reed-solomon omnithread io . swig
+SUBDIRS = missing runtime filter general gengen g72x reed-solomon io . swig
 
 # generate libgnuradio-core.la from the convenience libraries in subdirs
 
@@ -35,7 +35,7 @@ libgnuradio_core_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
 
 libgnuradio_core_qa_la_SOURCES = bug_work_around_6.cc
 libgnuradio_core_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 \
-                               $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
+                                $(LIBGNURADIO_CORE_EXTRA_LDFLAGS)
 
 libgnuradio_core_la_LIBADD  =          \
        filter/libfilter.la             \
@@ -44,9 +44,9 @@ libgnuradio_core_la_LIBADD  =                 \
        gengen/libgengen.la             \
        io/libio.la                     \
        missing/libmissing.la           \
-       omnithread/libomnithread.la     \
        reed-solomon/librs.la           \
        runtime/libruntime.la           \
+       $(OMNITHREAD_LIBS)              \
        $(FFTW3F_LIBS)
 
 libgnuradio_core_qa_la_LIBADD  =       \
diff --git a/gnuradio-core/src/lib/omnithread/Makefile.am b/gnuradio-core/src/lib/omnithread/Makefile.am
deleted file mode 100644 (file)
index de365c1..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright 2003 Free Software Foundation, Inc.
-# 
-# This file is part of GNU Radio
-# 
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-# 
-# GNU Radio 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 General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING.  If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-# 
-
-include $(top_srcdir)/Makefile.common
-
-# This is the omnithread package,
-#   extracted from the omniORB-4.0.1 distribution
-
-# we should do some configure hacking to determine these on the fly
-OMNITHREAD_DEFINES = -DPthreadDraftVersion=10
-
-INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(OMNITHREAD_DEFINES)
-
-noinst_LTLIBRARIES = libomnithread.la
-
-# At this point we only support the posix and nt pthreads i/f...
-
-if OMNITHREAD_POSIX
-libomnithread_la_SOURCES =             \
-       posix.cc
-endif
-
-if OMNITHREAD_NT
-libomnithread_la_SOURCES =             \
-       nt.cc
-endif
-
-libomnithread_la_LIBADD =              \
-       $(PTHREAD_LIBS)
-
-# ... but this code also came with the package
-
-EXTRA_DIST =                           \
-       mach.cc                         \
-       nt.cc                           \
-       posix.cc                        \
-       solaris.cc                      \
-       threaddata.cc                   \
-       vxWorks.cc                      \
-       dir.mk
-
-grinclude_HEADERS =                    \
-       omnithread.h                    \
-       ot_mach.h                       \
-       ot_nt.h                         \
-       ot_posix.h                      \
-       ot_pthread_nt.h                 \
-       ot_solaris.h                    \
-       ot_VxThread.h                   
diff --git a/gnuradio-core/src/lib/omnithread/dir.mk b/gnuradio-core/src/lib/omnithread/dir.mk
deleted file mode 100644 (file)
index d538034..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-ifeq ($(ThreadSystem),Solaris)
-CXXSRCS = solaris.cc
-DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
-endif
-
-ifeq ($(ThreadSystem),Posix)
-CXXSRCS = posix.cc
-DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS) $(OMNITHREAD_POSIX_CPPFLAGS)
-endif
-
-ifeq ($(ThreadSystem),NT)
-CXXSRCS = nt.cc
-DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
-MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
-MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
-MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
-MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
-endif
-
-ifeq ($(ThreadSystem),NTPosix)
-CXXSRCS = posix.cc
-DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
-MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
-MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
-MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
-MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
-endif
-
-ifeq ($(ThreadSystem),Mach)
-CXXSRCS = mach.cc
-DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
-endif
-
-ifeq ($(ThreadSystem),vxWorks)
-CXXSRCS = vxWorks.cc
-OBJS = vxWorks.o
-DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
-endif
-
-LIB_NAME     := omnithread
-LIB_VERSION  := $(OMNITHREAD_VERSION)
-LIB_OBJS     := $(CXXSRCS:.cc=.o)
-LIB_IMPORTS  := $(OMNITHREAD_PLATFORM_LIB)
-
-all:: mkstatic mkshared
-
-export:: mkstatic mkshared
-
-ifdef INSTALLTARGET
-install:: mkstatic mkshared
-endif
-
-vers := $(subst ., ,$(LIB_VERSION))
-ifeq ($(words $(vers)), 2)
-  vers  := _ $(vers)
-  major := ""
-else
-  major := $(word 1, $(vers))
-endif
-
-namespec := $(LIB_NAME) $(vers)
-
-##############################################################################
-# Build Static library
-##############################################################################
-
-ifndef NoStaticLibrary
-
-staticlib := static/$(patsubst %,$(LibNoDebugPattern),$(LIB_NAME)$(major))
-
-mkstatic::
-       @(dir=static; $(CreateDir))
-
-mkstatic:: $(staticlib)
-
-$(staticlib): $(patsubst %, static/%, $(LIB_OBJS))
-       @$(StaticLinkLibrary)
-
-export:: $(staticlib)
-       @$(ExportLibrary)
-
-ifdef INSTALLTARGET
-install:: $(staticlib)
-       @$(InstallLibrary)
-endif
-
-clean::
-       $(RM) static/*.o
-       $(RM) $(staticlib)
-
-veryclean::
-       $(RM) static/*.o
-       $(RM) $(staticlib)
-
-else
-
-mkstatic::
-
-endif
-
-
-##############################################################################
-# Build Shared library
-##############################################################################
-ifdef BuildSharedLibrary
-
-shlib := shared/$(shell $(SharedLibraryFullName) $(namespec))
-
-ifdef Win32Platform
-# in case of Win32 lossage:
-  imps := $(patsubst $(DLLDebugSearchPattern),$(DLLNoDebugSearchPattern), \
-          $(LIB_IMPORTS))
-else
-  imps := $(LIB_IMPORTS)
-endif
-
-mkshared::
-       @(dir=shared; $(CreateDir))
-
-mkshared:: $(shlib)
-
-$(shlib): $(patsubst %, shared/%, $(LIB_OBJS))
-       @(namespec="$(namespec)" extralibs="$(imps)" nodeffile=1; \
-         $(MakeCXXSharedLibrary))
-
-export:: $(shlib)
-       @(namespec="$(namespec)"; \
-          $(ExportSharedLibrary))
-
-ifdef INSTALLTARGET
-install:: $(shlib)
-       @(namespec="$(namespec)"; \
-          $(InstallSharedLibrary))
-endif
-
-clean::
-       $(RM) shared/*.o
-       (dir=shared; $(CleanSharedLibrary))
-
-veryclean::
-       $(RM) shared/*.o
-       @(dir=shared; $(CleanSharedLibrary))
-
-else
-
-mkshared::
-
-endif
-
-##############################################################################
-# Build debug libraries for Win32
-##############################################################################
-ifdef Win32Platform
-
-ifdef BuildSharedLibrary
-
-all:: mkstaticdbug mkshareddbug
-
-export:: mkstaticdbug mkshareddbug
-
-else
-
-all:: mkstaticdbug
-
-export:: mkstaticdbug
-
-endif
-
-
-#####################################################
-#      Static debug libraries
-#####################################################
-
-dbuglib := debug/$(patsubst %,$(LibDebugPattern),$(LIB_NAME)$(major))
-
-mkstaticdbug::
-       @(dir=debug; $(CreateDir))
-
-mkstaticdbug:: $(dbuglib)
-
-$(dbuglib): $(patsubst %, debug/%, $(LIB_OBJS))
-       @$(StaticLinkLibrary)
-
-export:: $(dbuglib)
-       @$(ExportLibrary)
-
-clean::
-       $(RM) debug/*.o
-       $(RM) $(dbuglib)
-
-veryclean::
-       $(RM) debug/*.o
-       $(RM) $(dbuglib)
-
-#####################################################
-#      DLL debug libraries
-#####################################################
-
-ifdef BuildSharedLibrary
-
-dbugshlib := shareddebug/$(shell $(SharedLibraryDebugFullName) $(namespec))
-
-dbugimps  := $(patsubst $(DLLNoDebugSearchPattern),$(DLLDebugSearchPattern), \
-               $(LIB_IMPORTS))
-
-mkshareddbug::
-       @(dir=shareddebug; $(CreateDir))
-
-mkshareddbug:: $(dbugshlib)
-
-$(dbugshlib): $(patsubst %, shareddebug/%, $(LIB_OBJS))
-       (namespec="$(namespec)" debug=1 extralibs="$(dbugimps)" nodeffile=1; \
-         $(MakeCXXSharedLibrary))
-
-export:: $(dbugshlib)
-       @(namespec="$(namespec)" debug=1; \
-          $(ExportSharedLibrary))
-
-clean::
-       $(RM) shareddebug/*.o
-       @(dir=shareddebug; $(CleanSharedLibrary))
-
-veryclean::
-       $(RM) shareddebug/*.o
-       @(dir=shareddebug; $(CleanSharedLibrary))
-
-endif
-endif
-
diff --git a/gnuradio-core/src/lib/omnithread/mach.cc b/gnuradio-core/src/lib/omnithread/mach.cc
deleted file mode 100644 (file)
index 8759bb4..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-//                             Package : omnithread
-// omnithread/mach.cc          Created : 7/97 lars immisch lars@ibp.de
-//
-//    Copyright (C) 1997 Immisch, Becker & Partner
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-
-//
-// Implementation of OMNI thread abstraction for mach threads
-//
-// to the author's pleasure, mach cthreads are very similar to posix threads
-//
-
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <mach/cthreads.h>
-#include "omnithread.h"
-
-#define DB(x) // x
-// #include <iostream> or #include <iostream.h> if DB is on.
-
-#define ERRNO(x) (x)
-
-//
-// static variables
-//
-
-int omni_thread::init_t::count = 0;
-
-omni_mutex* omni_thread::next_id_mutex;
-int omni_thread::next_id = 0;
-
-static int normal_priority;
-static int highest_priority;
-
-static size_t stack_size = 0;
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Mutex
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_mutex::omni_mutex(void)
-{
-  mutex_init(&mach_mutex);     
-}
-
-
-omni_mutex::~omni_mutex(void)
-{
-  mutex_clear(&mach_mutex);    
-}
-
-
-void omni_mutex::lock(void)
-{
-  mutex_lock(&mach_mutex);
-}
-
-
-void omni_mutex::unlock(void)
-{
-  mutex_unlock(&mach_mutex);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Condition variable
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_condition::omni_condition(omni_mutex* m) : mutex(m)
-{
-  condition_init(&mach_cond);
-}
-
-
-omni_condition::~omni_condition(void)
-{
-  condition_clear(&mach_cond);
-}
-
-void
-omni_condition::wait(void)
-{
-  condition_wait(&mach_cond, &mutex->mach_mutex);
-}
-
-typedef struct alarmclock_args {
-  unsigned long secs;
-  unsigned long nsecs;
-  bool wakeup;
-  condition_t condition;
-  mutex_t mutex;
-};
-
-any_t alarmclock(any_t arg)
-{
-  alarmclock_args* alarm = (alarmclock_args*)arg;
-       
-  omni_thread::sleep(alarm->secs, alarm->nsecs);
-
-  mutex_lock(alarm->mutex);
-                       
-  alarm->wakeup = TRUE;
-       
-  condition_signal(alarm->condition);
-               
-  mutex_unlock(alarm->mutex);
-
-  return (any_t)TRUE;
-}
-
-int omni_condition::timedwait(unsigned long abs_secs, unsigned long abs_nsecs)
-{
-  alarmclock_args alarm;
-
-  omni_thread::get_time(&alarm.secs, &alarm.nsecs, 0, 0);
-       
-  if (abs_secs < alarm.secs || (abs_secs == alarm.secs && abs_nsecs <= alarm.nsecs))
-    return ETIMEDOUT;
-
-  alarm.secs = abs_secs - alarm.secs;
-  if (abs_nsecs <= alarm.nsecs) {
-    alarm.nsecs = 1000000 - alarm.nsecs + abs_nsecs;
-    alarm.secs--;
-  }
-  else {
-    alarm.nsecs = abs_nsecs - alarm.nsecs;
-  }
-
-  alarm.mutex = &mutex->mach_mutex;
-  alarm.condition = &mach_cond;
-  alarm.wakeup = FALSE;
-       
-  cthread_t ct = cthread_fork((cthread_fn_t)alarmclock, (any_t)&alarm);
-  cthread_detach(ct);
-       
-  condition_wait(&mach_cond, &mutex->mach_mutex);
-               
-  if (alarm.wakeup) {
-    return 0;
-  }
-       
-  // interrupt the alarmclock thread sleep
-  cthread_abort(ct);
-       
-  // wait until it has signalled the condition
-  condition_wait(&mach_cond, &mutex->mach_mutex);
-
-  return 1;
-}
-
-
-void omni_condition::signal(void)
-{
-  condition_signal(&mach_cond);
-}
-
-
-void omni_condition::broadcast(void)
-{
-  condition_signal(&mach_cond);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Counting semaphore
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_semaphore::omni_semaphore(unsigned int initial) : c(&m)
-{
-  value = initial;
-}
-
-
-omni_semaphore::~omni_semaphore(void)
-{
-}
-
-
-void 
-omni_semaphore::wait(void)
-{
-  omni_mutex_lock l(m);
-
-  while (value == 0)
-    c.wait();
-
-  value--;
-}
-
-
-int
-omni_semaphore::trywait(void)
-{
-  omni_mutex_lock l(m);
-
-  if (value == 0)
-    return 0;
-
-  value--;
-  return 1;
-}
-
-
-void
-omni_semaphore::post(void)
-{
-  omni_mutex_lock l(m);
-
-  if (value == 0)
-    c.signal();
-
-  value++;
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-
-//
-// Initialisation function (gets called before any user code).
-//
-
-omni_thread::init_t::init_t(void)
-{
-  if (count++ != 0)    // only do it once however many objects get created.
-    return;
-
-  //
-  // find base and max priority. 
-  // This is the initial thread, so the max priority of this
-  // thread also applies to any newly created thread.
-  //
-
-  kern_return_t                                error;
-  struct thread_sched_info     info;
-  unsigned int                         info_count = THREAD_SCHED_INFO_COUNT;
-
-  error = thread_info(thread_self(), THREAD_SCHED_INFO, (thread_info_t)&info, &info_count);
-  if (error != KERN_SUCCESS) {
-    DB(cerr << "omni_thread::init: error determining thread_info" << endl);
-    ::exit(1);
-  }
-  else {
-    normal_priority = info.base_priority;
-    highest_priority = info.max_priority;
-  }
-
-  next_id_mutex = new omni_mutex;
-
-  //
-  // Create object for this (i.e. initial) thread.
-  //
-
-  omni_thread* t = new omni_thread;
-
-  if (t->_state != STATE_NEW) {
-    DB(cerr << "omni_thread::init: problem creating initial thread object\n");
-    ::exit(1);
-  }
-
-  t->_state = STATE_RUNNING;
-  
-  t->mach_thread = cthread_self();
-
-  DB(cerr << "initial thread " << t->id() << endl);
-
-  cthread_set_data(t->mach_thread, (any_t)t);
-}
-
-
-//
-// Wrapper for thread creation.
-//
-
-extern "C" void*
-omni_thread_wrapper(void* ptr)
-{
-  omni_thread* me = (omni_thread*)ptr;
-  
-  DB(cerr << "omni_thread::wrapper: thread " << me->id()
-     << " started\n");
-
-  cthread_set_data(cthread_self(), (any_t)me);
-
-  //
-  // Now invoke the thread function with the given argument.
-  //
-
-  if (me->fn_void != NULL) {
-    (*me->fn_void)(me->thread_arg);
-    omni_thread::exit();
-  }
-  
-  if (me->fn_ret != NULL) {
-    void* return_value = (*me->fn_ret)(me->thread_arg);
-    omni_thread::exit(return_value);
-  }
-  
-  if (me->detached) {
-    me->run(me->thread_arg);
-    omni_thread::exit();
-  } else {
-    void* return_value = me->run_undetached(me->thread_arg);
-    omni_thread::exit(return_value);
-  }
-
-  // should never get here.
-
-  return NULL;
-}
-
-
-//
-// Constructors for omni_thread - set up the thread object but don't
-// start it running.
-//
-
-// construct a detached thread running a given function.
-
-omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
-{
-  common_constructor(arg, pri, 1);
-  fn_void = fn;
-  fn_ret = NULL;
-}
-
-// construct an undetached thread running a given function.
-
-omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
-{
-  common_constructor(arg, pri, 0);
-  fn_void = NULL;
-  fn_ret = fn;
-}
-
-// construct a thread which will run either run() or run_undetached().
-
-omni_thread::omni_thread(void* arg, priority_t pri)
-{
-  common_constructor(arg, pri, 1);
-  fn_void = NULL;
-  fn_ret = NULL;
-}
-
-// common part of all constructors.
-
-void omni_thread::common_constructor(void* arg, priority_t pri, int det)
-{
-  _state = STATE_NEW;
-  _priority = pri;
-  
-  next_id_mutex->lock();
-  _id = next_id++;
-  next_id_mutex->unlock();
-  
-  thread_arg = arg;
-  detached = det;      // may be altered in start_undetached()
-
-  _dummy       = 0;
-  _values      = 0;
-  _value_alloc = 0;
-  // posix_thread is set up in initialisation routine or start().
-}
-
-
-//
-// Destructor for omni_thread.
-//
-
-omni_thread::~omni_thread(void)
-{
-  DB(cerr << "destructor called for thread " << id() << endl);
-  if (_values) {
-    for (key_t i=0; i < _value_alloc; i++) {
-      if (_values[i]) {
-       delete _values[i];
-      }
-    }
-    delete [] _values;
-  }
-}
-
-
-//
-// Start the thread
-//
-
-void 
-omni_thread::start(void)
-{
-  omni_mutex_lock l(mutex);
-
-  int rc;
-
-  if (_state != STATE_NEW)
-    throw omni_thread_invalid();
-
-  mach_thread = cthread_fork(omni_thread_wrapper, (any_t)this);
-       
-  _state = STATE_RUNNING;
-
-  if (detached) {
-    cthread_detach(mach_thread);
-  }
-}
-
-//
-// Start a thread which will run the member function run_undetached().
-//
-
-void
-omni_thread::start_undetached(void)
-{
-  if ((fn_void != NULL) || (fn_ret != NULL))
-    throw omni_thread_invalid();
-
-  detached = 0;
-  start();
-}
-
-
-//
-// join - simply check error conditions & call cthread_join.
-//
-
-void 
-omni_thread::join(void** status)
-{
-  mutex.lock();
-
-  if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
-    mutex.unlock();
-    throw omni_thread_invalid();
-  }
-
-  mutex.unlock();
-
-  if (this == self())  
-    throw omni_thread_invalid();
-
-  if (detached)
-    throw omni_thread_invalid();
-
-  DB(cerr << "omni_thread::join: doing cthread_join\n");
-
- *status = cthread_join(mach_thread);
-
-  delete this;
-}
-
-
-//
-// Change this thread's priority.
-//
-
-void
-omni_thread::set_priority(priority_t pri)
-{
-  omni_mutex_lock l(mutex);
-
-  if (_state != STATE_RUNNING)
-    throw omni_thread_invalid();
-
-  _priority = pri;
-
-  kern_return_t rc = cthread_priority(mach_thread, mach_priority(pri), FALSE);
-       
-  if (rc != KERN_SUCCESS)
-    throw omni_thread_fatal(errno);
-}
-
-//
-// create - construct a new thread object and start it running.  Returns thread
-// object if successful, null pointer if not.
-//
-
-// detached version
-
-omni_thread* 
-omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
-{
-  omni_thread* t = new omni_thread(fn, arg, pri);
-
-  t->start();
-
-  return t;
-}
-
-// undetached version
-
-omni_thread*
-omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
-{
-  omni_thread* t = new omni_thread(fn, arg, pri);
-
-  t->start();
-
-  return t;
-}
-
-//
-// exit() _must_ lock the mutex even in the case of a detached thread.  This is
-// because a thread may run to completion before the thread that created it has
-// had a chance to get out of start().  By locking the mutex we ensure that the
-// creating thread must have reached the end of start() before we delete the
-// thread object.  Of course, once the call to start() returns, the user can
-// still incorrectly refer to the thread object, but that's their problem.
-//
-
-void omni_thread::exit(void* return_value)
-{
-  omni_thread* me = self();
-
-  if (me)
-    {
-      me->mutex.lock();
-
-      if (me->_state != STATE_RUNNING)
-       DB(cerr << "omni_thread::exit: thread not in \"running\" state\n");
-
-      me->_state = STATE_TERMINATED;
-
-      me->mutex.unlock();
-
-      DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
-        << me->detached << " return value " << return_value << endl);
-
-      if (me->detached)
-       delete me;
-    }
-  else
-    {
-      DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
-    }
-  cthread_exit(return_value);
-}
-
-omni_thread* omni_thread::self(void)
-{
-  omni_thread* me;
-
-  me = (omni_thread*)cthread_data(cthread_self());
-
-  if (!me) {
-    // This thread is not created by omni_thread::start because it
-    // doesn't has a class omni_thread instance attached to its key.
-    DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
-  }
-       
-  return me;
-}
-
-void omni_thread::yield(void)
-{
-  cthread_yield();
-}
-
-#define MAX_SLEEP_SECONDS (unsigned)4294966    // (2**32-2)/1000
-
-void
-omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
-{
-  if (secs <= MAX_SLEEP_SECONDS) {
-    thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, secs * 1000 + nanosecs / 1000000);
-    return;
-  }
-
-  unsigned no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
-
-  for (unsigned i = 0; i < no_of_max_sleeps; i++)
-    thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, MAX_SLEEP_SECONDS * 1000);
-
-  thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, 
-               (secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
-       
-  return;
-}
-
-void
-omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
-                     unsigned long rel_sec, unsigned long rel_nsec)
-{
-  int rc;
-  unsigned long tv_sec;
-  unsigned long tv_nsec;
-  struct timeval tv;
-       
-  rc = gettimeofday(&tv, NULL); 
-  if (rc)      throw omni_thread_fatal(rc);
-
-  tv_sec = tv.tv_sec;
-  tv_nsec = tv.tv_usec * 1000;
-
-  tv_nsec += rel_nsec;
-  tv_sec += rel_sec + tv_nsec / 1000000000;
-  tv_nsec = tv_nsec % 1000000000;
-
-  *abs_sec = tv_sec;
-  *abs_nsec = tv_nsec;
-}
-
-
-int 
-omni_thread::mach_priority(priority_t pri)
-{
-  switch (pri) {
-
-  case PRIORITY_LOW:
-    return 0;
-
-  case PRIORITY_NORMAL:
-    return normal_priority;
-
-  case PRIORITY_HIGH:
-    return highest_priority;
-
-  default:
-    return -1;
-  }
-}
-
-void
-omni_thread::stacksize(unsigned long sz)
-{
-  stack_size = sz;
-}
-
-unsigned long
-omni_thread::stacksize()
-{
-  return stack_size;
-}
-
-
-//
-// Dummy thread
-//
-
-#error This dummy thread code is not tested. It might work if you're lucky.
-
-class omni_thread_dummy : public omni_thread {
-public:
-  inline omni_thread_dummy() : omni_thread()
-  {
-    _dummy = 1;
-    _state = STATE_RUNNING;
-    mach_thread = cthread_self();
-    cthread_set_data(mach_thread, (any_t)this));
-  }
-  inline ~omni_thread_dummy()
-  {
-    cthread_set_data(mach_thread, (any_t)0));
-  }
-};
-
-omni_thread*
-omni_thread::create_dummy()
-{
-  if (omni_thread::self())
-    throw omni_thread_invalid();
-
-  return new omni_thread_dummy;
-}
-
-void
-omni_thread::release_dummy()
-{
-  omni_thread* self = omni_thread::self();
-  if (!self || !self->_dummy)
-    throw omni_thread_invalid();
-
-  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
-  delete dummy;
-}
-
-
-#define INSIDE_THREAD_IMPL_CC
-#include "threaddata.cc"
-#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/nt.cc b/gnuradio-core/src/lib/omnithread/nt.cc
deleted file mode 100644 (file)
index 3853f01..0000000
+++ /dev/null
@@ -1,969 +0,0 @@
-//                             Package : omnithread
-// omnithread/nt.cc            Created : 6/95 tjr
-//
-//    Copyright (C) 2006 Free Software Foundation, Inc.
-//    Copyright (C) 1995-1999 AT&T Laboratories Cambridge
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-
-//
-// Implementation of OMNI thread abstraction for NT threads
-//
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <errno.h>
-#include <WinError.h>
-#include <omnithread.h>
-#include <process.h>
-
-#define DB(x) // x 
-//#include <iostream.h> or #include <iostream> if DB is on.
-
-static void get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec);
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Mutex
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_mutex::omni_mutex(void)
-{
-    InitializeCriticalSection(&crit);
-}
-
-omni_mutex::~omni_mutex(void)
-{
-    DeleteCriticalSection(&crit);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Condition variable
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-//
-// Condition variables are tricky to implement using NT synchronisation
-// primitives, since none of them have the atomic "release mutex and wait to be
-// signalled" which is central to the idea of a condition variable.  To get
-// around this the solution is to record which threads are waiting and
-// explicitly wake up those threads.
-//
-// Here we implement a condition variable using a list of waiting threads
-// (protected by a critical section), and a per-thread semaphore (which
-// actually only needs to be a binary semaphore).
-//
-// To wait on the cv, a thread puts itself on the list of waiting threads for
-// that cv, then releases the mutex and waits on its own personal semaphore.  A
-// signalling thread simply takes a thread from the head of the list and kicks
-// that thread's semaphore.  Broadcast is simply implemented by kicking the
-// semaphore of each waiting thread.
-//
-// The only other tricky part comes when a thread gets a timeout from a timed
-// wait on its semaphore.  Between returning with a timeout from the wait and
-// entering the critical section, a signalling thread could get in, kick the
-// waiting thread's semaphore and remove it from the list.  If this happens,
-// the waiting thread's semaphore is now out of step so it needs resetting, and
-// the thread should indicate that it was signalled rather than that it timed
-// out.
-//
-// It is possible that the thread calling wait or timedwait is not a
-// omni_thread. In this case we have to provide a temporary data structure,
-// i.e. for the duration of the call, for the thread to link itself on the
-// list of waiting threads. _internal_omni_thread_dummy provides such
-// a data structure and _internal_omni_thread_helper is a helper class to
-// deal with this special case for wait() and timedwait(). Once created,
-// the _internal_omni_thread_dummy is cached for use by the next wait() or
-// timedwait() call from a non-omni_thread. This is probably worth doing
-// because creating a Semaphore is quite heavy weight.
-
-class _internal_omni_thread_helper;
-
-class _internal_omni_thread_dummy : public omni_thread {
-public:
-  inline _internal_omni_thread_dummy() : next(0) { }
-  inline ~_internal_omni_thread_dummy() { }
-  friend class _internal_omni_thread_helper;
-private:
-  _internal_omni_thread_dummy* next;
-};
-
-class _internal_omni_thread_helper {
-public:
-  inline _internal_omni_thread_helper()  { 
-    d = 0;
-    t = omni_thread::self();
-    if (!t) {
-      omni_mutex_lock sync(cachelock);
-      if (cache) {
-       d = cache;
-       cache = cache->next;
-      }
-      else {
-       d = new _internal_omni_thread_dummy;
-      }
-      t = d;
-    }
-  }
-  inline ~_internal_omni_thread_helper() { 
-    if (d) {
-      omni_mutex_lock sync(cachelock);
-      d->next = cache;
-      cache = d;
-    }
-  }
-  inline operator omni_thread* () { return t; }
-  inline omni_thread* operator->() { return t; }
-
-  static _internal_omni_thread_dummy* cache;
-  static omni_mutex                   cachelock;
-
-private:
-  _internal_omni_thread_dummy* d;
-  omni_thread*                 t;
-};
-
-_internal_omni_thread_dummy* _internal_omni_thread_helper::cache = 0;
-omni_mutex                   _internal_omni_thread_helper::cachelock;
-
-
-omni_condition::omni_condition(omni_mutex* m) : mutex(m)
-{
-    InitializeCriticalSection(&crit);
-    waiting_head = waiting_tail = NULL;
-}
-
-
-omni_condition::~omni_condition(void)
-{
-    DeleteCriticalSection(&crit);
-    DB( if (waiting_head != NULL) {
-       cerr << "omni_condition::~omni_condition: list of waiting threads "
-            << "is not empty\n";
-    } )
-}
-
-
-void
-omni_condition::wait(void)
-{
-    _internal_omni_thread_helper me;
-
-    EnterCriticalSection(&crit);
-
-    me->cond_next = NULL;
-    me->cond_prev = waiting_tail;
-    if (waiting_head == NULL)
-       waiting_head = me;
-    else
-       waiting_tail->cond_next = me;
-    waiting_tail = me;
-    me->cond_waiting = TRUE;
-
-    LeaveCriticalSection(&crit);
-
-    mutex->unlock();
-
-    DWORD result = WaitForSingleObject(me->cond_semaphore, INFINITE);
-
-    mutex->lock();
-
-    if (result != WAIT_OBJECT_0)
-       throw omni_thread_fatal(GetLastError());
-}
-
-
-int
-omni_condition::timedwait(unsigned long abs_sec, unsigned long abs_nsec)
-{
-    _internal_omni_thread_helper me;
-
-    EnterCriticalSection(&crit);
-
-    me->cond_next = NULL;
-    me->cond_prev = waiting_tail;
-    if (waiting_head == NULL)
-       waiting_head = me;
-    else
-       waiting_tail->cond_next = me;
-    waiting_tail = me;
-    me->cond_waiting = TRUE;
-
-    LeaveCriticalSection(&crit);
-
-    mutex->unlock();
-
-    unsigned long now_sec, now_nsec;
-
-    get_time_now(&now_sec, &now_nsec);
-
-    DWORD timeout;
-    if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec)))
-      timeout = 0;
-    else {
-      timeout = (abs_sec-now_sec) * 1000;
-
-      if( abs_nsec < now_nsec )  timeout -= (now_nsec-abs_nsec) / 1000000;
-      else                       timeout += (abs_nsec-now_nsec) / 1000000;
-    }
-
-    DWORD result = WaitForSingleObject(me->cond_semaphore, timeout);
-
-    if (result == WAIT_TIMEOUT) {
-       EnterCriticalSection(&crit);
-
-       if (me->cond_waiting) {
-           if (me->cond_prev != NULL)
-               me->cond_prev->cond_next = me->cond_next;
-           else
-               waiting_head = me->cond_next;
-           if (me->cond_next != NULL)
-               me->cond_next->cond_prev = me->cond_prev;
-           else
-               waiting_tail = me->cond_prev;
-           me->cond_waiting = FALSE;
-
-           LeaveCriticalSection(&crit);
-
-           mutex->lock();
-           return 0;
-       }
-
-       //
-       // We timed out but another thread still signalled us.  Wait for
-       // the semaphore (it _must_ have been signalled) to decrement it
-       // again.  Return that we were signalled, not that we timed out.
-       //
-
-       LeaveCriticalSection(&crit);
-
-       result = WaitForSingleObject(me->cond_semaphore, INFINITE);
-    }
-
-    if (result != WAIT_OBJECT_0)
-       throw omni_thread_fatal(GetLastError());
-
-    mutex->lock();
-    return 1;
-}
-
-
-void
-omni_condition::signal(void)
-{
-    EnterCriticalSection(&crit);
-
-    if (waiting_head != NULL) {
-       omni_thread* t = waiting_head;
-       waiting_head = t->cond_next;
-       if (waiting_head == NULL)
-           waiting_tail = NULL;
-       else
-           waiting_head->cond_prev = NULL;
-       t->cond_waiting = FALSE;
-
-       if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
-           int rc = GetLastError();
-           LeaveCriticalSection(&crit);
-           throw omni_thread_fatal(rc);
-       }
-    }
-
-    LeaveCriticalSection(&crit);
-}
-
-
-void
-omni_condition::broadcast(void)
-{
-    EnterCriticalSection(&crit);
-
-    while (waiting_head != NULL) {
-       omni_thread* t = waiting_head;
-       waiting_head = t->cond_next;
-       if (waiting_head == NULL)
-           waiting_tail = NULL;
-       else
-           waiting_head->cond_prev = NULL;
-       t->cond_waiting = FALSE;
-
-       if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
-           int rc = GetLastError();
-           LeaveCriticalSection(&crit);
-           throw omni_thread_fatal(rc);
-       }
-    }
-
-    LeaveCriticalSection(&crit);
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Counting semaphore
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-#define SEMAPHORE_MAX 0x7fffffff
-
-
-omni_semaphore::omni_semaphore(unsigned int initial, unsigned int max_count)
-{
-    if (max_count > SEMAPHORE_MAX)
-      max_count= SEMAPHORE_MAX;
-
-    nt_sem = CreateSemaphore(NULL, initial, max_count, NULL);
-
-    if (nt_sem == NULL) {
-      DB( cerr << "omni_semaphore::omni_semaphore: CreateSemaphore error "
-            << GetLastError() << endl );
-      throw omni_thread_fatal(GetLastError());
-    }
-}
-
-
-omni_semaphore::~omni_semaphore(void)
-{
-  if (!CloseHandle(nt_sem)) {
-    DB( cerr << "omni_semaphore::~omni_semaphore: CloseHandle error "
-            << GetLastError() << endl );
-    throw omni_thread_fatal(GetLastError());
-  }
-}
-
-
-void
-omni_semaphore::wait(void)
-{
-    if (WaitForSingleObject(nt_sem, INFINITE) != WAIT_OBJECT_0)
-       throw omni_thread_fatal(GetLastError());
-}
-
-
-int
-omni_semaphore::trywait(void)
-{
-    switch (WaitForSingleObject(nt_sem, 0)) {
-
-    case WAIT_OBJECT_0:
-       return 1;
-    case WAIT_TIMEOUT:
-       return 0;
-    }
-
-    throw omni_thread_fatal(GetLastError());
-    return 0; /* keep msvc++ happy */
-}
-
-
-void
-omni_semaphore::post(void)
-{
-    if (!ReleaseSemaphore(nt_sem, 1, NULL)
-       && GetLastError() != ERROR_TOO_MANY_POSTS )     // MinGW fix--see ticket:95 in trac
-       throw omni_thread_fatal(GetLastError());
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-//
-// Static variables
-//
-
-omni_mutex* omni_thread::next_id_mutex;
-int omni_thread::next_id = 0;
-static DWORD self_tls_index;
-
-static unsigned int stack_size = 0;
-
-//
-// Initialisation function (gets called before any user code).
-//
-
-static int& count() {
-  static int the_count = 0;
-  return the_count;
-}
-
-omni_thread::init_t::init_t(void)
-{
-    if (count()++ != 0)        // only do it once however many objects get created.
-       return;
-
-    DB(cerr << "omni_thread::init: NT implementation initialising\n");
-
-    self_tls_index = TlsAlloc();
-
-    if (self_tls_index == 0xffffffff)
-       throw omni_thread_fatal(GetLastError());
-
-    next_id_mutex = new omni_mutex;
-
-    //
-    // Create object for this (i.e. initial) thread.
-    //
-
-    omni_thread* t = new omni_thread;
-
-    t->_state = STATE_RUNNING;
-
-    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
-                        GetCurrentProcess(), &t->handle,
-                        0, FALSE, DUPLICATE_SAME_ACCESS))
-       throw omni_thread_fatal(GetLastError());
-
-    t->nt_id = GetCurrentThreadId();
-
-    DB(cerr << "initial thread " << t->id() << " NT thread id " << t->nt_id
-       << endl);
-
-    if (!TlsSetValue(self_tls_index, (LPVOID)t))
-       throw omni_thread_fatal(GetLastError());
-
-    if (!SetThreadPriority(t->handle, nt_priority(PRIORITY_NORMAL)))
-       throw omni_thread_fatal(GetLastError());
-}
-
-omni_thread::init_t::~init_t(void)
-{
-    if (--count() != 0) return;
-
-    omni_thread* self = omni_thread::self();
-    if (!self) return;
-
-    TlsSetValue(self_tls_index, (LPVOID)0);
-    delete self;
-
-    delete next_id_mutex;
-
-    TlsFree(self_tls_index);
-}
-
-//
-// Wrapper for thread creation.
-//
-
-extern "C" 
-#ifndef __BCPLUSPLUS__
-unsigned __stdcall
-#else
-void _USERENTRY
-#endif
-omni_thread_wrapper(void* ptr)
-{
-    omni_thread* me = (omni_thread*)ptr;
-
-    DB(cerr << "omni_thread_wrapper: thread " << me->id()
-       << " started\n");
-
-    if (!TlsSetValue(self_tls_index, (LPVOID)me))
-       throw omni_thread_fatal(GetLastError());
-
-    //
-    // Now invoke the thread function with the given argument.
-    //
-
-    if (me->fn_void != NULL) {
-       (*me->fn_void)(me->thread_arg);
-       omni_thread::exit();
-    }
-
-    if (me->fn_ret != NULL) {
-       void* return_value = (*me->fn_ret)(me->thread_arg);
-       omni_thread::exit(return_value);
-    }
-
-    if (me->detached) {
-       me->run(me->thread_arg);
-       omni_thread::exit();
-    } else {
-       void* return_value = me->run_undetached(me->thread_arg);
-       omni_thread::exit(return_value);
-    }
-
-    // should never get here.
-#ifndef __BCPLUSPLUS__
-    return 0;
-#endif
-}
-
-
-//
-// Constructors for omni_thread - set up the thread object but don't
-// start it running.
-//
-
-// construct a detached thread running a given function.
-
-omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 1);
-    fn_void = fn;
-    fn_ret = NULL;
-}
-
-// construct an undetached thread running a given function.
-
-omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 0);
-    fn_void = NULL;
-    fn_ret = fn;
-}
-
-// construct a thread which will run either run() or run_undetached().
-
-omni_thread::omni_thread(void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 1);
-    fn_void = NULL;
-    fn_ret = NULL;
-}
-
-// common part of all constructors.
-
-void
-omni_thread::common_constructor(void* arg, priority_t pri, int det)
-{
-    _state = STATE_NEW;
-    _priority = pri;
-
-    next_id_mutex->lock();
-    _id = next_id++;
-    next_id_mutex->unlock();
-
-    thread_arg = arg;
-    detached = det;    // may be altered in start_undetached()
-
-    cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL);
-
-    if (cond_semaphore == NULL)
-       throw omni_thread_fatal(GetLastError());
-
-    cond_next = cond_prev = NULL;
-    cond_waiting = FALSE;
-
-    handle = NULL;
-
-    _dummy       = 0;
-    _values      = 0;
-    _value_alloc = 0;
-}
-
-
-//
-// Destructor for omni_thread.
-//
-
-omni_thread::~omni_thread(void)
-{
-    DB(cerr << "destructor called for thread " << id() << endl);
-    if (_values) {
-        for (key_t i=0; i < _value_alloc; i++) {
-           if (_values[i]) {
-               delete _values[i];
-           }
-        }
-       delete [] _values;
-    }
-    if (handle && !CloseHandle(handle))
-       throw omni_thread_fatal(GetLastError());
-    if (cond_semaphore && !CloseHandle(cond_semaphore))
-       throw omni_thread_fatal(GetLastError());
-}
-
-
-//
-// Start the thread
-//
-
-void
-omni_thread::start(void)
-{
-    omni_mutex_lock l(mutex);
-
-    if (_state != STATE_NEW)
-       throw omni_thread_invalid();
-
-#ifndef __BCPLUSPLUS__
-    // MSVC++ or compatiable
-    unsigned int t;
-    handle = (HANDLE)_beginthreadex(
-                        NULL,
-                       stack_size,
-                       omni_thread_wrapper,
-                       (LPVOID)this,
-                       CREATE_SUSPENDED, 
-                       &t);
-    nt_id = t;
-    if (handle == NULL)
-      throw omni_thread_fatal(GetLastError());
-#else
-    // Borland C++
-    handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,
-                                   stack_size,
-                                   (void*)this,
-                                   NULL,
-                                   CREATE_SUSPENDED,
-                                   &nt_id);
-    if (handle == INVALID_HANDLE_VALUE)
-      throw omni_thread_fatal(errno);
-#endif
-
-    if (!SetThreadPriority(handle, nt_priority(_priority)))
-      throw omni_thread_fatal(GetLastError());
-
-    if (ResumeThread(handle) == 0xffffffff)
-       throw omni_thread_fatal(GetLastError());
-
-    _state = STATE_RUNNING;
-}
-
-
-//
-// Start a thread which will run the member function run_undetached().
-//
-
-void
-omni_thread::start_undetached(void)
-{
-    if ((fn_void != NULL) || (fn_ret != NULL))
-       throw omni_thread_invalid();
-
-    detached = 0;
-    start();
-}
-
-
-//
-// join - simply check error conditions & call WaitForSingleObject.
-//
-
-void
-omni_thread::join(void** status)
-{
-    mutex.lock();
-
-    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
-       mutex.unlock();
-       throw omni_thread_invalid();
-    }
-
-    mutex.unlock();
-
-    if (this == self())
-       throw omni_thread_invalid();
-
-    if (detached)
-       throw omni_thread_invalid();
-
-    DB(cerr << "omni_thread::join: doing WaitForSingleObject\n");
-
-    if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0)
-       throw omni_thread_fatal(GetLastError());
-
-    DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n");
-
-    if (status)
-      *status = return_val;
-
-    delete this;
-}
-
-
-//
-// Change this thread's priority.
-//
-
-void
-omni_thread::set_priority(priority_t pri)
-{
-    omni_mutex_lock l(mutex);
-
-    if (_state != STATE_RUNNING)
-       throw omni_thread_invalid();
-
-    _priority = pri;
-
-    if (!SetThreadPriority(handle, nt_priority(pri)))
-       throw omni_thread_fatal(GetLastError());
-}
-
-
-//
-// create - construct a new thread object and start it running.  Returns thread
-// object if successful, null pointer if not.
-//
-
-// detached version
-
-omni_thread*
-omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
-{
-    omni_thread* t = new omni_thread(fn, arg, pri);
-    t->start();
-    return t;
-}
-
-// undetached version
-
-omni_thread*
-omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
-{
-    omni_thread* t = new omni_thread(fn, arg, pri);
-    t->start();
-    return t;
-}
-
-
-//
-// exit() _must_ lock the mutex even in the case of a detached thread.  This is
-// because a thread may run to completion before the thread that created it has
-// had a chance to get out of start().  By locking the mutex we ensure that the
-// creating thread must have reached the end of start() before we delete the
-// thread object.  Of course, once the call to start() returns, the user can
-// still incorrectly refer to the thread object, but that's their problem.
-//
-
-void
-omni_thread::exit(void* return_value)
-{
-    omni_thread* me = self();
-
-    if (me)
-      {
-       me->mutex.lock();
-
-       me->_state = STATE_TERMINATED;
-
-       me->mutex.unlock();
-
-       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
-          << me->detached << " return value " << return_value << endl);
-
-       if (me->detached) {
-         delete me;
-       } else {
-         me->return_val = return_value;
-       }
-      }
-    else
-      {
-       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
-      }
-#ifndef __BCPLUSPLUS__
-    // MSVC++ or compatiable
-    //   _endthreadex() does not automatically closes the thread handle.
-    //   The omni_thread dtor closes the thread handle.
-    _endthreadex(0);
-#else
-    // Borland C++
-    //   _endthread() does not automatically closes the thread handle.
-    //   _endthreadex() is only available if __MFC_COMPAT__ is defined and
-    //   all it does is to call _endthread().
-    _endthread();
-#endif
-}
-
-
-omni_thread*
-omni_thread::self(void)
-{
-    LPVOID me;
-
-    me = TlsGetValue(self_tls_index);
-
-    if (me == NULL) {
-      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
-    }
-    return (omni_thread*)me;
-}
-
-
-void
-omni_thread::yield(void)
-{
-    Sleep(0);
-}
-
-
-#define MAX_SLEEP_SECONDS (DWORD)4294966       // (2**32-2)/1000
-
-void
-omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
-{
-    if (secs <= MAX_SLEEP_SECONDS) {
-       Sleep(secs * 1000 + nanosecs / 1000000);
-       return;
-    }
-
-    DWORD no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
-
-    for (DWORD i = 0; i < no_of_max_sleeps; i++)
-       Sleep(MAX_SLEEP_SECONDS * 1000);
-
-    Sleep((secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
-}
-
-
-void
-omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
-                     unsigned long rel_sec, unsigned long rel_nsec)
-{
-    get_time_now(abs_sec, abs_nsec);
-    *abs_nsec += rel_nsec;
-    *abs_sec += rel_sec + *abs_nsec / 1000000000;
-    *abs_nsec = *abs_nsec % 1000000000;
-}
-
-
-int
-omni_thread::nt_priority(priority_t pri)
-{
-    switch (pri) {
-
-    case PRIORITY_LOW:
-       return THREAD_PRIORITY_LOWEST;
-
-    case PRIORITY_NORMAL:
-       return THREAD_PRIORITY_NORMAL;
-
-    case PRIORITY_HIGH:
-       return THREAD_PRIORITY_HIGHEST;
-    }
-
-    throw omni_thread_invalid();
-    return 0; /* keep msvc++ happy */
-}
-
-
-static void
-get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec)
-{
-    static int days_in_preceding_months[12]
-       = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-    static int days_in_preceding_months_leap[12]
-       = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
-
-    SYSTEMTIME st;
-
-    GetSystemTime(&st);
-    *abs_nsec = st.wMilliseconds * 1000000;
-
-    // this formula should work until 1st March 2100
-
-    DWORD days = ((st.wYear - 1970) * 365 + (st.wYear - 1969) / 4
-                 + ((st.wYear % 4)
-                    ? days_in_preceding_months[st.wMonth - 1]
-                    : days_in_preceding_months_leap[st.wMonth - 1])
-                 + st.wDay - 1);
-
-    *abs_sec = st.wSecond + 60 * (st.wMinute + 60 * (st.wHour + 24 * days));
-}
-
-void
-omni_thread::stacksize(unsigned long sz)
-{
-  stack_size = sz;
-}
-
-unsigned long
-omni_thread::stacksize()
-{
-  return stack_size;
-}
-
-//
-// Dummy thread
-//
-
-class omni_thread_dummy : public omni_thread {
-public:
-  inline omni_thread_dummy() : omni_thread()
-  {
-    _dummy = 1;
-    _state = STATE_RUNNING;
-
-    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
-                        GetCurrentProcess(), &handle,
-                        0, FALSE, DUPLICATE_SAME_ACCESS))
-      throw omni_thread_fatal(GetLastError());
-
-    nt_id = GetCurrentThreadId();
-
-    if (!TlsSetValue(self_tls_index, (LPVOID)this))
-      throw omni_thread_fatal(GetLastError());
-  }
-  inline ~omni_thread_dummy()
-  {
-    if (!TlsSetValue(self_tls_index, (LPVOID)0))
-      throw omni_thread_fatal(GetLastError());
-  }
-};
-
-omni_thread*
-omni_thread::create_dummy()
-{
-  if (omni_thread::self())
-    throw omni_thread_invalid();
-
-  return new omni_thread_dummy;
-}
-
-void
-omni_thread::release_dummy()
-{
-  omni_thread* self = omni_thread::self();
-  if (!self || !self->_dummy)
-    throw omni_thread_invalid();
-
-  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
-  delete dummy;
-}
-
-
-#if defined(__DMC__) && defined(_WINDLL)
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
-  return TRUE;
-}
-#endif
-
-
-#define INSIDE_THREAD_IMPL_CC
-#include "threaddata.cc"
-#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/omnithread.h b/gnuradio-core/src/lib/omnithread/omnithread.h
deleted file mode 100644 (file)
index b6df34d..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-// -*- Mode: C++; -*-
-//                             Package : omnithread
-// omnithread.h                        Created : 7/94 tjr
-//
-//    Copyright (C) 2006 Free Software Foundation, Inc.
-//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-
-//
-// Interface to OMNI thread abstraction.
-//
-// This file declares classes for threads and synchronisation objects
-// (mutexes, condition variables and counting semaphores).
-//
-// Wherever a seemingly arbitrary choice has had to be made as to the interface
-// provided, the intention here has been to be as POSIX-like as possible.  This
-// is why there is no semaphore timed wait, for example.
-//
-
-#ifndef __omnithread_h_
-#define __omnithread_h_
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-class omni_mutex;
-class omni_condition;
-class omni_semaphore;
-class omni_thread;
-
-//
-// OMNI_THREAD_EXPOSE can be defined as public or protected to expose the
-// implementation class - this may be useful for debugging.  Hopefully this
-// won't change the underlying structure which the compiler generates so that
-// this can work without recompiling the library.
-//
-
-#ifndef OMNI_THREAD_EXPOSE
-#define OMNI_THREAD_EXPOSE private
-#endif
-
-//
-// Include implementation-specific header file.
-//
-// This must define 4 CPP macros of the form OMNI_x_IMPLEMENTATION for mutex,
-// condition variable, semaphore and thread.  Each should define any
-// implementation-specific members of the corresponding classes.
-//
-
-
-//
-// For now, we assume they've always got a Posix Threads implementation.
-// If not, it'll take some configure hacking to sort it out, along with
-// the relevant libraries to link with, etc.
-//
-
-#if !defined(OMNITHREAD_POSIX) && !defined(OMNITHREAD_NT) && defined HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(OMNITHREAD_POSIX)
-#include <ot_posix.h>
-
-#elif defined(OMNITHREAD_NT)
-#include <ot_nt.h>
-
-#ifdef _MSC_VER
-
-// Using MSVC++ to compile. If compiling library as a DLL,
-// define _OMNITHREAD_DLL. If compiling as a statuc library, define
-// _WINSTATIC
-// If compiling an application that is to be statically linked to omnithread,
-// define _WINSTATIC (if the application is  to be dynamically linked, 
-// there is no need to define any of these macros).
-
-#if defined (_OMNITHREAD_DLL) && defined(_WINSTATIC)
-#error "Both _OMNITHREAD_DLL and _WINSTATIC are defined."
-#elif defined(_OMNITHREAD_DLL)
-#define _OMNITHREAD_NTDLL_ __declspec(dllexport)
-#elif !defined(_WINSTATIC)
-#define _OMNITHREAD_NTDLL_ __declspec(dllimport)
-#elif defined(_WINSTATIC)
-#define _OMNITHREAD_NTDLL_
-#endif
- // _OMNITHREAD_DLL && _WINSTATIC
-
-#else
-
-// Not using MSVC++ to compile
-#define _OMNITHREAD_NTDLL_
-
-#endif
- // _MSC_VER
-#elif defined(__vxWorks__)
-#include <ot_VxThread.h>
-
-#elif defined(__sunos__)
-#if __OSVERSION__ != 5
-// XXX Workaround for SUN C++ compiler (seen on 4.2) Template.DB code
-//     regeneration bug. See omniORB2/CORBA_sysdep.h for details.
-#if !defined(__SUNPRO_CC) || __OSVERSION__ != '5'
-#error "Only SunOS 5.x or later is supported."
-#endif
-#endif
-#ifdef UseSolarisThreads
-#include <ot_solaris.h>
-#else
-#include <ot_posix.h>
-#endif
-
-#elif defined(__rtems__)
-#include <ot_posix.h>
-#include <sched.h>
-
-#elif defined(__macos__)
-#include <ot_posix.h>
-#include <sched.h>
-
-#else
-#error "No implementation header file"
-#endif
-
-
-#if !defined(__WIN32__)
-#define _OMNITHREAD_NTDLL_
-#endif
-
-#if (!defined(OMNI_MUTEX_IMPLEMENTATION)        || \
-     !defined(OMNI_MUTEX_LOCK_IMPLEMENTATION)   || \
-     !defined(OMNI_MUTEX_TRYLOCK_IMPLEMENTATION)|| \
-     !defined(OMNI_MUTEX_UNLOCK_IMPLEMENTATION) || \
-     !defined(OMNI_CONDITION_IMPLEMENTATION)    || \
-     !defined(OMNI_SEMAPHORE_IMPLEMENTATION)    || \
-     !defined(OMNI_THREAD_IMPLEMENTATION))
-#error "Implementation header file incomplete"
-#endif
-
-
-//
-// This exception is thrown in the event of a fatal error.
-//
-
-class _OMNITHREAD_NTDLL_ omni_thread_fatal {
-public:
-    int error;
-    omni_thread_fatal(int e = 0) : error(e) {}
-};
-
-
-//
-// This exception is thrown when an operation is invoked with invalid
-// arguments.
-//
-
-class _OMNITHREAD_NTDLL_ omni_thread_invalid {};
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Mutex
-//
-///////////////////////////////////////////////////////////////////////////
-
-class _OMNITHREAD_NTDLL_ omni_mutex {
-
-public:
-    omni_mutex(void);
-    ~omni_mutex(void);
-
-    inline void lock(void)    { OMNI_MUTEX_LOCK_IMPLEMENTATION   }
-    inline void unlock(void)  { OMNI_MUTEX_UNLOCK_IMPLEMENTATION }
-    inline int trylock(void)  { return OMNI_MUTEX_TRYLOCK_IMPLEMENTATION }
-       // if mutex is unlocked, lock it and return 1 (true).
-       // If it's already locked then return 0 (false).
-
-    inline void acquire(void) { lock(); }
-    inline void release(void) { unlock(); }
-       // the names lock and unlock are preferred over acquire and release
-       // since we are attempting to be as POSIX-like as possible.
-
-    friend class omni_condition;
-
-private:
-    // dummy copy constructor and operator= to prevent copying
-    omni_mutex(const omni_mutex&);
-    omni_mutex& operator=(const omni_mutex&);
-
-OMNI_THREAD_EXPOSE:
-    OMNI_MUTEX_IMPLEMENTATION
-};
-
-//
-// As an alternative to:
-// {
-//   mutex.lock();
-//   .....
-//   mutex.unlock();
-// }
-//
-// you can use a single instance of the omni_mutex_lock class:
-//
-// {
-//   omni_mutex_lock l(mutex);
-//   ....
-// }
-//
-// This has the advantage that mutex.unlock() will be called automatically
-// when an exception is thrown.
-//
-
-class _OMNITHREAD_NTDLL_ omni_mutex_lock {
-    omni_mutex& mutex;
-public:
-    omni_mutex_lock(omni_mutex& m) : mutex(m) { mutex.lock(); }
-    ~omni_mutex_lock(void) { mutex.unlock(); }
-private:
-    // dummy copy constructor and operator= to prevent copying
-    omni_mutex_lock(const omni_mutex_lock&);
-    omni_mutex_lock& operator=(const omni_mutex_lock&);
-};
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Condition variable
-//
-///////////////////////////////////////////////////////////////////////////
-
-class _OMNITHREAD_NTDLL_ omni_condition {
-
-    omni_mutex* mutex;
-
-public:
-    omni_condition(omni_mutex* m);
-       // constructor must be given a pointer to an existing mutex. The
-       // condition variable is then linked to the mutex, so that there is an
-       // implicit unlock and lock around wait() and timed_wait().
-
-    ~omni_condition(void);
-
-    void wait(void);
-       // wait for the condition variable to be signalled.  The mutex is
-       // implicitly released before waiting and locked again after waking up.
-       // If wait() is called by multiple threads, a signal may wake up more
-       // than one thread.  See POSIX threads documentation for details.
-
-    int timedwait(unsigned long secs, unsigned long nanosecs = 0);
-       // timedwait() is given an absolute time to wait until.  To wait for a
-       // relative time from now, use omni_thread::get_time. See POSIX threads
-       // documentation for why absolute times are better than relative.
-       // Returns 1 (true) if successfully signalled, 0 (false) if time
-       // expired.
-
-    void signal(void);
-       // if one or more threads have called wait(), signal wakes up at least
-       // one of them, possibly more.  See POSIX threads documentation for
-       // details.
-
-    void broadcast(void);
-       // broadcast is like signal but wakes all threads which have called
-       // wait().
-
-private:
-    // dummy copy constructor and operator= to prevent copying
-    omni_condition(const omni_condition&);
-    omni_condition& operator=(const omni_condition&);
-
-OMNI_THREAD_EXPOSE:
-    OMNI_CONDITION_IMPLEMENTATION
-};
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Counting (or binary) semaphore
-//
-///////////////////////////////////////////////////////////////////////////
-
-class _OMNITHREAD_NTDLL_ omni_semaphore {
-
-public:
-    // if max_count == 1, you've got a binary semaphore.
-    omni_semaphore(unsigned int initial = 1, unsigned int max_count = 0x7fffffff);
-    ~omni_semaphore(void);
-
-    void wait(void);
-       // if semaphore value is > 0 then decrement it and carry on. If it's
-       // already 0 then block.
-
-    int trywait(void);
-       // if semaphore value is > 0 then decrement it and return 1 (true).
-       // If it's already 0 then return 0 (false).
-
-    void post(void);
-       // if any threads are blocked in wait(), wake one of them up. Otherwise
-       // increment the value of the semaphore.
-
-private:
-    // dummy copy constructor and operator= to prevent copying
-    omni_semaphore(const omni_semaphore&);
-    omni_semaphore& operator=(const omni_semaphore&);
-
-OMNI_THREAD_EXPOSE:
-    OMNI_SEMAPHORE_IMPLEMENTATION
-};
-
-//
-// A helper class for semaphores, similar to omni_mutex_lock above.
-//
-
-class _OMNITHREAD_NTDLL_ omni_semaphore_lock {
-    omni_semaphore& sem;
-public:
-    omni_semaphore_lock(omni_semaphore& s) : sem(s) { sem.wait(); }
-    ~omni_semaphore_lock(void) { sem.post(); }
-private:
-    // dummy copy constructor and operator= to prevent copying
-    omni_semaphore_lock(const omni_semaphore_lock&);
-    omni_semaphore_lock& operator=(const omni_semaphore_lock&);
-};
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread
-//
-///////////////////////////////////////////////////////////////////////////
-
-class _OMNITHREAD_NTDLL_ omni_thread {
-
-public:
-
-    enum priority_t {
-       PRIORITY_LOW,
-       PRIORITY_NORMAL,
-       PRIORITY_HIGH
-    };
-
-    enum state_t {
-       STATE_NEW,              // thread object exists but thread hasn't
-                               // started yet.
-       STATE_RUNNING,          // thread is running.
-       STATE_TERMINATED        // thread has terminated but storage has not
-                               // been reclaimed (i.e. waiting to be joined).
-    };
-
-    //
-    // Constructors set up the thread object but the thread won't start until
-    // start() is called. The create method can be used to construct and start
-    // a thread in a single call.
-    //
-
-    omni_thread(void (*fn)(void*), void* arg = NULL,
-               priority_t pri = PRIORITY_NORMAL);
-    omni_thread(void* (*fn)(void*), void* arg = NULL,
-               priority_t pri = PRIORITY_NORMAL);
-       // these constructors create a thread which will run the given function
-       // when start() is called.  The thread will be detached if given a
-       // function with void return type, undetached if given a function
-       // returning void*. If a thread is detached, storage for the thread is
-       // reclaimed automatically on termination. Only an undetached thread
-       // can be joined.
-
-    void start(void);
-       // start() causes a thread created with one of the constructors to
-       // start executing the appropriate function.
-
-protected:
-
-    omni_thread(void* arg = NULL, priority_t pri = PRIORITY_NORMAL);
-       // this constructor is used in a derived class.  The thread will
-       // execute the run() or run_undetached() member functions depending on
-       // whether start() or start_undetached() is called respectively.
-
-    void start_undetached(void);
-       // can be used with the above constructor in a derived class to cause
-       // the thread to be undetached.  In this case the thread executes the
-       // run_undetached member function.
-
-    virtual ~omni_thread(void);
-       // destructor cannot be called by user (except via a derived class).
-       // Use exit() or cancel() instead. This also means a thread object must
-       // be allocated with new - it cannot be statically or automatically
-       // allocated. The destructor of a class that inherits from omni_thread
-       // shouldn't be public either (otherwise the thread object can be
-       // destroyed while the underlying thread is still running).
-
-public:
-
-    void join(void**);
-       // join causes the calling thread to wait for another's completion,
-       // putting the return value in the variable of type void* whose address
-       // is given (unless passed a null pointer). Only undetached threads
-       // may be joined. Storage for the thread will be reclaimed.
-
-    void set_priority(priority_t);
-       // set the priority of the thread.
-
-    static omni_thread* create(void (*fn)(void*), void* arg = NULL,
-                              priority_t pri = PRIORITY_NORMAL);
-    static omni_thread* create(void* (*fn)(void*), void* arg = NULL,
-                              priority_t pri = PRIORITY_NORMAL);
-       // create spawns a new thread executing the given function with the
-       // given argument at the given priority. Returns a pointer to the
-       // thread object. It simply constructs a new thread object then calls
-       // start.
-
-    static void exit(void* return_value = NULL);
-       // causes the calling thread to terminate.
-
-    static omni_thread* self(void);
-       // returns the calling thread's omni_thread object.  If the
-       // calling thread is not the main thread and is not created
-       // using this library, returns 0. (But see create_dummy()
-       // below.)
-
-    static void yield(void);
-       // allows another thread to run.
-
-    static void sleep(unsigned long secs, unsigned long nanosecs = 0);
-       // sleeps for the given time.
-
-    static void get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
-                        unsigned long rel_sec = 0, unsigned long rel_nsec=0);
-       // calculates an absolute time in seconds and nanoseconds, suitable for
-       // use in timed_waits on condition variables, which is the current time
-       // plus the given relative offset.
-
-
-    static void stacksize(unsigned long sz);
-    static unsigned long stacksize();
-        // Use this value as the stack size when spawning a new thread.
-        // The default value (0) means that the thread library default is
-        // to be used.
-
-
-    // Per-thread data
-    //
-    // These functions allow you to attach additional data to an
-    // omni_thread. First allocate a key for yourself with
-    // allocate_key(). Then you can store any object whose class is
-    // derived from value_t. Any values still stored in the
-    // omni_thread when the thread exits are deleted.
-    //
-    // These functions are NOT thread safe, so you should be very
-    // careful about setting/getting data in a different thread to the
-    // current thread.
-
-    typedef unsigned int key_t;
-    static key_t allocate_key();
-
-    class value_t {
-    public:
-      virtual ~value_t() {}
-    };
-
-    value_t* set_value(key_t k, value_t* v);
-        // Sets a value associated with the given key. The key must
-        // have been allocated with allocate_key(). If a value has
-        // already been set with the specified key, the old value_t
-        // object is deleted and replaced. Returns the value which was
-        // set, or zero if the key is invalid.
-
-    value_t* get_value(key_t k);
-        // Returns the value associated with the key. If the key is
-        // invalid, or there is no value for the key, returns zero.
-
-    value_t* remove_value(key_t k);
-        // Removes the value associated with the key and returns it.
-        // If the key is invalid, or there is no value for the key,
-        // returns zero.
-
-
-    // Dummy omni_thread
-    //
-    // Sometimes, an application finds itself with threads created
-    // outside of omnithread which must interact with omnithread
-    // features such as the per-thread data. In this situation,
-    // omni_thread::self() would normally return 0. These functions
-    // allow the application to create a suitable dummy omni_thread
-    // object.
-
-    static omni_thread* create_dummy(void);
-        // creates a dummy omni_thread for the calling thread. Future
-        // calls to self() will return the dummy omni_thread. Throws
-        // omni_thread_invalid if this thread already has an
-        // associated omni_thread (real or dummy).
-
-    static void release_dummy();
-        // release the dummy omni_thread for this thread. This
-        // function MUST be called before the thread exits. Throws
-        // omni_thread_invalid if the calling thread does not have a
-        // dummy omni_thread.
-
-    // class ensure_self should be created on the stack. If created in
-    // a thread without an associated omni_thread, it creates a dummy
-    // thread which is released when the ensure_self object is deleted.
-
-    class ensure_self {
-    public:
-      inline ensure_self() : _dummy(0)
-      {
-       _self = omni_thread::self();
-       if (!_self) {
-         _dummy = 1;
-         _self  = omni_thread::create_dummy();
-       }
-      }
-      inline ~ensure_self()
-      {
-       if (_dummy)
-         omni_thread::release_dummy();
-      }
-      inline omni_thread* self() { return _self; }
-    private:
-      omni_thread* _self;
-      int          _dummy;
-    };
-
-
-private:
-
-    virtual void run(void* /*arg*/) {}
-    virtual void* run_undetached(void* /*arg*/) { return NULL; }
-       // can be overridden in a derived class.  When constructed using the
-       // the constructor omni_thread(void*, priority_t), these functions are
-       // called by start() and start_undetached() respectively.
-
-    void common_constructor(void* arg, priority_t pri, int det);
-       // implements the common parts of the constructors.
-
-    omni_mutex mutex;
-       // used to protect any members which can change after construction,
-       // i.e. the following 2 members.
-
-    state_t _state;
-    priority_t _priority;
-
-    static omni_mutex* next_id_mutex;
-    static int next_id;
-    int _id;
-
-    void (*fn_void)(void*);
-    void* (*fn_ret)(void*);
-    void* thread_arg;
-    int detached;
-    int _dummy;
-    value_t**     _values;
-    unsigned long _value_alloc;
-
-    omni_thread(const omni_thread&);
-    omni_thread& operator=(const omni_thread&);
-    // Not implemented
-
-public:
-
-    priority_t priority(void) {
-
-       // return this thread's priority.
-
-       omni_mutex_lock l(mutex);
-       return _priority;
-    }
-
-    state_t state(void) {
-
-       // return thread state (invalid, new, running or terminated).
-
-       omni_mutex_lock l(mutex);
-       return _state;
-    }
-
-    int id(void) { return _id; }
-       // return unique thread id within the current process.
-
-
-    // This class plus the instance of it declared below allows us to execute
-    // some initialisation code before main() is called.
-
-    class _OMNITHREAD_NTDLL_ init_t {
-    public:
-       init_t(void);
-        ~init_t(void);
-    };
-
-    friend class init_t;
-    friend class omni_thread_dummy;
-
-OMNI_THREAD_EXPOSE:
-    OMNI_THREAD_IMPLEMENTATION
-};
-
-#ifndef __rtems__
-static omni_thread::init_t omni_thread_init;
-#else
-// RTEMS calls global Ctor/Dtor in a context that is not
-// a posix thread. Calls to functions to pthread_self() in
-// that context returns NULL. 
-// So, for RTEMS we will make the thread initialization at the
-// beginning of the Init task that has a posix context.
-#endif
-
-#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_VxThread.h b/gnuradio-core/src/lib/omnithread/ot_VxThread.h
deleted file mode 100644 (file)
index e96c036..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef __VXTHREAD_H__
-#define __VXTHREAD_H__
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Project:     omniORB
-%% Filename:    $Filename$
-%% Author:      Guillaume/Bill ARRECKX
-%%              Copyright Wavetek Wandel & Goltermann, Plymouth.
-%% Description: OMNI thread implementation classes for VxWorks threads
-%% Notes:
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% $Log$
-%% Revision 1.1  2004/04/10 18:00:52  eb
-%% Initial revision
-%%
-%% Revision 1.1.1.1  2004/03/01 00:20:27  eb
-%% initial checkin
-%%
-%% Revision 1.1  2003/05/25 05:29:04  eb
-%% see ChangeLog
-%%
-%% Revision 1.1.2.1  2003/02/17 02:03:07  dgrisby
-%% vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
-%%
-%% Revision 1.1.1.1  2002/11/19 14:55:21  sokcevti
-%% OmniOrb4.0.0 VxWorks port
-%%
-%% Revision 1.2  2002/06/14 12:45:50  engeln
-%% unnecessary members in condition removed.
-%% ---
-%%
-%% Revision 1.1.1.1  2002/04/02 10:08:49  sokcevti
-%% omniORB4 initial realease
-%%
-%% Revision 1.1  2001/03/23 16:50:23  hartmut
-%% Initial Version 2.8
-%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-*/
-
-
-///////////////////////////////////////////////////////////////////////////
-// Includes
-///////////////////////////////////////////////////////////////////////////
-#include <vxWorks.h>
-#include <semLib.h>
-#include <taskLib.h>
-
-
-///////////////////////////////////////////////////////////////////////////
-// Externs prototypes
-///////////////////////////////////////////////////////////////////////////
-extern "C" void omni_thread_wrapper(void* ptr);
-
-
-///////////////////////////////////////////////////////////////////////////
-// Exported macros
-// Note: These are added as private members in each class implementation.
-///////////////////////////////////////////////////////////////////////////
-#define OMNI_MUTEX_IMPLEMENTATION \
-   SEM_ID mutexID;     \
-   bool m_bConstructed;
-
-#define OMNI_CONDITION_IMPLEMENTATION \
-   long waiters_; \
-   SEM_ID waiters_lock_; \
-   SEM_ID sema_;
-
-#define OMNI_SEMAPHORE_IMPLEMENTATION \
-   SEM_ID semID;
-
-#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
-       if(semTake(mutexID, WAIT_FOREVER) != OK)        \
-       {       \
-               throw omni_thread_fatal(errno); \
-       }
-
-#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
-       if(semGive(mutexID) != OK)      \
-       {       \
-               throw omni_thread_fatal(errno); \
-       }
-
-#define OMNI_THREAD_IMPLEMENTATION \
-   friend void omni_thread_wrapper(void* ptr); \
-   static int vxworks_priority(priority_t); \
-   omni_condition *running_cond; \
-   void* return_val; \
-   int tid; \
-   public: \
-   static void attach(void); \
-   static void detach(void); \
-   static void show(void);
-
-
-///////////////////////////////////////////////////////////////////////////
-// Porting macros
-///////////////////////////////////////////////////////////////////////////
-// This is a wrapper function for the 'main' function which does not exists
-//  as such in VxWorks. The wrapper creates a launch function instead,
-//  which spawns the application wrapped in a omni_thread.
-// Argc will always be null.
-///////////////////////////////////////////////////////////////////////////
-#define main( discarded_argc, discarded_argv ) \
-        omni_discard_retval() \
-          { \
-          throw; \
-          } \
-        int omni_main( int argc, char **argv ); \
-        void launch( ) \
-          { \
-          omni_thread* th = new omni_thread( (void(*)(void*))omni_main );\
-          th->start();\
-          }\
-        int omni_main( int argc, char **argv )
-
-
-#endif // ndef __VXTHREAD_H__
diff --git a/gnuradio-core/src/lib/omnithread/ot_mach.h b/gnuradio-core/src/lib/omnithread/ot_mach.h
deleted file mode 100644 (file)
index 7636192..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-//                             Package : omnithread
-// omnithread/posix.h          Created : 7/97 lars immisch lars@ibp.de
-//
-//    Copyright (C) 1994,1995,1996, 1997 Immisch, becker & Partner
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-//
-// OMNI thread implementation classes for posix threads
-//
-
-#ifndef __omnithread_mach_h_
-#define __omnithread_mach_h_
-
-#include <mach/cthreads.h>
-
-extern "C" void* omni_thread_wrapper(void* ptr);
-
-#define OMNI_MUTEX_IMPLEMENTATION                      \
-    struct mutex mach_mutex;
-
-#define OMNI_CONDITION_IMPLEMENTATION                  \
-    struct condition mach_cond;
-
-#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
-    omni_mutex m;                                      \
-    omni_condition c;                                  \
-    int value;
-
-
-#define OMNI_THREAD_IMPLEMENTATION                     \
-    cthread_t mach_thread;                             \
-    static int mach_priority(priority_t);              \
-    friend void* omni_thread_wrapper(void* ptr);
-
-#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_nt.h b/gnuradio-core/src/lib/omnithread/ot_nt.h
deleted file mode 100644 (file)
index 551ccf2..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-//                             Package : omnithread
-// omnithread/nt.h             Created : 6/95 tjr
-//
-//    Copyright (C) 1995, 1996, 1997 Olivetti & Oracle Research Laboratory
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-//
-// OMNI thread implementation classes for NT threads.
-//
-
-#ifndef __omnithread_nt_h_
-#define __omnithread_nt_h_
-
-#ifndef WIN32_LEAN_AND_MEAN
-#  define WIN32_LEAN_AND_MEAN
-#  define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
-#endif
-
-#include <windows.h>
-
-#ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
-#  undef WIN32_LEAN_AND_MEAN
-#  undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
-#endif
-
-
-#ifndef __BCPLUSPLUS__
-#define OMNI_THREAD_WRAPPER \
-    unsigned __stdcall omni_thread_wrapper(LPVOID ptr);
-#else
-#define OMNI_THREAD_WRAPPER \
-    void _USERENTRY omni_thread_wrapper(void *ptr);
-#endif
-
-extern "C" OMNI_THREAD_WRAPPER;
-
-#define OMNI_MUTEX_IMPLEMENTATION                      \
-    CRITICAL_SECTION crit;
-
-#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
-    EnterCriticalSection(&crit);
-
-#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION               \
-    TryEnterCriticalSection(&crit);
-
-#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
-    LeaveCriticalSection(&crit);
-
-#define OMNI_CONDITION_IMPLEMENTATION                  \
-    CRITICAL_SECTION crit;                             \
-    omni_thread* waiting_head;                         \
-    omni_thread* waiting_tail;
-
-#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
-    HANDLE nt_sem;
-
-#define OMNI_THREAD_IMPLEMENTATION                     \
-    HANDLE handle;                                     \
-    DWORD nt_id;                                       \
-    void* return_val;                                  \
-    HANDLE cond_semaphore;                             \
-    omni_thread* cond_next;                            \
-    omni_thread* cond_prev;                            \
-    BOOL cond_waiting;                                 \
-    static int nt_priority(priority_t);                        \
-    friend class omni_condition;                       \
-    friend OMNI_THREAD_WRAPPER;
-
-#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_posix.h b/gnuradio-core/src/lib/omnithread/ot_posix.h
deleted file mode 100644 (file)
index 666ccc0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-//                             Package : omnithread
-// omnithread/posix.h          Created : 7/94 tjr
-//
-//    Copyright (C) 2006 Free Software Foundation, Inc.
-//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-//
-// OMNI thread implementation classes for posix threads
-//
-
-#ifndef __omnithread_posix_h_
-#define __omnithread_posix_h_
-
-#if defined(__alpha__) && defined(__osf1__) || defined(__hpux__)
-// stop unnecessary definitions of TRY, etc on OSF
-#ifndef EXC_HANDLING
-#define EXC_HANDLING
-#endif
-#endif
-
-#ifndef __POSIX_NT__
-#  include <pthread.h>
-#else
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#    define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
-#  endif
-#  include <windows.h>
-#  include "pthread_nt.h"
-#  ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
-#    undef WIN32_LEAN_AND_MEAN
-#    undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
-#  endif
-#endif
-
-extern "C" void* omni_thread_wrapper(void* ptr);
-
-#define OMNI_MUTEX_IMPLEMENTATION                      \
-    pthread_mutex_t posix_mutex;
-
-#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
-    pthread_mutex_lock(&posix_mutex);
-
-#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION               \
-    (pthread_mutex_trylock(&posix_mutex)==0);
-
-#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
-    pthread_mutex_unlock(&posix_mutex);
-
-#define OMNI_CONDITION_IMPLEMENTATION                  \
-    pthread_cond_t posix_cond;
-
-#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
-    omni_mutex m;                                      \
-    omni_condition c;                                  \
-    int value;                                         \
-    int max_count;
-
-#define OMNI_THREAD_IMPLEMENTATION                     \
-    pthread_t posix_thread;                            \
-    static int posix_priority(priority_t);             \
-    friend void* omni_thread_wrapper(void* ptr);
-
-#endif
diff --git a/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h b/gnuradio-core/src/lib/omnithread/ot_pthread_nt.h
deleted file mode 100644 (file)
index dbf4356..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*                             Package : omnithread
-   omnithread/pthread_nt.h     Created : Steven Brenneis <brennes1@rjrt.com>
-  
-      Copyright (C) 1998 Steven Brennes
-  
-      This file is part of the omnithread library
-  
-      The omnithread 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., 51 Franklin Street, Boston, MA  
-      02110-1301, USA
-  
-      Posix Threads implementation for Windows NT, version 4.0
-*/
-
-#ifndef PTHREAD_NT_H_INCLUDED
-#define PTHREAD_NT_H_INCLUDED
-
-#include <errno.h>
-
-#ifndef ETIMEDOUT
-//     May have to be changed if NT starts supporting more errno values
-#define ETIMEDOUT 60
-#endif
-
-#undef PthreadDraftVersion
-#define PthreadDraftVersion 10
-
-#define NoNanoSleep
-
-#define PthreadSupportThreadPriority
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _TIMERS_T_
-#define _TIMERS_T_
-       typedef struct timespec {
-               unsigned long tv_sec;
-               long tv_nsec;
-       } timespec_t;
-#endif
-
-typedef char* __pthreadLongString_t;
-typedef void* __pthreadLongAddr_t;
-typedef __pthreadLongAddr_t* __pthreadLongAddr_p;
-typedef long __pthreadLongInt_t;
-typedef unsigned long __pthreadLongUint_t;
-typedef __pthreadLongAddr_p __pthreadTsd_t;
-
-typedef struct __pthread_mutex_t {
-       unsigned int lock;           /* LOCK, SLOW, TYPE, RECURSIVE  */
-       unsigned int valid;          /* Validation info */
-       __pthreadLongString_t name;   /* Name of mutex */
-       unsigned int arg;            /* printf argument for  name */
-       unsigned int depth;          /* Recursive lock depth */
-       unsigned long sequence;       /* Mutex sequence number */
-       unsigned long owner;          /* Current owner (if known */
-       __pthreadLongAddr_t block;          /* Pointer to blocking struct */
-} pthread_mutex_t;
-
-typedef struct __pthread_mutexattr_t {
-       long valid;
-       __pthreadLongUint_t reserved[15];
-} pthread_mutexattr_t;
-
-typedef struct __pthread_cond_t {
-       unsigned int state;          /* EVENT, SLOW, REFCNT */
-       unsigned int valid;          /* Validation info */
-       __pthreadLongString_t name;   /* Name of condition variable */
-       unsigned int arg;            /* printf argument for name */
-       unsigned long sequence;       /* Condition variable seq # */
-       __pthreadLongAddr_t block;          /* Pointer to blocking struct */
-} pthread_cond_t ;
-
-typedef struct __pthread_condattr_t {
-       long valid;
-       __pthreadLongUint_t reserved[13];
-} pthread_condattr_t ;
-
-typedef struct __pthread_transp_t {
-       __pthreadLongAddr_t reserved1;      /* Reserved to posix_nt */
-       __pthreadLongAddr_t reserved2;      /* Reserved to posix_nt */
-       unsigned short size;           /* Size of data structure */
-       unsigned char reserved3[2];   /* Reserved to posix_nt */
-       __pthreadLongAddr_t reserved4;   /* Reserved to posix_nt */
-       __pthreadLongUint_t sequence;       /* Thread sequence number */
-       __pthreadLongUint_t reserved5[2];   /* Reserved to posix_nt */
-       __pthreadLongAddr_t per_kt_area;    /* Pointer to kernel context */
-       __pthreadLongAddr_t stack_base;     /* Current stack base */
-       __pthreadLongAddr_t stack_reserve; /* Current stack reserve zone */
-       __pthreadLongAddr_t stack_yellow;   /* Current stack yellow zone */
-       __pthreadLongAddr_t stack_guard;    /* Current stack guard zone */
-       __pthreadLongUint_t stack_size;     /* Size of stack */
-       __pthreadTsd_t tsd_values;     /* TSD array (indexed by key) */
-       unsigned long tsd_count;      /* Number of TSD cells */
-       __pthreadLongAddr_t reserved6;      /* Reserved to posix_nt */
-       __pthreadLongAddr_t reserved7;      /* Reserved to posix_nt */
-       unsigned int thread_flags;   /* Dynamic external state */
-} pthread_transp_t, *pthread_transp_p;
-
-typedef pthread_transp_p pthread_t;
-
-typedef struct __pthread_attr_t {
-       long valid;
-       __pthreadLongString_t name;
-       __pthreadLongUint_t arg;
-       __pthreadLongUint_t reserved[19];
-} pthread_attr_t ;
-
-typedef unsigned int pthread_key_t;
-
-typedef struct sched_param {
-       int sched_priority;
-} sched_param_t;
-        
-/*     Function Prototypes */
-
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
-                                                               void *(*start_routine)(void*), void *arg);
-int pthread_detach(pthread_t thread);
-int pthread_join(pthread_t thread, void **value_ptr);
-void pthread_exit(void *value_ptr);
-int pthread_attr_init(pthread_attr_t *attr);
-int pthread_attr_destroy(pthread_attr_t *attr);
-int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
-int pthread_attr_getstacksize(const pthread_attr_t *attr, 
-                                                                                       size_t *stacksize);
-int pthread_cond_init(pthread_cond_t *cond,
-                                                               const pthread_condattr_t *attr);
-int pthread_cond_destroy(pthread_cond_t *cond);
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
-int pthread_cond_timedwait(pthread_cond_t *cond, 
-                                                                                       pthread_mutex_t *mutex,
-                                                                                       const struct timespec *abstime);
-int pthread_cond_signal(pthread_cond_t *cond);
-int pthread_cond_broadcast(pthread_cond_t *cond);
-int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
-int pthread_key_delete(pthread_key_t key);
-int pthread_mutex_destroy(pthread_mutex_t *mutex);
-int pthread_mutex_init(pthread_mutex_t *mutex, 
-                                                                       const pthread_mutexattr_t *attr);
-int pthread_mutex_lock(pthread_mutex_t *mutex);
-int pthread_mutex_trylock(pthread_mutex_t *mutex);
-int pthread_mutex_unlock(pthread_mutex_t *mutex);
-pthread_t pthread_self();
-int pthread_setspecific(pthread_key_t key, const void *value);
-void *pthread_getspecific(pthread_key_t key);
-int pthread_getschedparam(pthread_t thread, int *policy,
-                                                                                       struct sched_param *param);
-int pthread_setschedparam(pthread_t thread, int policy,
-                                                                               const struct sched_param *param);
-int pthread_attr_setschedparam(pthread_attr_t *attr, 
-                                                                                               const struct sched_param *param);
-int pthread_attr_getschedparam(const pthread_attr_t *attr, 
-                                                                                               struct sched_param *param);
-
-int pthread_delay_np(const struct timespec *interval);
-int pthread_get_expiration_np(const struct timespec *delta,
-                                                                                               struct timespec *abstime);
-
-# define SCHED_FIFO 1
-# define SCHED_RR 2
-# define SCHED_OTHER 3
-
-int sched_yield();
-int sched_get_priority_max(int policy);
-int sched_get_priority_min(int policy);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //      PTHREAD_NT_H_INCLUDED
diff --git a/gnuradio-core/src/lib/omnithread/ot_solaris.h b/gnuradio-core/src/lib/omnithread/ot_solaris.h
deleted file mode 100644 (file)
index f4fea0b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-//                             Package : omnithread
-// omnithread/solaris.h                Created : 7/94 tjr
-//
-//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-// OMNI thread implementation classes for solaris threads.
-//
-
-#ifndef __omnithread_solaris_h_
-#define __omnithread_solaris_h_
-
-#include <thread.h>
-
-extern "C" void* omni_thread_wrapper(void* ptr);
-
-#define OMNI_MUTEX_IMPLEMENTATION                      \
-    mutex_t sol_mutex;
-
-#define OMNI_CONDITION_IMPLEMENTATION                  \
-    cond_t sol_cond;
-
-#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
-    sema_t sol_sem;
-
-#define OMNI_THREAD_IMPLEMENTATION                     \
-    thread_t sol_thread;                               \
-    static int sol_priority(priority_t);               \
-    friend void* omni_thread_wrapper(void* ptr);
-
-#endif
diff --git a/gnuradio-core/src/lib/omnithread/posix.cc b/gnuradio-core/src/lib/omnithread/posix.cc
deleted file mode 100644 (file)
index b82e86d..0000000
+++ /dev/null
@@ -1,972 +0,0 @@
-//                             Package : omnithread
-// omnithread/posix.cc         Created : 7/94 tjr
-//
-//    Copyright (C) 2006 Free Software Foundation, Inc.
-//    Copyright (C) 1994-1999 AT&T Laboratories Cambridge
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-
-//
-// Implementation of OMNI thread abstraction for posix threads
-//
-// The source below tests for the definition of the macros:
-//     PthreadDraftVersion
-//     PthreadSupportThreadPriority
-//     NoNanoSleep
-//     NeedPthreadInit
-//
-// As different draft versions of the pthread standard P1003.4a/P1003.1c
-// define slightly different APIs, the macro 'PthreadDraftVersion'
-// identifies the draft version supported by this particular platform.
-//
-// Some unix variants do not support thread priority unless a real-time
-// kernel option is installed. The macro 'PthreadSupportThreadPriority',
-// if defined, enables the use of thread priority. If it is not defined,
-// setting or changing thread priority will be silently ignored.
-//
-// nanosleep() is defined in Posix P1003.4 since Draft 9 (?).
-// Not all platforms support this standard. The macro 'NoNanoSleep'
-// identifies platform that don't.
-//
-
-#include <config.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <omnithread.h>
-
-#ifdef HAVE_NANOSLEEP
-#undef NoNanoSleep
-#else
-#define NoNanoSleep
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-// typedef of struct timeval and gettimeofday();
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
-#if defined(__linux__) && defined(_MIT_POSIX_THREADS)
-#include <pthread/mit/sys/timers.h>
-#endif
-
-#if defined(__irix__) && defined(PthreadSupportThreadPriority)
-#if _POSIX_THREAD_PRIORITY_SCHEDULING
-#include <sched.h>
-#endif
-#endif
-
-#define DB(x) // x
-//#include <iostream.h> or #include <iostream> if DB is on.
-
-#if (PthreadDraftVersion <= 6)
-#define ERRNO(x) (((x) != 0) ? (errno) : 0)
-#ifdef __VMS
-// pthread_setprio returns old priority on success (draft version 4:
-// OpenVms version < 7)
-#define THROW_ERRORS(x) { if ((x) == -1) throw omni_thread_fatal(errno); }
-#else
-#define THROW_ERRORS(x) { if ((x) != 0) throw omni_thread_fatal(errno); }
-#endif
-#else
-#define ERRNO(x) (x)
-#define THROW_ERRORS(x) { int rc = (x); \
-                         if (rc != 0) throw omni_thread_fatal(rc); }
-#endif
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Mutex
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_mutex::omni_mutex(void)
-{
-#if (PthreadDraftVersion == 4)
-    THROW_ERRORS(pthread_mutex_init(&posix_mutex, pthread_mutexattr_default));
-#else
-    THROW_ERRORS(pthread_mutex_init(&posix_mutex, 0));
-#endif
-}
-
-omni_mutex::~omni_mutex(void)
-{
-    THROW_ERRORS(pthread_mutex_destroy(&posix_mutex));
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Condition variable
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_condition::omni_condition(omni_mutex* m) : mutex(m)
-{
-#if (PthreadDraftVersion == 4)
-    THROW_ERRORS(pthread_cond_init(&posix_cond, pthread_condattr_default));
-#else
-    THROW_ERRORS(pthread_cond_init(&posix_cond, 0));
-#endif
-}
-
-omni_condition::~omni_condition(void)
-{
-    THROW_ERRORS(pthread_cond_destroy(&posix_cond));
-}
-
-void
-omni_condition::wait(void)
-{
-    THROW_ERRORS(pthread_cond_wait(&posix_cond, &mutex->posix_mutex));
-}
-
-int
-omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
-{
-    timespec rqts = { secs, nanosecs };
-
-again:
-    int rc = ERRNO(pthread_cond_timedwait(&posix_cond,
-                                         &mutex->posix_mutex, &rqts));
-    if (rc == 0)
-       return 1;
-
-#if (PthreadDraftVersion <= 6)
-    if (rc == EAGAIN)
-       return 0;
-#endif
-
-    // Some versions of unix produces this errno when the wait was
-    // interrupted by a unix signal or fork.
-    // Some versions of the glibc 2.0.x produces this errno when the 
-    // program is debugged under gdb. Straightly speaking this is non-posix
-    // compliant. We catch this here to make debugging possible.
-    if (rc == EINTR)
-      goto again;
-
-    if (rc == ETIMEDOUT)
-       return 0;
-
-    throw omni_thread_fatal(rc);
-#ifdef _MSC_VER
-    return 0;
-#endif
-}
-
-void
-omni_condition::signal(void)
-{
-    THROW_ERRORS(pthread_cond_signal(&posix_cond));
-}
-
-void
-omni_condition::broadcast(void)
-{
-    THROW_ERRORS(pthread_cond_broadcast(&posix_cond));
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Counting (or binary) semaphore
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_semaphore::omni_semaphore(unsigned int initial, unsigned int _max_count) : c(&m)
-{
-    value = initial;
-    max_count = _max_count;
-    if (value < 0 || max_count < 1)
-      throw omni_thread_fatal(0);
-}
-
-omni_semaphore::~omni_semaphore(void)
-{
-}
-
-void
-omni_semaphore::wait(void)
-{
-    omni_mutex_lock l(m);
-
-    while (value == 0)
-       c.wait();
-
-    value--;
-}
-
-int
-omni_semaphore::trywait(void)
-{
-    omni_mutex_lock l(m);
-
-    if (value == 0)
-       return 0;
-
-    value--;
-    return 1;
-}
-
-void
-omni_semaphore::post(void)
-{
-    {
-        omni_mutex_lock l(m);
-       if (value < max_count)
-         value++;
-    }
-
-    c.signal();
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-//
-// static variables
-//
-
-omni_mutex* omni_thread::next_id_mutex;
-int omni_thread::next_id = 0;
-
-static pthread_key_t self_key;
-
-#ifdef PthreadSupportThreadPriority
-static int lowest_priority;
-static int normal_priority;
-static int highest_priority;
-#endif
-
-#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
-// omniORB requires a larger stack size than the default (21120) on OSF/1
-static size_t stack_size = 32768;
-#elif defined(__rtems__)
-static size_t stack_size = ThreadStackSize;
-#elif defined(__aix__)
-static size_t stack_size = 262144;
-#else
-static size_t stack_size = 0;
-#endif
-
-//
-// Initialisation function (gets called before any user code).
-//
-
-static int& count() {
-  static int the_count = 0;
-  return the_count;
-}
-
-omni_thread::init_t::init_t(void)
-{
-    if (count()++ != 0)        // only do it once however many objects get created.
-       return;
-
-    DB(cerr << "omni_thread::init: posix 1003.4a/1003.1c (draft "
-       << PthreadDraftVersion << ") implementation initialising\n");
-
-#ifdef NeedPthreadInit
-
-    pthread_init();
-
-#endif
-
-#if (PthreadDraftVersion == 4)
-    THROW_ERRORS(pthread_keycreate(&self_key, NULL));
-#else
-    THROW_ERRORS(pthread_key_create(&self_key, NULL));
-#endif
-
-#ifdef PthreadSupportThreadPriority
-
-#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
-
-    lowest_priority = PRI_OTHER_MIN;
-    highest_priority = PRI_OTHER_MAX;
-
-#elif defined(__hpux__)
-
-    lowest_priority = PRI_OTHER_MIN;
-    highest_priority = PRI_OTHER_MAX;
-
-#elif defined(__sunos__) && (__OSVERSION__ == 5)
-
-    // a bug in pthread_attr_setschedparam means lowest priority is 1 not 0
-
-    lowest_priority  = 1;
-    highest_priority = 3;
-
-#else
-
-    lowest_priority = sched_get_priority_min(SCHED_FIFO);
-    highest_priority = sched_get_priority_max(SCHED_FIFO);
-
-#endif
-
-    switch (highest_priority - lowest_priority) {
-
-    case 0:
-    case 1:
-       normal_priority = lowest_priority;
-       break;
-
-    default:
-       normal_priority = lowest_priority + 1;
-       break;
-    }
-
-#endif   /* PthreadSupportThreadPriority */
-
-    next_id_mutex = new omni_mutex;
-
-    //
-    // Create object for this (i.e. initial) thread.
-    //
-
-    omni_thread* t = new omni_thread;
-
-    t->_state = STATE_RUNNING;
-
-    t->posix_thread = pthread_self ();
-
-    DB(cerr << "initial thread " << t->id() << endl);
-
-    THROW_ERRORS(pthread_setspecific(self_key, (void*)t));
-
-#ifdef PthreadSupportThreadPriority
-
-#if (PthreadDraftVersion == 4)
-
-    THROW_ERRORS(pthread_setprio(t->posix_thread,
-                                posix_priority(PRIORITY_NORMAL)));
-
-#elif (PthreadDraftVersion == 6)
-
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-
-    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(PRIORITY_NORMAL)));
-
-    THROW_ERRORS(pthread_setschedattr(t->posix_thread, attr));
-
-#else
-
-    struct sched_param sparam;
-
-    sparam.sched_priority = posix_priority(PRIORITY_NORMAL);
-
-    THROW_ERRORS(pthread_setschedparam(t->posix_thread, SCHED_OTHER, &sparam));
-
-#endif   /* PthreadDraftVersion */
-
-#endif   /* PthreadSupportThreadPriority */
-}
-
-omni_thread::init_t::~init_t(void)
-{
-    if (--count() != 0) return;
-
-    omni_thread* self = omni_thread::self();
-    if (!self) return;
-
-    pthread_setspecific(self_key, 0);
-    delete self;
-
-    delete next_id_mutex;
-}
-
-//
-// Wrapper for thread creation.
-//
-
-extern "C" void* 
-omni_thread_wrapper(void* ptr)
-{
-    omni_thread* me = (omni_thread*)ptr;
-
-    DB(cerr << "omni_thread_wrapper: thread " << me->id()
-       << " started\n");
-
-    THROW_ERRORS(pthread_setspecific(self_key, me));
-
-    //
-    // Now invoke the thread function with the given argument.
-    //
-
-    if (me->fn_void != NULL) {
-       (*me->fn_void)(me->thread_arg);
-       omni_thread::exit();
-    }
-
-    if (me->fn_ret != NULL) {
-       void* return_value = (*me->fn_ret)(me->thread_arg);
-       omni_thread::exit(return_value);
-    }
-
-    if (me->detached) {
-       me->run(me->thread_arg);
-       omni_thread::exit();
-    } else {
-       void* return_value = me->run_undetached(me->thread_arg);
-       omni_thread::exit(return_value);
-    }
-
-    // should never get here.
-
-    return NULL;
-}
-
-
-//
-// Constructors for omni_thread - set up the thread object but don't
-// start it running.
-//
-
-// construct a detached thread running a given function.
-
-omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 1);
-    fn_void = fn;
-    fn_ret = NULL;
-}
-
-// construct an undetached thread running a given function.
-
-omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 0);
-    fn_void = NULL;
-    fn_ret = fn;
-}
-
-// construct a thread which will run either run() or run_undetached().
-
-omni_thread::omni_thread(void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 1);
-    fn_void = NULL;
-    fn_ret = NULL;
-}
-
-// common part of all constructors.
-
-void
-omni_thread::common_constructor(void* arg, priority_t pri, int det)
-{
-    _state = STATE_NEW;
-    _priority = pri;
-
-    next_id_mutex->lock();
-    _id = next_id++;
-    next_id_mutex->unlock();
-
-    thread_arg = arg;
-    detached = det;    // may be altered in start_undetached()
-
-    _dummy       = 0;
-    _values      = 0;
-    _value_alloc = 0;
-    // posix_thread is set up in initialisation routine or start().
-}
-
-
-//
-// Destructor for omni_thread.
-//
-
-omni_thread::~omni_thread(void)
-{
-    DB(cerr << "destructor called for thread " << id() << endl);
-    if (_values) {
-        for (key_t i=0; i < _value_alloc; i++) {
-           if (_values[i]) {
-               delete _values[i];
-           }
-        }
-       delete [] _values;
-    }
-}
-
-
-//
-// Start the thread
-//
-
-void
-omni_thread::start(void)
-{
-    omni_mutex_lock l(mutex);
-
-    if (_state != STATE_NEW)
-       throw omni_thread_invalid();
-
-    pthread_attr_t attr;
-
-#if (PthreadDraftVersion == 4)
-    pthread_attr_create(&attr);
-#else
-    pthread_attr_init(&attr);
-#endif
-
-#if (PthreadDraftVersion == 8)
-    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
-#endif
-
-#ifdef PthreadSupportThreadPriority
-
-#if (PthreadDraftVersion <= 6)
-
-    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(_priority)));
-
-#else
-
-    struct sched_param sparam;
-
-    sparam.sched_priority = posix_priority(_priority);
-
-    THROW_ERRORS(pthread_attr_setschedparam(&attr, &sparam));
-
-#endif /* PthreadDraftVersion */
-
-#endif /* PthreadSupportThreadPriority */
-
-#if !defined(__linux__)
-    if (stack_size) {
-      THROW_ERRORS(pthread_attr_setstacksize(&attr, stack_size));
-    }
-#endif
-
-
-#if (PthreadDraftVersion == 4)
-    THROW_ERRORS(pthread_create(&posix_thread, attr, omni_thread_wrapper,
-                               (void*)this));
-    pthread_attr_delete(&attr);
-#else
-    THROW_ERRORS(pthread_create(&posix_thread, &attr, omni_thread_wrapper,
-                               (void*)this));
-    pthread_attr_destroy(&attr);
-#endif
-
-    _state = STATE_RUNNING;
-
-    if (detached) {
-
-#if (PthreadDraftVersion <= 6)
-       THROW_ERRORS(pthread_detach(&posix_thread));
-#else
-       THROW_ERRORS(pthread_detach(posix_thread));
-#endif
-    }
-}
-
-
-//
-// Start a thread which will run the member function run_undetached().
-//
-
-void
-omni_thread::start_undetached(void)
-{
-    if ((fn_void != NULL) || (fn_ret != NULL))
-       throw omni_thread_invalid();
-
-    detached = 0;
-    start();
-}
-
-
-//
-// join - simply check error conditions & call pthread_join.
-//
-
-void
-omni_thread::join(void** status)
-{
-    mutex.lock();
-
-    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
-       mutex.unlock();
-       throw omni_thread_invalid();
-    }
-
-    mutex.unlock();
-
-    if (this == self())
-       throw omni_thread_invalid();
-
-    if (detached)
-       throw omni_thread_invalid();
-
-    DB(cerr << "omni_thread::join: doing pthread_join\n");
-
-    THROW_ERRORS(pthread_join(posix_thread, status));
-
-    DB(cerr << "omni_thread::join: pthread_join succeeded\n");
-
-#if (PthreadDraftVersion == 4)
-    // With draft 4 pthreads implementations (HPUX 10.x and
-    // Digital Unix 3.2), have to detach the thread after 
-    // join. If not, the storage for the thread will not be
-    // be reclaimed.
-    THROW_ERRORS(pthread_detach(&posix_thread));
-#endif
-
-    delete this;
-}
-
-
-//
-// Change this thread's priority.
-//
-
-void
-omni_thread::set_priority(priority_t pri)
-{
-    omni_mutex_lock l(mutex);
-
-    if (_state != STATE_RUNNING)
-       throw omni_thread_invalid();
-
-    _priority = pri;
-
-#ifdef PthreadSupportThreadPriority
-
-#if (PthreadDraftVersion == 4)
-
-    THROW_ERRORS(pthread_setprio(posix_thread, posix_priority(pri)));
-
-#elif (PthreadDraftVersion == 6)
-
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-
-    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(pri)));
-
-    THROW_ERRORS(pthread_setschedattr(posix_thread, attr));
-
-#else
-
-    struct sched_param sparam;
-
-    sparam.sched_priority = posix_priority(pri);
-
-    THROW_ERRORS(pthread_setschedparam(posix_thread, SCHED_OTHER, &sparam));
-
-#endif   /* PthreadDraftVersion */
-
-#endif   /* PthreadSupportThreadPriority */
-}
-
-
-//
-// create - construct a new thread object and start it running.  Returns thread
-// object if successful, null pointer if not.
-//
-
-// detached version
-
-omni_thread*
-omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
-{
-    omni_thread* t = new omni_thread(fn, arg, pri);
-
-    t->start();
-
-    return t;
-}
-
-// undetached version
-
-omni_thread*
-omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
-{
-    omni_thread* t = new omni_thread(fn, arg, pri);
-
-    t->start();
-
-    return t;
-}
-
-
-//
-// exit() _must_ lock the mutex even in the case of a detached thread.  This is
-// because a thread may run to completion before the thread that created it has
-// had a chance to get out of start().  By locking the mutex we ensure that the
-// creating thread must have reached the end of start() before we delete the
-// thread object.  Of course, once the call to start() returns, the user can
-// still incorrectly refer to the thread object, but that's their problem.
-//
-
-void
-omni_thread::exit(void* return_value)
-{
-    omni_thread* me = self();
-
-    if (me)
-      {
-       me->mutex.lock();
-
-       me->_state = STATE_TERMINATED;
-
-       me->mutex.unlock();
-
-       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
-          << me->detached << " return value " << return_value << endl);
-
-       if (me->detached)
-         delete me;
-      }
-    else
-      {
-       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
-      }
-
-    pthread_exit(return_value);
-}
-
-
-omni_thread*
-omni_thread::self(void)
-{
-    omni_thread* me;
-
-#if (PthreadDraftVersion <= 6)
-
-    THROW_ERRORS(pthread_getspecific(self_key, (void**)&me));
-
-#else
-
-    me = (omni_thread *)pthread_getspecific(self_key);
-
-#endif
-
-    if (!me) {
-      // This thread is not created by omni_thread::start because it
-      // doesn't has a class omni_thread instance attached to its key.
-      DB(cerr << "omni_thread::self: called with a non-omnithread. NULL is returned." << endl);
-    }
-
-    return me;
-}
-
-
-void
-omni_thread::yield(void)
-{
-#if (PthreadDraftVersion == 6)
-
-    pthread_yield(NULL);
-
-#elif (PthreadDraftVersion < 9)
-
-    pthread_yield();
-
-#else
-
-    THROW_ERRORS(sched_yield());
-
-#endif
-}
-
-
-void
-omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
-{
-    timespec rqts = { secs, nanosecs };
-
-#ifndef NoNanoSleep
-
-    timespec remain;
-    while (nanosleep(&rqts, &remain)) {
-      if (errno == EINTR) {
-       rqts.tv_sec  = remain.tv_sec;
-       rqts.tv_nsec = remain.tv_nsec;
-       continue;
-      }
-      else
-       throw omni_thread_fatal(errno);
-    }
-#else
-
-#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined (__POSIX_NT__)
-
-    if (pthread_delay_np(&rqts) != 0)
-       throw omni_thread_fatal(errno);
-
-#elif defined(__linux__) || defined(__aix__)
-
-    if (secs > 2000) {
-      while ((secs = ::sleep(secs))) ;
-    } else {
-       usleep(secs * 1000000 + (nanosecs / 1000));
-    }
-
-#elif defined(__darwin__) || defined(__macos__)
-
-    // Single UNIX Specification says argument of usleep() must be
-    // less than 1,000,000.
-    secs += nanosecs / 1000000000;
-    nanosecs %= 1000000000;
-    while ((secs = ::sleep(secs))) ;
-    usleep(nanosecs / 1000);
-
-#else
-
-    throw omni_thread_invalid();
-
-#endif
-#endif /* NoNanoSleep */
-}
-
-
-void
-omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
-                     unsigned long rel_sec, unsigned long rel_nsec)
-{
-    timespec abs;
-
-#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined(__POSIX_NT__)
-
-    timespec rel;
-    rel.tv_sec = rel_sec;
-    rel.tv_nsec = rel_nsec;
-    THROW_ERRORS(pthread_get_expiration_np(&rel, &abs));
-
-#else
-
-#ifdef HAVE_CLOCK_GETTIME      /* __linux__ || __aix__ */
-
-    clock_gettime(CLOCK_REALTIME, &abs);
-
-#elif defined(HAVE_GETTIMEOFDAY)       /* defined(__linux__) || defined(__aix__) || defined(__SCO_VERSION__) || defined(__darwin__) || defined(__macos__) */
-
-    struct timeval tv;
-    gettimeofday(&tv, NULL); 
-    abs.tv_sec = tv.tv_sec;
-    abs.tv_nsec = tv.tv_usec * 1000;
-
-#else
-#error no get time support
-#endif /* __linux__ || __aix__ */
-
-    abs.tv_nsec += rel_nsec;
-    abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
-    abs.tv_nsec = abs.tv_nsec % 1000000000;
-
-#endif /* __osf1__ && __alpha__ */
-
-    *abs_sec = abs.tv_sec;
-    *abs_nsec = abs.tv_nsec;
-}
-
-
-int
-omni_thread::posix_priority(priority_t pri)
-{
-#ifdef PthreadSupportThreadPriority
-    switch (pri) {
-
-    case PRIORITY_LOW:
-       return lowest_priority;
-
-    case PRIORITY_NORMAL:
-       return normal_priority;
-
-    case PRIORITY_HIGH:
-       return highest_priority;
-
-    }
-#endif
-
-    throw omni_thread_invalid();
-#ifdef _MSC_VER
-    return 0;
-#endif
-}
-
-void
-omni_thread::stacksize(unsigned long sz)
-{
-  stack_size = sz;
-}
-
-unsigned long
-omni_thread::stacksize()
-{
-  return stack_size;
-}
-
-//
-// Dummy thread
-//
-
-class omni_thread_dummy : public omni_thread {
-public:
-  inline omni_thread_dummy() : omni_thread()
-  {
-    _dummy = 1;
-    _state = STATE_RUNNING;
-    posix_thread = pthread_self();
-    THROW_ERRORS(pthread_setspecific(self_key, (void*)this));
-  }
-  inline ~omni_thread_dummy()
-  {
-    THROW_ERRORS(pthread_setspecific(self_key, 0));
-  }
-};
-
-omni_thread*
-omni_thread::create_dummy()
-{
-  if (omni_thread::self())
-    throw omni_thread_invalid();
-
-  return new omni_thread_dummy;
-}
-
-void
-omni_thread::release_dummy()
-{
-  omni_thread* self = omni_thread::self();
-  if (!self || !self->_dummy)
-    throw omni_thread_invalid();
-
-  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
-  delete dummy;
-}
-
-
-#define INSIDE_THREAD_IMPL_CC
-#include "threaddata.cc"
-#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/solaris.cc b/gnuradio-core/src/lib/omnithread/solaris.cc
deleted file mode 100644 (file)
index b0139d2..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-//                             Package : omnithread
-// omnithread/solaris.cc       Created : 7/94 tjr
-//
-//    Copyright (C) 1994-1999 AT&T Laboratories Cambridge
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-//
-// Implementation of OMNI thread abstraction for solaris threads.
-//
-
-#include <stdlib.h>
-#include <errno.h>
-#include <omnithread.h>
-
-#define DB(x) // x 
-// #include <iostream> or #include <iostream.h> if DB is on.
-
-#define THROW_ERRORS(x) { int rc = (x); \
-                         if (rc != 0) throw omni_thread_fatal(rc); }
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Mutex
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_mutex::omni_mutex(void)
-{
-    THROW_ERRORS(mutex_init(&sol_mutex, USYNC_THREAD, 0));
-}
-
-omni_mutex::~omni_mutex(void)
-{
-    THROW_ERRORS(mutex_destroy(&sol_mutex));
-}
-
-void
-omni_mutex::lock(void)
-{
-    THROW_ERRORS(mutex_lock(&sol_mutex));
-}
-
-void
-omni_mutex::unlock(void)
-{
-    THROW_ERRORS(mutex_unlock(&sol_mutex));
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Condition variable
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_condition::omni_condition(omni_mutex* m) : mutex(m)
-{
-    THROW_ERRORS(cond_init(&sol_cond, USYNC_THREAD, 0));
-}
-
-omni_condition::~omni_condition(void)
-{
-    THROW_ERRORS(cond_destroy(&sol_cond));
-}
-
-void
-omni_condition::wait(void)
-{
-    THROW_ERRORS(cond_wait(&sol_cond, &mutex->sol_mutex));
-}
-
-int
-omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
-{
-    timespec rqts = { secs, nanosecs };
-
- again:
-    int rc = cond_timedwait(&sol_cond, &mutex->sol_mutex, &rqts);
-
-    if (rc == 0)
-       return 1;
-
-    if (rc == EINTR)
-        goto again;
-
-    if (rc == ETIME)
-       return 0;
-
-    throw omni_thread_fatal(rc);
-}
-
-void
-omni_condition::signal(void)
-{
-    THROW_ERRORS(cond_signal(&sol_cond));
-}
-
-void
-omni_condition::broadcast(void)
-{
-    THROW_ERRORS(cond_broadcast(&sol_cond));
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Counting semaphore
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-omni_semaphore::omni_semaphore(unsigned int initial)
-{
-    THROW_ERRORS(sema_init(&sol_sem, initial, USYNC_THREAD, NULL));
-}
-
-omni_semaphore::~omni_semaphore(void)
-{
-    THROW_ERRORS(sema_destroy(&sol_sem));
-}
-
-void
-omni_semaphore::wait(void)
-{
-    THROW_ERRORS(sema_wait(&sol_sem));
-}
-
-void
-omni_semaphore::post(void)
-{
-    THROW_ERRORS(sema_post(&sol_sem));
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-//
-// Static variables
-//
-
-int omni_thread::init_t::count = 0;
-
-omni_mutex* omni_thread::next_id_mutex;
-int omni_thread::next_id = 0;
-
-static thread_key_t self_key;
-
-static size_t stack_size = 0;
-
-//
-// Initialisation function (gets called before any user code).
-//
-
-omni_thread::init_t::init_t(void)
-{
-    if (count++ != 0)  // only do it once however many objects get created.
-       return;
-
-    DB(cerr << "omni_thread::init: solaris implementation initialising\n");
-
-    THROW_ERRORS(thr_keycreate(&self_key, NULL));
-
-    next_id_mutex = new omni_mutex;
-
-    //
-    // Create object for this (i.e. initial) thread.
-    //
-
-    omni_thread* t = new omni_thread;
-
-    t->_state = STATE_RUNNING;
-
-    t->sol_thread = thr_self();
-
-    DB(cerr << "initial thread " << t->id() << " sol_thread " << t->sol_thread
-       << endl);
-
-    THROW_ERRORS(thr_setspecific(self_key, (void*)t));
-
-    THROW_ERRORS(thr_setprio(t->sol_thread, sol_priority(PRIORITY_NORMAL)));
-}
-
-
-//
-// Wrapper for thread creation.
-//
-
-extern "C" void*
-omni_thread_wrapper(void* ptr)
-{
-    omni_thread* me = (omni_thread*)ptr;
-
-    DB(cerr << "omni_thread::wrapper: thread " << me->id()
-       << " started\n");
-
-    THROW_ERRORS(thr_setspecific(self_key, me));
-
-    //
-    // Now invoke the thread function with the given argument.
-    //
-
-    if (me->fn_void != NULL) {
-       (*me->fn_void)(me->thread_arg);
-       omni_thread::exit();
-    }
-
-    if (me->fn_ret != NULL) {
-       void* return_value = (*me->fn_ret)(me->thread_arg);
-       omni_thread::exit(return_value);
-    }
-
-    if (me->detached) {
-       me->run(me->thread_arg);
-       omni_thread::exit();
-    } else {
-       void* return_value = me->run_undetached(me->thread_arg);
-       omni_thread::exit(return_value);
-    }
-
-    // should never get here.
-
-    return NULL;
-}
-
-
-//
-// Constructors for omni_thread - set up the thread object but don't
-// start it running.
-//
-
-// construct a detached thread running a given function.
-
-omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 1);
-    fn_void = fn;
-    fn_ret = NULL;
-}
-
-// construct an undetached thread running a given function.
-
-omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 0);
-    fn_void = NULL;
-    fn_ret = fn;
-}
-
-// construct a thread which will run either run() or run_undetached().
-
-omni_thread::omni_thread(void* arg, priority_t pri)
-{
-    common_constructor(arg, pri, 1);
-    fn_void = NULL;
-    fn_ret = NULL;
-}
-
-// common part of all constructors.
-
-void
-omni_thread::common_constructor(void* arg, priority_t pri, int det)
-{
-    _state = STATE_NEW;
-    _priority = pri;
-
-    next_id_mutex->lock();
-    _id = next_id++;
-    next_id_mutex->unlock();
-
-    thread_arg = arg;
-    detached = det;    // may be altered in start_undetached()
-
-    _dummy       = 0;
-    _values      = 0;
-    _value_alloc = 0;
-    // sol_thread is set up in initialisation routine or start().
-}
-
-
-//
-// Destructor for omni_thread.
-//
-
-omni_thread::~omni_thread(void)
-{
-    DB(cerr << "destructor called for thread " << id() << endl);
-    if (_values) {
-        for (key_t i=0; i < _value_alloc; i++) {
-           if (_values[i]) {
-               delete _values[i];
-           }
-        }
-       delete [] _values;
-    }
-}
-
-
-//
-// Start the thread
-//
-
-void
-omni_thread::start(void)
-{
-    long flags = 0;
-
-    if (detached)
-       flags |= THR_DETACHED;
-
-    omni_mutex_lock l(mutex);
-
-    if (_state != STATE_NEW)
-       throw omni_thread_invalid();
-
-    THROW_ERRORS(thr_create(0, stack_size, omni_thread_wrapper, (void*)this, flags,
-                           &sol_thread));
-
-    _state = STATE_RUNNING;
-
-    THROW_ERRORS(thr_setprio(sol_thread, sol_priority(_priority)));
-}
-
-
-//
-// Start a thread which will run the member function run_undetached().
-//
-
-void
-omni_thread::start_undetached(void)
-{
-    if ((fn_void != NULL) || (fn_ret != NULL))
-       throw omni_thread_invalid();
-
-    detached = 0;
-    start();
-}
-
-
-//
-// join - simply check error conditions & call thr_join.
-//
-
-void
-omni_thread::join(void** status)
-{
-    mutex.lock();
-
-    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
-       mutex.unlock();
-       throw omni_thread_invalid();
-    }
-
-    mutex.unlock();
-
-    if (this == self())
-       throw omni_thread_invalid();
-
-    if (detached)
-       throw omni_thread_invalid();
-
-    DB(cerr << "omni_thread::join: doing thr_join\n");
-
-    THROW_ERRORS(thr_join(sol_thread, (thread_t *)NULL, status));
-
-    DB(cerr << "omni_thread::join: thr_join succeeded\n");
-
-    delete this;
-}
-
-
-//
-// Change this thread's priority.
-//
-
-void
-omni_thread::set_priority(priority_t pri)
-{
-    omni_mutex_lock l(mutex);
-
-    if (_state != STATE_RUNNING)
-       throw omni_thread_invalid();
-
-    _priority = pri;
-
-    THROW_ERRORS(thr_setprio(sol_thread, sol_priority(pri)));
-}
-
-
-//
-// create - construct a new thread object and start it running.  Returns thread
-// object if successful, null pointer if not.
-//
-
-// detached version
-
-omni_thread*
-omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
-{
-    omni_thread* t = new omni_thread(fn, arg, pri);
-
-    t->start();
-
-    return t;
-}
-
-// undetached version
-
-omni_thread*
-omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
-{
-    omni_thread* t = new omni_thread(fn, arg, pri);
-
-    t->start();
-
-    return t;
-}
-
-
-//
-// exit() _must_ lock the mutex even in the case of a detached thread.  This is
-// because a thread may run to completion before the thread that created it has
-// had a chance to get out of start().  By locking the mutex we ensure that the
-// creating thread must have reached the end of start() before we delete the
-// thread object.  Of course, once the call to start() returns, the user can
-// still incorrectly refer to the thread object, but that's their problem.
-//
-
-void
-omni_thread::exit(void* return_value)
-{
-    omni_thread* me = self();
-
-    if (me)
-      {
-       me->mutex.lock();
-
-       me->_state = STATE_TERMINATED;
-
-       me->mutex.unlock();
-
-       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
-          << me->detached << " return value " << return_value << endl);
-
-       if (me->detached)
-         delete me;
-      }
-    else
-      {
-       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
-      }
-
-    thr_exit(return_value);
-}
-
-
-omni_thread*
-omni_thread::self(void)
-{
-    omni_thread* me;
-
-    THROW_ERRORS(thr_getspecific(self_key, (void**)&me));
-
-    if (!me) {
-      // This thread is not created by omni_thread::start because it
-      // doesn't has a class omni_thread instance attached to its key.
-      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
-    }
-
-    return me;
-}
-
-
-void
-omni_thread::yield(void)
-{
-    thr_yield();
-}
-
-
-void
-omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
-{
-    timespec rqts = { secs, nanosecs };
-    timespec remain;
-    while (nanosleep(&rqts, &remain)) {
-      if (errno == EINTR) {
-       rqts.tv_sec  = remain.tv_sec;
-       rqts.tv_nsec = remain.tv_nsec;
-       continue;
-      }
-      else
-       throw omni_thread_fatal(errno);
-    }
-}
-
-
-void
-omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
-                     unsigned long rel_sec, unsigned long rel_nsec)
-{
-    timespec abs;
-    clock_gettime(CLOCK_REALTIME, &abs);
-    abs.tv_nsec += rel_nsec;
-    abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
-    abs.tv_nsec = abs.tv_nsec % 1000000000;
-    *abs_sec = abs.tv_sec;
-    *abs_nsec = abs.tv_nsec;
-}
-
-
-int
-omni_thread::sol_priority(priority_t pri)
-{
-    switch (pri) {
-
-    case PRIORITY_LOW:
-       return 0;
-
-    case PRIORITY_NORMAL:
-       return 1;
-
-    case PRIORITY_HIGH:
-       return 2;
-    }
-
-    throw omni_thread_invalid();
-}
-
-
-void
-omni_thread::stacksize(unsigned long sz)
-{
-  stack_size = sz;
-}
-
-unsigned long
-omni_thread::stacksize()
-{
-  return stack_size;
-}
-
-
-//
-// Dummy thread
-//
-
-#error This dummy thread code is not tested. It might work if you're lucky.
-
-class omni_thread_dummy : public omni_thread {
-public:
-  inline omni_thread_dummy() : omni_thread()
-  {
-    _dummy = 1;
-    _state = STATE_RUNNING;
-    sol_thread = thr_self();
-    THROW_ERRORS(thr_setspecific(self_key, (void*)this));
-  }
-  inline ~omni_thread_dummy()
-  {
-    THROW_ERRORS(thr_setspecific(self_key, 0));
-  }
-};
-
-omni_thread*
-omni_thread::create_dummy()
-{
-  if (omni_thread::self())
-    throw omni_thread_invalid();
-
-  return new omni_thread_dummy;
-}
-
-void
-omni_thread::release_dummy()
-{
-  omni_thread* self = omni_thread::self();
-  if (!self || !self->_dummy)
-    throw omni_thread_invalid();
-
-  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
-  delete dummy;
-}
-
-
-#define INSIDE_THREAD_IMPL_CC
-#include "threaddata.cc"
-#undef INSIDE_THREAD_IMPL_CC
diff --git a/gnuradio-core/src/lib/omnithread/threaddata.cc b/gnuradio-core/src/lib/omnithread/threaddata.cc
deleted file mode 100644 (file)
index d54c439..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-//                             Package : omnithread
-// omnithread/threaddata.cc    Created : 10/2000 dpg1
-//
-//    Copyright (C) 2000 AT&T Laboratories Cambridge
-//
-//    This file is part of the omnithread library
-//
-//    The omnithread 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., 51 Franklin Street, Boston, MA  
-//    02110-1301, USA
-//
-
-// Implementation of per-thread data
-
-#ifndef INSIDE_THREAD_IMPL_CC
-#error "threaddata.cc must be #included by a thread implementation."
-#endif
-
-
-static omni_thread::key_t allocated_keys = 0;
-
-omni_thread::key_t
-omni_thread::allocate_key()
-{
-  omni_mutex_lock l(*next_id_mutex);
-  return ++allocated_keys;
-}
-
-omni_thread::value_t*
-omni_thread::set_value(key_t k, value_t* v)
-{
-  if (k == 0) return 0;
-  if (k > _value_alloc) {
-    next_id_mutex->lock();
-    key_t alloc = allocated_keys;
-    next_id_mutex->unlock();
-
-    if (k > alloc) return 0;
-
-    value_t** nv = new value_t*[alloc];
-    key_t i = 0;
-    if (_values) {
-      for (; i < _value_alloc; i++)
-       nv[i] = _values[i];
-      delete [] _values;
-    }
-    for (; i < alloc; i++)
-      nv[i] = 0;
-
-    _values = nv;
-    _value_alloc = alloc;
-  }
-  if (_values[k-1]) delete _values[k-1];
-  _values[k-1] = v;
-  return v;
-}
-
-omni_thread::value_t*
-omni_thread::get_value(key_t k)
-{
-  if (k > _value_alloc) return 0;
-  return _values[k-1];
-}
-
-omni_thread::value_t*
-omni_thread::remove_value(key_t k)
-{
-  if (k > _value_alloc) return 0;
-  value_t* v = _values[k-1];
-  _values[k-1] = 0;
-  return v;
-}
diff --git a/gnuradio-core/src/lib/omnithread/vxWorks.cc b/gnuradio-core/src/lib/omnithread/vxWorks.cc
deleted file mode 100644 (file)
index 25634ce..0000000
+++ /dev/null
@@ -1,1160 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Filename:    vxWorks.cc
-// Author:             Tihomir Sokcevic
-//                                     Acterna, Eningen.
-// Description: vxWorks adaptation of the omnithread wrapper classes
-// Notes:               Munching strategy is imperative
-//////////////////////////////////////////////////////////////////////////////
-// $Log$
-// Revision 1.1  2004/04/10 18:00:52  eb
-// Initial revision
-//
-// Revision 1.1.1.1  2004/03/01 00:20:27  eb
-// initial checkin
-//
-// Revision 1.1  2003/05/25 05:29:04  eb
-// see ChangeLog
-//
-// Revision 1.1.2.1  2003/02/17 02:03:11  dgrisby
-// vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
-//
-// Revision 1.1.1.1  2002/11/19 14:58:04  sokcevti
-// OmniOrb4.0.0 VxWorks port
-//
-// Revision 1.4  2002/10/15 07:54:09  kuttlest
-// change semaphore from SEM_FIFO to SEM_PRIO
-// ---
-//
-// Revision 1.3  2002/07/05 07:38:52  engeln
-// made priority redefinable on load time by defining int variables
-//     omni_thread_prio_low = 220;
-//     omni_thread_prio_normal = 110;
-//     omni_thread_prio_high = 55;
-// the default priority is prio_normal.
-// The normal priority default has been increased from 200 to 110 and the
-//     high priority from 100 to 55.
-// ---
-//
-// Revision 1.2  2002/06/14 12:44:57  engeln
-// replaced possibly unsafe wakeup procedure in broadcast.
-// ---
-//
-// Revision 1.1.1.1  2002/04/02 10:09:34  sokcevti
-// omniORB4 initial realease
-//
-// Revision 1.0        2001/10/23 14:22:45     sokcevti
-// Initial Version 4.00
-// ---
-//
-//////////////////////////////////////////////////////////////////////////////
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Include files
-//////////////////////////////////////////////////////////////////////////////
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <time.h>
-#include <omnithread.h>
-#include <sysLib.h>
-
-#include <assert.h>            // assert
-#include <intLib.h>            // intContext
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Local defines
-//////////////////////////////////////////////////////////////////////////////
-#define ERRNO(x) (((x) != 0) ? (errno) : 0)
-#define THROW_ERRORS(x) { if((x) != OK) throw omni_thread_fatal(errno); }
-#define OMNI_THREAD_ID 0x7F7155AAl
-#define OMNI_STACK_SIZE 32768l
-
-#ifdef _DEBUG
-       #include <fstream>
-       #define DBG_TRACE(X) X
-#else // _DEBUG
-       #define DBG_TRACE(X)
-#endif // _DEBUG
-
-#define DBG_ASSERT(X)
-
-#define DBG_THROW(X) X
-
-int omni_thread_prio_low = 220;
-int omni_thread_prio_normal = 110;
-int omni_thread_prio_high = 55;
-///////////////////////////////////////////////////////////////////////////
-//
-// Mutex
-//
-///////////////////////////////////////////////////////////////////////////
-omni_mutex::omni_mutex(void):m_bConstructed(false)
-{
-       mutexID = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
-
-       DBG_ASSERT(assert(mutexID != NULL));
-
-       if(mutexID==NULL)
-       {
-               DBG_TRACE(cout<<"Exception: omni_mutex::omni_mutex()  tid: "<<(int)taskIdSelf()<<endl);
-               DBG_THROW(throw omni_thread_fatal(-1));
-       }
-
-       m_bConstructed = true;
-}
-
-omni_mutex::~omni_mutex(void)
-{
-       m_bConstructed = false;
-
-       STATUS status = semDelete(mutexID);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_mutex::~omni_mutex()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-/*
-void omni_mutex::lock(void)
-{
-       DBG_ASSERT(assert(!intContext()));              // not in ISR context
-       DBG_ASSERT(assert(m_bConstructed));
-
-       STATUS status = semTake(mutexID, WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_mutex::lock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-void omni_mutex::unlock(void)
-{
-       DBG_ASSERT(assert(m_bConstructed));
-
-       STATUS status = semGive(mutexID);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_mutex::unlock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-*/
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Condition variable
-//
-///////////////////////////////////////////////////////////////////////////
-omni_condition::omni_condition(omni_mutex* m) : mutex(m)
-{
-       DBG_TRACE(cout<<"omni_condition::omni_condition  mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
-
-       waiters_ = 0;
-
-       sema_ = semCCreate(SEM_Q_PRIORITY, 0);
-       if(sema_ == NULL)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       waiters_lock_ = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
-       if(waiters_lock_ == NULL)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-}
-
-omni_condition::~omni_condition(void)
-{
-       STATUS status = semDelete(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       status = semDelete(sema_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-void omni_condition::wait(void)
-{
-       DBG_TRACE(cout<<"omni_condition::wait            mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
-
-       // Prevent race conditions on the <waiters_> count.
-
-       STATUS status = semTake(waiters_lock_,WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       ++waiters_;
-
-       status = semGive(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       // disable task lock to have an atomic unlock+semTake
-       taskLock();
-
-       // We keep the lock held just long enough to increment the count of
-       // waiters by one.      Note that we can't keep it held across the call
-       // to wait() since that will deadlock other calls to signal().
-       mutex->unlock();
-
-       // Wait to be awakened by a cond_signal() or cond_broadcast().
-       status = semTake(sema_,WAIT_FOREVER);
-
-       // reenable task rescheduling
-       taskUnlock();
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       // Reacquire lock to avoid race conditions on the <waiters_> count.
-       status = semTake(waiters_lock_,WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       // We're ready to return, so there's one less waiter.
-       --waiters_;
-
-       // Release the lock so that other collaborating threads can make
-       // progress.
-       status = semGive(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       // Bad things happened, so let's just return below.
-
-       // We must always regain the <external_mutex>, even when errors
-       // occur because that's the guarantee that we give to our callers.
-       mutex->lock();
-}
-
-
-// The time given is absolute. Return 0 is timeout
-int omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
-{
-       STATUS result = OK;
-       timespec now;
-       unsigned long timeout;
-       int ticks;
-
-       // Prevent race conditions on the <waiters_> count.
-       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       ++waiters_;
-
-       status = semGive(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       clock_gettime(CLOCK_REALTIME, &now);
-
-       if(((unsigned long)secs <= (unsigned long)now.tv_sec) &&
-               (((unsigned long)secs < (unsigned long)now.tv_sec) ||
-               (nanosecs < (unsigned long)now.tv_nsec)))
-               timeout = 0;
-       else
-               timeout = (secs-now.tv_sec) * 1000 + (nanosecs-now.tv_nsec) / 1000000l;
-
-       // disable task lock to have an atomic unlock+semTake
-       taskLock();
-
-       // We keep the lock held just long enough to increment the count
-       // of waiters by one.
-       mutex->unlock();
-
-       // Wait to be awakened by a signal() or broadcast().
-       ticks = (timeout * sysClkRateGet()) / 1000L;
-       result = semTake(sema_, ticks);
-
-       // reenable task rescheduling
-       taskUnlock();
-
-       // Reacquire lock to avoid race conditions.
-       status = semTake(waiters_lock_, WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       --waiters_;
-
-       status = semGive(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       // A timeout has occured - fires exception if the origin is other than timeout
-       if(result!=OK && !(errno == S_objLib_OBJ_TIMEOUT || errno == S_objLib_OBJ_UNAVAILABLE))
-       {
-               DBG_TRACE(cout<<"omni_condition::timedwait! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       // We must always regain the <external_mutex>, even when errors
-       // occur because that's the guarantee that we give to our callers.
-       mutex->lock();
-
-       if(result!=OK) // timeout
-               return 0;
-
-       return 1;
-}
-
-void omni_condition::signal(void)
-{
-       DBG_TRACE(cout<<"omni_condition::signal          mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
-
-       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       int have_waiters = waiters_ > 0;
-
-       status = semGive(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       if(have_waiters != 0)
-       {
-               status = semGive(sema_);
-
-               DBG_ASSERT(assert(status == OK));
-
-               if(status != OK)
-               {
-                       DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
-                       DBG_THROW(throw omni_thread_fatal(errno));
-               }
-       }
-}
-
-void omni_condition::broadcast(void)
-{
-       DBG_TRACE(cout<<"omni_condition::broadcast       mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
-
-       int have_waiters = 0;
-
-       // The <external_mutex> must be locked before this call is made.
-       // This is needed to ensure that <waiters_> and <was_broadcast_> are
-       // consistent relative to each other.
-       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       if(waiters_ > 0)
-       {
-               // We are broadcasting, even if there is just one waiter...
-               // Record the fact that we are broadcasting.    This helps the
-               // cond_wait() method know how to optimize itself.      Be sure to
-               // set this with the <waiters_lock_> held.
-               have_waiters = 1;
-       }
-
-       status = semGive(waiters_lock_);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-
-       if(have_waiters)
-       {
-               // Wake up all the waiters.
-               status = semFlush(sema_);
-
-                       DBG_ASSERT(assert(status == OK));
-
-                       if(status != OK)
-                       {
-                               DBG_TRACE(cout<<"omni_condition::broadcast1! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
-                               DBG_THROW(throw omni_thread_fatal(errno));
-                       }
-
-       }
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Counting semaphore
-//
-///////////////////////////////////////////////////////////////////////////
-omni_semaphore::omni_semaphore(unsigned int initial)
-{
-
-       DBG_ASSERT(assert(0 <= (int)initial));          // POSIX expects only unsigned init values
-
-       semID = semCCreate(SEM_Q_PRIORITY, (int)initial);
-
-       DBG_ASSERT(assert(semID!=NULL));
-
-       if(semID==NULL)
-       {
-               DBG_TRACE(cout<<"Exception: omni_semaphore::omni_semaphore"<<endl);
-               DBG_THROW(throw omni_thread_fatal(-1));
-       }
-}
-
-omni_semaphore::~omni_semaphore(void)
-{
-       STATUS status = semDelete(semID);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_semaphore::~omni_semaphore"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-void omni_semaphore::wait(void)
-{
-       DBG_ASSERT(assert(!intContext()));              // no wait in ISR
-
-       STATUS status = semTake(semID, WAIT_FOREVER);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_semaphore::wait"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-int omni_semaphore::trywait(void)
-{
-       STATUS status = semTake(semID, NO_WAIT);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               if(errno == S_objLib_OBJ_UNAVAILABLE)
-               {
-                       return 0;
-               }
-               else
-               {
-                       DBG_ASSERT(assert(false));
-
-                       DBG_TRACE(cout<<"Exception: omni_semaphore::trywait"<<endl);
-                       DBG_THROW(throw omni_thread_fatal(errno));
-               }
-       }
-
-       return 1;
-}
-
-void omni_semaphore::post(void)
-{
-       STATUS status = semGive(semID);
-
-       DBG_ASSERT(assert(status == OK));
-
-       if(status != OK)
-       {
-               DBG_TRACE(cout<<"Exception: omni_semaphore::post"<<endl);
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// Thread
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-//
-// static variables
-//
-omni_mutex* omni_thread::next_id_mutex = 0;
-int omni_thread::next_id = 0;
-
-// omniORB requires a larger stack size than the default (21120) on OSF/1
-static size_t stack_size = OMNI_STACK_SIZE;
-
-
-//
-// Initialisation function (gets called before any user code).
-//
-
-static int& count() {
-  static int the_count = 0;
-  return the_count;
-}
-
-omni_thread::init_t::init_t(void)
-{
-       // Only do it once however many objects get created.
-       if(count()++ != 0)
-               return;
-
-       attach();
-}
-
-omni_thread::init_t::~init_t(void)
-{
-    if (--count() != 0) return;
-
-    omni_thread* self = omni_thread::self();
-    if (!self) return;
-
-    taskTcb(taskIdSelf())->spare1 = 0;
-    delete self;
-
-    delete next_id_mutex;
-}
-
-
-//
-// Wrapper for thread creation.
-//
-extern "C" void omni_thread_wrapper(void* ptr)
-{
-       omni_thread* me = (omni_thread*)ptr;
-
-       DBG_TRACE(cout<<"omni_thread_wrapper: thread "<<me->id()<<" started\n");
-
-       //
-       // We can now tweaked the task info since the tcb exist now
-       //
-       me->mutex.lock();       // To ensure that start has had time to finish
-       taskTcb(me->tid)->spare1 = OMNI_THREAD_ID;
-       taskTcb(me->tid)->spare2 = (int)ptr;
-       me->mutex.unlock();
-
-       //
-       // Now invoke the thread function with the given argument.
-       //
-       if(me->fn_void != NULL)
-       {
-               (*me->fn_void)(me->thread_arg);
-               omni_thread::exit();
-       }
-
-       if(me->fn_ret != NULL)
-       {
-               void* return_value = (*me->fn_ret)(me->thread_arg);
-               omni_thread::exit(return_value);
-       }
-
-       if(me->detached)
-       {
-               me->run(me->thread_arg);
-               omni_thread::exit();
-       }
-       else
-       {
-               void* return_value = me->run_undetached(me->thread_arg);
-               omni_thread::exit(return_value);
-       }
-}
-
-
-//
-// Special functions for VxWorks only
-//
-void omni_thread::attach(void)
-{
-       DBG_TRACE(cout<<"omni_thread_attach: VxWorks mapping thread initialising\n");
-
-       int _tid = taskIdSelf();
-
-       // Check the task is not already attached
-       if(taskTcb(_tid)->spare1 == OMNI_THREAD_ID)
-               return;
-
-       // Create the mutex required to lock the threads debugging id (create before the thread!!!)
-       if(next_id_mutex == 0)
-               next_id_mutex = new omni_mutex;
-
-       // Create a thread object for THIS running process
-       omni_thread* t = new omni_thread;
-
-       // Lock its mutex straigh away!
-       omni_mutex_lock l(t->mutex);
-
-       // Adjust data members of this instance
-       t->_state = STATE_RUNNING;
-       t->tid = taskIdSelf();
-
-       // Set the thread values so it can be recongnised as a omni_thread
-       // Set the id last can possibly prevent race condition
-       taskTcb(t->tid)->spare2 = (int)t;
-       taskTcb(t->tid)->spare1 = OMNI_THREAD_ID;
-
-       // Create the running_mutex at this stage, but leave it empty. We are not running
-       //      in the task context HERE, so taking it would be disastrous.
-       t->running_cond = new omni_condition(&t->mutex);
-}
-
-
-void omni_thread::detach(void)
-{
-       DBG_TRACE(cout<<"omni_thread_detach: VxWorks detaching thread mapping\n");
-
-       int _tid = taskIdSelf();
-
-       // Check the task has a OMNI_THREAD attached
-       if(taskTcb(_tid)->spare1 != OMNI_THREAD_ID)
-               return;
-
-       // Invalidate the id NOW !
-       taskTcb(_tid)->spare1 = 0;
-
-       // Even if NULL, it is safe to delete the thread
-       omni_thread* t = (omni_thread*)taskTcb(_tid)->spare2;
-       // Fininsh cleaning the tcb structure
-       taskTcb(_tid)->spare2 = 0;
-
-       delete t;
-}
-
-
-//
-// Constructors for omni_thread - set up the thread object but don't
-// start it running.
-//
-
-// construct a detached thread running a given function.
-omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
-{
-       common_constructor(arg, pri, 1);
-       fn_void = fn;
-       fn_ret = NULL;
-}
-
-// construct an undetached thread running a given function.
-omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
-{
-       common_constructor(arg, pri, 0);
-       fn_void = NULL;
-       fn_ret = fn;
-}
-
-// construct a thread which will run either run() or run_undetached().
-
-omni_thread::omni_thread(void* arg, priority_t pri)
-{
-       common_constructor(arg, pri, 1);
-       fn_void = NULL;
-       fn_ret = NULL;
-}
-
-// common part of all constructors.
-void omni_thread::common_constructor(void* arg, priority_t pri, int det)
-{
-       _state = STATE_NEW;
-       _priority = pri;
-
-       // Set the debugging id
-       next_id_mutex->lock();
-       _id = next_id++;
-       next_id_mutex->unlock();
-
-       // Note : tid can only be setup when the task is up and running
-       tid = 0;
-
-       thread_arg = arg;
-       detached = det;         // may be altered in start_undetached()
-
-    _dummy       = 0;
-    _values      = 0;
-    _value_alloc = 0;
-}
-
-//
-// Destructor for omni_thread.
-//
-omni_thread::~omni_thread(void)
-{
-       DBG_TRACE(cout<<"omni_thread::~omni_thread for thread "<<id()<<endl);
-
-    if (_values) {
-        for (key_t i=0; i < _value_alloc; i++) {
-           if (_values[i]) {
-               delete _values[i];
-           }
-        }
-       delete [] _values;
-    }
-
-       delete running_cond;
-}
-
-
-//
-// Start the thread
-//
-void omni_thread::start(void)
-{
-       omni_mutex_lock l(mutex);
-
-       DBG_ASSERT(assert(_state == STATE_NEW));
-
-       if(_state != STATE_NEW)
-               DBG_THROW(throw omni_thread_invalid());
-
-       // Allocate memory for the task. (The returned id cannot be trusted by the task)
-       tid = taskSpawn(
-               NULL,                                                            // Task name
-               vxworks_priority(_priority),    // Priority
-               0,                                                                       // Option
-               stack_size,                                              // Stack size
-               (FUNCPTR)omni_thread_wrapper, // Priority
-               (int)this,                                                      // First argument is this
-               0,0,0,0,0,0,0,0,0                                // Remaining unused args
-               );
-
-       DBG_ASSERT(assert(tid!=ERROR));
-
-       if(tid==ERROR)
-               DBG_THROW(throw omni_thread_invalid());
-
-       _state = STATE_RUNNING;
-
-       // Create the running_mutex at this stage, but leave it empty. We are not running
-       //      in the task context HERE, so taking it would be disastrous.
-       running_cond = new omni_condition(&mutex);
-}
-
-
-//
-// Start a thread which will run the member function run_undetached().
-//
-void omni_thread::start_undetached(void)
-{
-       DBG_ASSERT(assert(!((fn_void != NULL) || (fn_ret != NULL))));
-
-       if((fn_void != NULL) || (fn_ret != NULL))
-               DBG_THROW(throw omni_thread_invalid());
-
-       detached = 0;
-
-       start();
-}
-
-
-//
-// join - Wait for the task to complete before returning to the calling process
-//
-void omni_thread::join(void** status)
-{
-       mutex.lock();
-
-       if((_state != STATE_RUNNING) && (_state != STATE_TERMINATED))
-       {
-               mutex.unlock();
-
-               DBG_ASSERT(assert(false));
-
-               DBG_THROW(throw omni_thread_invalid());
-       }
-
-       mutex.unlock();
-
-       DBG_ASSERT(assert(this != self()));
-
-       if(this == self())
-               DBG_THROW(throw omni_thread_invalid());
-
-       DBG_ASSERT(assert(!detached));
-
-       if(detached)
-               DBG_THROW(throw omni_thread_invalid());
-
-       mutex.lock();
-       running_cond->wait();
-       mutex.unlock();
-
-       if(status)
-               *status = return_val;
-
-       delete this;
-}
-
-
-//
-// Change this thread's priority.
-//
-void omni_thread::set_priority(priority_t pri)
-{
-       omni_mutex_lock l(mutex);
-
-       DBG_ASSERT(assert(_state == STATE_RUNNING));
-
-       if(_state != STATE_RUNNING)
-       {
-               DBG_THROW(throw omni_thread_invalid());
-       }
-
-       _priority = pri;
-
-       if(taskPrioritySet(tid, vxworks_priority(pri))==ERROR)
-       {
-               DBG_ASSERT(assert(false));
-
-               DBG_THROW(throw omni_thread_fatal(errno));
-       }
-}
-
-
-//
-// create - construct a new thread object and start it running.        Returns thread
-// object if successful, null pointer if not.
-//
-
-// detached version (the entry point is a void)
-omni_thread* omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
-{
-       omni_thread* t = new omni_thread(fn, arg, pri);
-
-       t->start();
-
-       return t;
-}
-
-// undetached version (the entry point is a void*)
-omni_thread* omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
-{
-       omni_thread* t = new omni_thread(fn, arg, pri);
-
-       t->start();
-
-       return t;
-}
-
-
-//
-// exit() _must_ lock the mutex even in the case of a detached thread. This is
-// because a thread may run to completion before the thread that created it has
-// had a chance to get out of start(). By locking the mutex we ensure that the
-// creating thread must have reached the end of start() before we delete the
-// thread object.      Of course, once the call to start() returns, the user can
-// still incorrectly refer to the thread object, but that's their problem.
-//
-void omni_thread::exit(void* return_value)
-{
-       omni_thread* me = self();
-
-       if(me)
-       {
-               me->mutex.lock();
-
-               me->return_val = return_value;
-               me->_state = STATE_TERMINATED;
-               me->running_cond->signal();
-
-               me->mutex.unlock();
-
-               DBG_TRACE(cout<<"omni_thread::exit: thread "<<me->id()<<" detached "<<me->detached<<" return value "<<(int)return_value<<endl);
-
-               if(me->detached)
-                       delete me;
-       }
-       else
-               DBG_TRACE(cout<<"omni_thread::exit: called with a non-omnithread. Exit quietly."<<endl);
-
-       taskDelete(taskIdSelf());
-}
-
-
-omni_thread* omni_thread::self(void)
-{
-       if(taskTcb(taskIdSelf())->spare1 != OMNI_THREAD_ID)
-               return NULL;
-
-       return (omni_thread*)taskTcb(taskIdSelf())->spare2;
-}
-
-
-void omni_thread::yield(void)
-{
-       taskDelay(NO_WAIT);
-}
-
-
-void omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
-{
-       int tps = sysClkRateGet();
-
-       // Convert to us to avoid overflow in the multiplication
-       //      tps should always be less than 1000 !
-       nanosecs /= 1000;
-
-       taskDelay(secs*tps + (nanosecs*tps)/1000000l);
-}
-
-
-void omni_thread::get_time( unsigned long* abs_sec,
-                                                       unsigned long* abs_nsec,
-                                                       unsigned long rel_sec,
-                                                       unsigned long rel_nsec)
-{
-       timespec abs;
-       clock_gettime(CLOCK_REALTIME, &abs);
-       abs.tv_nsec += rel_nsec;
-       abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
-       abs.tv_nsec = abs.tv_nsec % 1000000000;
-       *abs_sec = abs.tv_sec;
-       *abs_nsec = abs.tv_nsec;
-}
-
-
-int omni_thread::vxworks_priority(priority_t pri)
-{
-       switch (pri)
-       {
-       case PRIORITY_LOW:
-               return omni_thread_prio_low;
-
-       case PRIORITY_NORMAL:
-               return omni_thread_prio_normal;
-
-       case PRIORITY_HIGH:
-               return omni_thread_prio_high;
-       }
-
-       DBG_ASSERT(assert(false));
-
-       DBG_THROW(throw omni_thread_invalid());
-}
-
-
-void omni_thread::stacksize(unsigned long sz)
-{
-       stack_size = sz;
-}
-
-
-unsigned long omni_thread::stacksize()
-{
-       return stack_size;
-}
-
-
-void omni_thread::show(void)
-{
-       omni_thread *pThread;
-       int s1, s2;
-       int tid = taskIdSelf();
-
-       printf("TaskId is %.8x\n", tid);
-
-       s1 = taskTcb(tid)->spare1;
-
-       if(s1 != OMNI_THREAD_ID)
-       {
-               printf("Spare 1 is %.8x, and not recongnized\n", s1);
-
-               return;
-       }
-       else
-       {
-               printf("Spare 1 indicate an omni_thread.\n");
-       }
-
-       s2 = taskTcb(tid)->spare2;
-
-       if(s2 == 0)
-       {
-               printf("Spare 2 is NULL! - No thread object attached !!\n");
-
-               return;
-       }
-       else
-       {
-               printf("Thread object at %.8x\n", s2);
-       }
-
-       pThread = (omni_thread *)s2;
-
-       state_t status = pThread->_state;
-
-       printf("        | Thread status is ");
-
-       switch (status)
-       {
-       case STATE_NEW:
-               printf("NEW\n");                break;
-       case STATE_RUNNING:
-               printf("STATE_RUNNING\n"); break;
-       case STATE_TERMINATED:
-               printf("TERMINATED\n"); break;
-       default:
-               printf("Illegal (=%.8x)\n", (unsigned int)status);
-
-               return;
-       }
-
-       if(pThread->tid != tid)
-       {
-               printf("        | Task ID in thread object is different!! (=%.8x)\n", pThread->tid);
-
-               return;
-       }
-       else
-       {
-               printf("        | Task ID in thread consistent\n");
-       }
-
-       printf("\n");
-}
-
-
-//
-// Dummy thread
-//
-
-class omni_thread_dummy : public omni_thread {
-public:
-  inline omni_thread_dummy() : omni_thread()
-  {
-    _dummy = 1;
-    _state = STATE_RUNNING;
-
-       // Adjust data members of this instance
-       tid = taskIdSelf();
-
-       // Set the thread values so it can be recongnised as a omni_thread
-       // Set the id last can possibly prevent race condition
-       taskTcb(tid)->spare2 = (int)this;
-       taskTcb(tid)->spare1 = OMNI_THREAD_ID;
-   }
-  inline ~omni_thread_dummy()
-  {
-       taskTcb(taskIdSelf())->spare1 = 0;
-  }
-};
-
-omni_thread*
-omni_thread::create_dummy()
-{
-  if (omni_thread::self())
-    throw omni_thread_invalid();
-
-  return new omni_thread_dummy;
-}
-
-void
-omni_thread::release_dummy()
-{
-  omni_thread* self = omni_thread::self();
-  if (!self || !self->_dummy)
-    throw omni_thread_invalid();
-
-  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
-  delete dummy;
-}
-
-
-#define INSIDE_THREAD_IMPL_CC
-#include "threaddata.cc"
-#undef INSIDE_THREAD_IMPL_CC
diff --git a/omnithread/Makefile.am b/omnithread/Makefile.am
new file mode 100644 (file)
index 0000000..2eac4c9
--- /dev/null
@@ -0,0 +1,68 @@
+#
+# Copyright 2003 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+# 
+# GNU Radio 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 General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+# This is the omnithread package,
+#   extracted from the omniORB-4.0.1 distribution
+
+# we should do some configure hacking to determine these on the fly
+OMNITHREAD_DEFINES = -DPthreadDraftVersion=10
+
+INCLUDES = $(DEFINES) $(OMNITHREAD_DEFINES) $(OMNITHREAD_INCLUDES)
+
+# we call it libgromnithread to avoid a collision with libomnithread on Debian
+lib_LTLIBRARIES = libgromnithread.la
+
+# At this point we only support the posix and nt pthreads i/f...
+
+if OMNITHREAD_POSIX
+libgromnithread_la_SOURCES =           \
+       posix.cc
+endif
+
+if OMNITHREAD_NT
+libgromnithread_la_SOURCES =           \
+       nt.cc
+endif
+
+libgromnithread_la_LIBADD =            \
+       $(PTHREAD_LIBS)
+
+# ... but this code also came with the package
+
+EXTRA_DIST =                           \
+       mach.cc                         \
+       nt.cc                           \
+       posix.cc                        \
+       solaris.cc                      \
+       threaddata.cc                   \
+       vxWorks.cc                      \
+       dir.mk
+
+grinclude_HEADERS =                    \
+       omnithread.h                    \
+       ot_mach.h                       \
+       ot_nt.h                         \
+       ot_posix.h                      \
+       ot_pthread_nt.h                 \
+       ot_solaris.h                    \
+       ot_VxThread.h                   
diff --git a/omnithread/dir.mk b/omnithread/dir.mk
new file mode 100644 (file)
index 0000000..d538034
--- /dev/null
@@ -0,0 +1,229 @@
+ifeq ($(ThreadSystem),Solaris)
+CXXSRCS = solaris.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),Posix)
+CXXSRCS = posix.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS) $(OMNITHREAD_POSIX_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),NT)
+CXXSRCS = nt.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
+MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
+MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
+MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
+endif
+
+ifeq ($(ThreadSystem),NTPosix)
+CXXSRCS = posix.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+MSVC_STATICLIB_CXXNODEBUGFLAGS += -D_WINSTATIC
+MSVC_STATICLIB_CXXDEBUGFLAGS += -D_WINSTATIC
+MSVC_DLL_CXXNODEBUGFLAGS += -D_OMNITHREAD_DLL
+MSVC_DLL_CXXDEBUGFLAGS += -D_OMNITHREAD_DLL
+endif
+
+ifeq ($(ThreadSystem),Mach)
+CXXSRCS = mach.cc
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+ifeq ($(ThreadSystem),vxWorks)
+CXXSRCS = vxWorks.cc
+OBJS = vxWorks.o
+DIR_CPPFLAGS = $(OMNITHREAD_CPPFLAGS)
+endif
+
+LIB_NAME     := omnithread
+LIB_VERSION  := $(OMNITHREAD_VERSION)
+LIB_OBJS     := $(CXXSRCS:.cc=.o)
+LIB_IMPORTS  := $(OMNITHREAD_PLATFORM_LIB)
+
+all:: mkstatic mkshared
+
+export:: mkstatic mkshared
+
+ifdef INSTALLTARGET
+install:: mkstatic mkshared
+endif
+
+vers := $(subst ., ,$(LIB_VERSION))
+ifeq ($(words $(vers)), 2)
+  vers  := _ $(vers)
+  major := ""
+else
+  major := $(word 1, $(vers))
+endif
+
+namespec := $(LIB_NAME) $(vers)
+
+##############################################################################
+# Build Static library
+##############################################################################
+
+ifndef NoStaticLibrary
+
+staticlib := static/$(patsubst %,$(LibNoDebugPattern),$(LIB_NAME)$(major))
+
+mkstatic::
+       @(dir=static; $(CreateDir))
+
+mkstatic:: $(staticlib)
+
+$(staticlib): $(patsubst %, static/%, $(LIB_OBJS))
+       @$(StaticLinkLibrary)
+
+export:: $(staticlib)
+       @$(ExportLibrary)
+
+ifdef INSTALLTARGET
+install:: $(staticlib)
+       @$(InstallLibrary)
+endif
+
+clean::
+       $(RM) static/*.o
+       $(RM) $(staticlib)
+
+veryclean::
+       $(RM) static/*.o
+       $(RM) $(staticlib)
+
+else
+
+mkstatic::
+
+endif
+
+
+##############################################################################
+# Build Shared library
+##############################################################################
+ifdef BuildSharedLibrary
+
+shlib := shared/$(shell $(SharedLibraryFullName) $(namespec))
+
+ifdef Win32Platform
+# in case of Win32 lossage:
+  imps := $(patsubst $(DLLDebugSearchPattern),$(DLLNoDebugSearchPattern), \
+          $(LIB_IMPORTS))
+else
+  imps := $(LIB_IMPORTS)
+endif
+
+mkshared::
+       @(dir=shared; $(CreateDir))
+
+mkshared:: $(shlib)
+
+$(shlib): $(patsubst %, shared/%, $(LIB_OBJS))
+       @(namespec="$(namespec)" extralibs="$(imps)" nodeffile=1; \
+         $(MakeCXXSharedLibrary))
+
+export:: $(shlib)
+       @(namespec="$(namespec)"; \
+          $(ExportSharedLibrary))
+
+ifdef INSTALLTARGET
+install:: $(shlib)
+       @(namespec="$(namespec)"; \
+          $(InstallSharedLibrary))
+endif
+
+clean::
+       $(RM) shared/*.o
+       (dir=shared; $(CleanSharedLibrary))
+
+veryclean::
+       $(RM) shared/*.o
+       @(dir=shared; $(CleanSharedLibrary))
+
+else
+
+mkshared::
+
+endif
+
+##############################################################################
+# Build debug libraries for Win32
+##############################################################################
+ifdef Win32Platform
+
+ifdef BuildSharedLibrary
+
+all:: mkstaticdbug mkshareddbug
+
+export:: mkstaticdbug mkshareddbug
+
+else
+
+all:: mkstaticdbug
+
+export:: mkstaticdbug
+
+endif
+
+
+#####################################################
+#      Static debug libraries
+#####################################################
+
+dbuglib := debug/$(patsubst %,$(LibDebugPattern),$(LIB_NAME)$(major))
+
+mkstaticdbug::
+       @(dir=debug; $(CreateDir))
+
+mkstaticdbug:: $(dbuglib)
+
+$(dbuglib): $(patsubst %, debug/%, $(LIB_OBJS))
+       @$(StaticLinkLibrary)
+
+export:: $(dbuglib)
+       @$(ExportLibrary)
+
+clean::
+       $(RM) debug/*.o
+       $(RM) $(dbuglib)
+
+veryclean::
+       $(RM) debug/*.o
+       $(RM) $(dbuglib)
+
+#####################################################
+#      DLL debug libraries
+#####################################################
+
+ifdef BuildSharedLibrary
+
+dbugshlib := shareddebug/$(shell $(SharedLibraryDebugFullName) $(namespec))
+
+dbugimps  := $(patsubst $(DLLNoDebugSearchPattern),$(DLLDebugSearchPattern), \
+               $(LIB_IMPORTS))
+
+mkshareddbug::
+       @(dir=shareddebug; $(CreateDir))
+
+mkshareddbug:: $(dbugshlib)
+
+$(dbugshlib): $(patsubst %, shareddebug/%, $(LIB_OBJS))
+       (namespec="$(namespec)" debug=1 extralibs="$(dbugimps)" nodeffile=1; \
+         $(MakeCXXSharedLibrary))
+
+export:: $(dbugshlib)
+       @(namespec="$(namespec)" debug=1; \
+          $(ExportSharedLibrary))
+
+clean::
+       $(RM) shareddebug/*.o
+       @(dir=shareddebug; $(CleanSharedLibrary))
+
+veryclean::
+       $(RM) shareddebug/*.o
+       @(dir=shareddebug; $(CleanSharedLibrary))
+
+endif
+endif
+
diff --git a/omnithread/mach.cc b/omnithread/mach.cc
new file mode 100644 (file)
index 0000000..8759bb4
--- /dev/null
@@ -0,0 +1,714 @@
+//                             Package : omnithread
+// omnithread/mach.cc          Created : 7/97 lars immisch lars@ibp.de
+//
+//    Copyright (C) 1997 Immisch, Becker & Partner
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for mach threads
+//
+// to the author's pleasure, mach cthreads are very similar to posix threads
+//
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <mach/cthreads.h>
+#include "omnithread.h"
+
+#define DB(x) // x
+// #include <iostream> or #include <iostream.h> if DB is on.
+
+#define ERRNO(x) (x)
+
+//
+// static variables
+//
+
+int omni_thread::init_t::count = 0;
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static int normal_priority;
+static int highest_priority;
+
+static size_t stack_size = 0;
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+  mutex_init(&mach_mutex);     
+}
+
+
+omni_mutex::~omni_mutex(void)
+{
+  mutex_clear(&mach_mutex);    
+}
+
+
+void omni_mutex::lock(void)
+{
+  mutex_lock(&mach_mutex);
+}
+
+
+void omni_mutex::unlock(void)
+{
+  mutex_unlock(&mach_mutex);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+  condition_init(&mach_cond);
+}
+
+
+omni_condition::~omni_condition(void)
+{
+  condition_clear(&mach_cond);
+}
+
+void
+omni_condition::wait(void)
+{
+  condition_wait(&mach_cond, &mutex->mach_mutex);
+}
+
+typedef struct alarmclock_args {
+  unsigned long secs;
+  unsigned long nsecs;
+  bool wakeup;
+  condition_t condition;
+  mutex_t mutex;
+};
+
+any_t alarmclock(any_t arg)
+{
+  alarmclock_args* alarm = (alarmclock_args*)arg;
+       
+  omni_thread::sleep(alarm->secs, alarm->nsecs);
+
+  mutex_lock(alarm->mutex);
+                       
+  alarm->wakeup = TRUE;
+       
+  condition_signal(alarm->condition);
+               
+  mutex_unlock(alarm->mutex);
+
+  return (any_t)TRUE;
+}
+
+int omni_condition::timedwait(unsigned long abs_secs, unsigned long abs_nsecs)
+{
+  alarmclock_args alarm;
+
+  omni_thread::get_time(&alarm.secs, &alarm.nsecs, 0, 0);
+       
+  if (abs_secs < alarm.secs || (abs_secs == alarm.secs && abs_nsecs <= alarm.nsecs))
+    return ETIMEDOUT;
+
+  alarm.secs = abs_secs - alarm.secs;
+  if (abs_nsecs <= alarm.nsecs) {
+    alarm.nsecs = 1000000 - alarm.nsecs + abs_nsecs;
+    alarm.secs--;
+  }
+  else {
+    alarm.nsecs = abs_nsecs - alarm.nsecs;
+  }
+
+  alarm.mutex = &mutex->mach_mutex;
+  alarm.condition = &mach_cond;
+  alarm.wakeup = FALSE;
+       
+  cthread_t ct = cthread_fork((cthread_fn_t)alarmclock, (any_t)&alarm);
+  cthread_detach(ct);
+       
+  condition_wait(&mach_cond, &mutex->mach_mutex);
+               
+  if (alarm.wakeup) {
+    return 0;
+  }
+       
+  // interrupt the alarmclock thread sleep
+  cthread_abort(ct);
+       
+  // wait until it has signalled the condition
+  condition_wait(&mach_cond, &mutex->mach_mutex);
+
+  return 1;
+}
+
+
+void omni_condition::signal(void)
+{
+  condition_signal(&mach_cond);
+}
+
+
+void omni_condition::broadcast(void)
+{
+  condition_signal(&mach_cond);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial) : c(&m)
+{
+  value = initial;
+}
+
+
+omni_semaphore::~omni_semaphore(void)
+{
+}
+
+
+void 
+omni_semaphore::wait(void)
+{
+  omni_mutex_lock l(m);
+
+  while (value == 0)
+    c.wait();
+
+  value--;
+}
+
+
+int
+omni_semaphore::trywait(void)
+{
+  omni_mutex_lock l(m);
+
+  if (value == 0)
+    return 0;
+
+  value--;
+  return 1;
+}
+
+
+void
+omni_semaphore::post(void)
+{
+  omni_mutex_lock l(m);
+
+  if (value == 0)
+    c.signal();
+
+  value++;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+omni_thread::init_t::init_t(void)
+{
+  if (count++ != 0)    // only do it once however many objects get created.
+    return;
+
+  //
+  // find base and max priority. 
+  // This is the initial thread, so the max priority of this
+  // thread also applies to any newly created thread.
+  //
+
+  kern_return_t                                error;
+  struct thread_sched_info     info;
+  unsigned int                         info_count = THREAD_SCHED_INFO_COUNT;
+
+  error = thread_info(thread_self(), THREAD_SCHED_INFO, (thread_info_t)&info, &info_count);
+  if (error != KERN_SUCCESS) {
+    DB(cerr << "omni_thread::init: error determining thread_info" << endl);
+    ::exit(1);
+  }
+  else {
+    normal_priority = info.base_priority;
+    highest_priority = info.max_priority;
+  }
+
+  next_id_mutex = new omni_mutex;
+
+  //
+  // Create object for this (i.e. initial) thread.
+  //
+
+  omni_thread* t = new omni_thread;
+
+  if (t->_state != STATE_NEW) {
+    DB(cerr << "omni_thread::init: problem creating initial thread object\n");
+    ::exit(1);
+  }
+
+  t->_state = STATE_RUNNING;
+  
+  t->mach_thread = cthread_self();
+
+  DB(cerr << "initial thread " << t->id() << endl);
+
+  cthread_set_data(t->mach_thread, (any_t)t);
+}
+
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+  omni_thread* me = (omni_thread*)ptr;
+  
+  DB(cerr << "omni_thread::wrapper: thread " << me->id()
+     << " started\n");
+
+  cthread_set_data(cthread_self(), (any_t)me);
+
+  //
+  // Now invoke the thread function with the given argument.
+  //
+
+  if (me->fn_void != NULL) {
+    (*me->fn_void)(me->thread_arg);
+    omni_thread::exit();
+  }
+  
+  if (me->fn_ret != NULL) {
+    void* return_value = (*me->fn_ret)(me->thread_arg);
+    omni_thread::exit(return_value);
+  }
+  
+  if (me->detached) {
+    me->run(me->thread_arg);
+    omni_thread::exit();
+  } else {
+    void* return_value = me->run_undetached(me->thread_arg);
+    omni_thread::exit(return_value);
+  }
+
+  // should never get here.
+
+  return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+  common_constructor(arg, pri, 1);
+  fn_void = fn;
+  fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+  common_constructor(arg, pri, 0);
+  fn_void = NULL;
+  fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+  common_constructor(arg, pri, 1);
+  fn_void = NULL;
+  fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+  _state = STATE_NEW;
+  _priority = pri;
+  
+  next_id_mutex->lock();
+  _id = next_id++;
+  next_id_mutex->unlock();
+  
+  thread_arg = arg;
+  detached = det;      // may be altered in start_undetached()
+
+  _dummy       = 0;
+  _values      = 0;
+  _value_alloc = 0;
+  // posix_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+  DB(cerr << "destructor called for thread " << id() << endl);
+  if (_values) {
+    for (key_t i=0; i < _value_alloc; i++) {
+      if (_values[i]) {
+       delete _values[i];
+      }
+    }
+    delete [] _values;
+  }
+}
+
+
+//
+// Start the thread
+//
+
+void 
+omni_thread::start(void)
+{
+  omni_mutex_lock l(mutex);
+
+  int rc;
+
+  if (_state != STATE_NEW)
+    throw omni_thread_invalid();
+
+  mach_thread = cthread_fork(omni_thread_wrapper, (any_t)this);
+       
+  _state = STATE_RUNNING;
+
+  if (detached) {
+    cthread_detach(mach_thread);
+  }
+}
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+  if ((fn_void != NULL) || (fn_ret != NULL))
+    throw omni_thread_invalid();
+
+  detached = 0;
+  start();
+}
+
+
+//
+// join - simply check error conditions & call cthread_join.
+//
+
+void 
+omni_thread::join(void** status)
+{
+  mutex.lock();
+
+  if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+    mutex.unlock();
+    throw omni_thread_invalid();
+  }
+
+  mutex.unlock();
+
+  if (this == self())  
+    throw omni_thread_invalid();
+
+  if (detached)
+    throw omni_thread_invalid();
+
+  DB(cerr << "omni_thread::join: doing cthread_join\n");
+
+ *status = cthread_join(mach_thread);
+
+  delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+  omni_mutex_lock l(mutex);
+
+  if (_state != STATE_RUNNING)
+    throw omni_thread_invalid();
+
+  _priority = pri;
+
+  kern_return_t rc = cthread_priority(mach_thread, mach_priority(pri), FALSE);
+       
+  if (rc != KERN_SUCCESS)
+    throw omni_thread_fatal(errno);
+}
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread* 
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+  omni_thread* t = new omni_thread(fn, arg, pri);
+
+  t->start();
+
+  return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+  omni_thread* t = new omni_thread(fn, arg, pri);
+
+  t->start();
+
+  return t;
+}
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void omni_thread::exit(void* return_value)
+{
+  omni_thread* me = self();
+
+  if (me)
+    {
+      me->mutex.lock();
+
+      if (me->_state != STATE_RUNNING)
+       DB(cerr << "omni_thread::exit: thread not in \"running\" state\n");
+
+      me->_state = STATE_TERMINATED;
+
+      me->mutex.unlock();
+
+      DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+        << me->detached << " return value " << return_value << endl);
+
+      if (me->detached)
+       delete me;
+    }
+  else
+    {
+      DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+    }
+  cthread_exit(return_value);
+}
+
+omni_thread* omni_thread::self(void)
+{
+  omni_thread* me;
+
+  me = (omni_thread*)cthread_data(cthread_self());
+
+  if (!me) {
+    // This thread is not created by omni_thread::start because it
+    // doesn't has a class omni_thread instance attached to its key.
+    DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+  }
+       
+  return me;
+}
+
+void omni_thread::yield(void)
+{
+  cthread_yield();
+}
+
+#define MAX_SLEEP_SECONDS (unsigned)4294966    // (2**32-2)/1000
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+  if (secs <= MAX_SLEEP_SECONDS) {
+    thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, secs * 1000 + nanosecs / 1000000);
+    return;
+  }
+
+  unsigned no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
+
+  for (unsigned i = 0; i < no_of_max_sleeps; i++)
+    thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, MAX_SLEEP_SECONDS * 1000);
+
+  thread_switch(THREAD_NULL, SWITCH_OPTION_WAIT, 
+               (secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
+       
+  return;
+}
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+  int rc;
+  unsigned long tv_sec;
+  unsigned long tv_nsec;
+  struct timeval tv;
+       
+  rc = gettimeofday(&tv, NULL); 
+  if (rc)      throw omni_thread_fatal(rc);
+
+  tv_sec = tv.tv_sec;
+  tv_nsec = tv.tv_usec * 1000;
+
+  tv_nsec += rel_nsec;
+  tv_sec += rel_sec + tv_nsec / 1000000000;
+  tv_nsec = tv_nsec % 1000000000;
+
+  *abs_sec = tv_sec;
+  *abs_nsec = tv_nsec;
+}
+
+
+int 
+omni_thread::mach_priority(priority_t pri)
+{
+  switch (pri) {
+
+  case PRIORITY_LOW:
+    return 0;
+
+  case PRIORITY_NORMAL:
+    return normal_priority;
+
+  case PRIORITY_HIGH:
+    return highest_priority;
+
+  default:
+    return -1;
+  }
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+
+//
+// Dummy thread
+//
+
+#error This dummy thread code is not tested. It might work if you're lucky.
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+    mach_thread = cthread_self();
+    cthread_set_data(mach_thread, (any_t)this));
+  }
+  inline ~omni_thread_dummy()
+  {
+    cthread_set_data(mach_thread, (any_t)0));
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/omnithread/nt.cc b/omnithread/nt.cc
new file mode 100644 (file)
index 0000000..3853f01
--- /dev/null
@@ -0,0 +1,969 @@
+//                             Package : omnithread
+// omnithread/nt.cc            Created : 6/95 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1995-1999 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for NT threads
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <WinError.h>
+#include <omnithread.h>
+#include <process.h>
+
+#define DB(x) // x 
+//#include <iostream.h> or #include <iostream> if DB is on.
+
+static void get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec);
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+    InitializeCriticalSection(&crit);
+}
+
+omni_mutex::~omni_mutex(void)
+{
+    DeleteCriticalSection(&crit);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Condition variables are tricky to implement using NT synchronisation
+// primitives, since none of them have the atomic "release mutex and wait to be
+// signalled" which is central to the idea of a condition variable.  To get
+// around this the solution is to record which threads are waiting and
+// explicitly wake up those threads.
+//
+// Here we implement a condition variable using a list of waiting threads
+// (protected by a critical section), and a per-thread semaphore (which
+// actually only needs to be a binary semaphore).
+//
+// To wait on the cv, a thread puts itself on the list of waiting threads for
+// that cv, then releases the mutex and waits on its own personal semaphore.  A
+// signalling thread simply takes a thread from the head of the list and kicks
+// that thread's semaphore.  Broadcast is simply implemented by kicking the
+// semaphore of each waiting thread.
+//
+// The only other tricky part comes when a thread gets a timeout from a timed
+// wait on its semaphore.  Between returning with a timeout from the wait and
+// entering the critical section, a signalling thread could get in, kick the
+// waiting thread's semaphore and remove it from the list.  If this happens,
+// the waiting thread's semaphore is now out of step so it needs resetting, and
+// the thread should indicate that it was signalled rather than that it timed
+// out.
+//
+// It is possible that the thread calling wait or timedwait is not a
+// omni_thread. In this case we have to provide a temporary data structure,
+// i.e. for the duration of the call, for the thread to link itself on the
+// list of waiting threads. _internal_omni_thread_dummy provides such
+// a data structure and _internal_omni_thread_helper is a helper class to
+// deal with this special case for wait() and timedwait(). Once created,
+// the _internal_omni_thread_dummy is cached for use by the next wait() or
+// timedwait() call from a non-omni_thread. This is probably worth doing
+// because creating a Semaphore is quite heavy weight.
+
+class _internal_omni_thread_helper;
+
+class _internal_omni_thread_dummy : public omni_thread {
+public:
+  inline _internal_omni_thread_dummy() : next(0) { }
+  inline ~_internal_omni_thread_dummy() { }
+  friend class _internal_omni_thread_helper;
+private:
+  _internal_omni_thread_dummy* next;
+};
+
+class _internal_omni_thread_helper {
+public:
+  inline _internal_omni_thread_helper()  { 
+    d = 0;
+    t = omni_thread::self();
+    if (!t) {
+      omni_mutex_lock sync(cachelock);
+      if (cache) {
+       d = cache;
+       cache = cache->next;
+      }
+      else {
+       d = new _internal_omni_thread_dummy;
+      }
+      t = d;
+    }
+  }
+  inline ~_internal_omni_thread_helper() { 
+    if (d) {
+      omni_mutex_lock sync(cachelock);
+      d->next = cache;
+      cache = d;
+    }
+  }
+  inline operator omni_thread* () { return t; }
+  inline omni_thread* operator->() { return t; }
+
+  static _internal_omni_thread_dummy* cache;
+  static omni_mutex                   cachelock;
+
+private:
+  _internal_omni_thread_dummy* d;
+  omni_thread*                 t;
+};
+
+_internal_omni_thread_dummy* _internal_omni_thread_helper::cache = 0;
+omni_mutex                   _internal_omni_thread_helper::cachelock;
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+    InitializeCriticalSection(&crit);
+    waiting_head = waiting_tail = NULL;
+}
+
+
+omni_condition::~omni_condition(void)
+{
+    DeleteCriticalSection(&crit);
+    DB( if (waiting_head != NULL) {
+       cerr << "omni_condition::~omni_condition: list of waiting threads "
+            << "is not empty\n";
+    } )
+}
+
+
+void
+omni_condition::wait(void)
+{
+    _internal_omni_thread_helper me;
+
+    EnterCriticalSection(&crit);
+
+    me->cond_next = NULL;
+    me->cond_prev = waiting_tail;
+    if (waiting_head == NULL)
+       waiting_head = me;
+    else
+       waiting_tail->cond_next = me;
+    waiting_tail = me;
+    me->cond_waiting = TRUE;
+
+    LeaveCriticalSection(&crit);
+
+    mutex->unlock();
+
+    DWORD result = WaitForSingleObject(me->cond_semaphore, INFINITE);
+
+    mutex->lock();
+
+    if (result != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+int
+omni_condition::timedwait(unsigned long abs_sec, unsigned long abs_nsec)
+{
+    _internal_omni_thread_helper me;
+
+    EnterCriticalSection(&crit);
+
+    me->cond_next = NULL;
+    me->cond_prev = waiting_tail;
+    if (waiting_head == NULL)
+       waiting_head = me;
+    else
+       waiting_tail->cond_next = me;
+    waiting_tail = me;
+    me->cond_waiting = TRUE;
+
+    LeaveCriticalSection(&crit);
+
+    mutex->unlock();
+
+    unsigned long now_sec, now_nsec;
+
+    get_time_now(&now_sec, &now_nsec);
+
+    DWORD timeout;
+    if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec)))
+      timeout = 0;
+    else {
+      timeout = (abs_sec-now_sec) * 1000;
+
+      if( abs_nsec < now_nsec )  timeout -= (now_nsec-abs_nsec) / 1000000;
+      else                       timeout += (abs_nsec-now_nsec) / 1000000;
+    }
+
+    DWORD result = WaitForSingleObject(me->cond_semaphore, timeout);
+
+    if (result == WAIT_TIMEOUT) {
+       EnterCriticalSection(&crit);
+
+       if (me->cond_waiting) {
+           if (me->cond_prev != NULL)
+               me->cond_prev->cond_next = me->cond_next;
+           else
+               waiting_head = me->cond_next;
+           if (me->cond_next != NULL)
+               me->cond_next->cond_prev = me->cond_prev;
+           else
+               waiting_tail = me->cond_prev;
+           me->cond_waiting = FALSE;
+
+           LeaveCriticalSection(&crit);
+
+           mutex->lock();
+           return 0;
+       }
+
+       //
+       // We timed out but another thread still signalled us.  Wait for
+       // the semaphore (it _must_ have been signalled) to decrement it
+       // again.  Return that we were signalled, not that we timed out.
+       //
+
+       LeaveCriticalSection(&crit);
+
+       result = WaitForSingleObject(me->cond_semaphore, INFINITE);
+    }
+
+    if (result != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+
+    mutex->lock();
+    return 1;
+}
+
+
+void
+omni_condition::signal(void)
+{
+    EnterCriticalSection(&crit);
+
+    if (waiting_head != NULL) {
+       omni_thread* t = waiting_head;
+       waiting_head = t->cond_next;
+       if (waiting_head == NULL)
+           waiting_tail = NULL;
+       else
+           waiting_head->cond_prev = NULL;
+       t->cond_waiting = FALSE;
+
+       if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
+           int rc = GetLastError();
+           LeaveCriticalSection(&crit);
+           throw omni_thread_fatal(rc);
+       }
+    }
+
+    LeaveCriticalSection(&crit);
+}
+
+
+void
+omni_condition::broadcast(void)
+{
+    EnterCriticalSection(&crit);
+
+    while (waiting_head != NULL) {
+       omni_thread* t = waiting_head;
+       waiting_head = t->cond_next;
+       if (waiting_head == NULL)
+           waiting_tail = NULL;
+       else
+           waiting_head->cond_prev = NULL;
+       t->cond_waiting = FALSE;
+
+       if (!ReleaseSemaphore(t->cond_semaphore, 1, NULL)) {
+           int rc = GetLastError();
+           LeaveCriticalSection(&crit);
+           throw omni_thread_fatal(rc);
+       }
+    }
+
+    LeaveCriticalSection(&crit);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#define SEMAPHORE_MAX 0x7fffffff
+
+
+omni_semaphore::omni_semaphore(unsigned int initial, unsigned int max_count)
+{
+    if (max_count > SEMAPHORE_MAX)
+      max_count= SEMAPHORE_MAX;
+
+    nt_sem = CreateSemaphore(NULL, initial, max_count, NULL);
+
+    if (nt_sem == NULL) {
+      DB( cerr << "omni_semaphore::omni_semaphore: CreateSemaphore error "
+            << GetLastError() << endl );
+      throw omni_thread_fatal(GetLastError());
+    }
+}
+
+
+omni_semaphore::~omni_semaphore(void)
+{
+  if (!CloseHandle(nt_sem)) {
+    DB( cerr << "omni_semaphore::~omni_semaphore: CloseHandle error "
+            << GetLastError() << endl );
+    throw omni_thread_fatal(GetLastError());
+  }
+}
+
+
+void
+omni_semaphore::wait(void)
+{
+    if (WaitForSingleObject(nt_sem, INFINITE) != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+int
+omni_semaphore::trywait(void)
+{
+    switch (WaitForSingleObject(nt_sem, 0)) {
+
+    case WAIT_OBJECT_0:
+       return 1;
+    case WAIT_TIMEOUT:
+       return 0;
+    }
+
+    throw omni_thread_fatal(GetLastError());
+    return 0; /* keep msvc++ happy */
+}
+
+
+void
+omni_semaphore::post(void)
+{
+    if (!ReleaseSemaphore(nt_sem, 1, NULL)
+       && GetLastError() != ERROR_TOO_MANY_POSTS )     // MinGW fix--see ticket:95 in trac
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Static variables
+//
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+static DWORD self_tls_index;
+
+static unsigned int stack_size = 0;
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+  static int the_count = 0;
+  return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+    if (count()++ != 0)        // only do it once however many objects get created.
+       return;
+
+    DB(cerr << "omni_thread::init: NT implementation initialising\n");
+
+    self_tls_index = TlsAlloc();
+
+    if (self_tls_index == 0xffffffff)
+       throw omni_thread_fatal(GetLastError());
+
+    next_id_mutex = new omni_mutex;
+
+    //
+    // Create object for this (i.e. initial) thread.
+    //
+
+    omni_thread* t = new omni_thread;
+
+    t->_state = STATE_RUNNING;
+
+    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &t->handle,
+                        0, FALSE, DUPLICATE_SAME_ACCESS))
+       throw omni_thread_fatal(GetLastError());
+
+    t->nt_id = GetCurrentThreadId();
+
+    DB(cerr << "initial thread " << t->id() << " NT thread id " << t->nt_id
+       << endl);
+
+    if (!TlsSetValue(self_tls_index, (LPVOID)t))
+       throw omni_thread_fatal(GetLastError());
+
+    if (!SetThreadPriority(t->handle, nt_priority(PRIORITY_NORMAL)))
+       throw omni_thread_fatal(GetLastError());
+}
+
+omni_thread::init_t::~init_t(void)
+{
+    if (--count() != 0) return;
+
+    omni_thread* self = omni_thread::self();
+    if (!self) return;
+
+    TlsSetValue(self_tls_index, (LPVOID)0);
+    delete self;
+
+    delete next_id_mutex;
+
+    TlsFree(self_tls_index);
+}
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" 
+#ifndef __BCPLUSPLUS__
+unsigned __stdcall
+#else
+void _USERENTRY
+#endif
+omni_thread_wrapper(void* ptr)
+{
+    omni_thread* me = (omni_thread*)ptr;
+
+    DB(cerr << "omni_thread_wrapper: thread " << me->id()
+       << " started\n");
+
+    if (!TlsSetValue(self_tls_index, (LPVOID)me))
+       throw omni_thread_fatal(GetLastError());
+
+    //
+    // Now invoke the thread function with the given argument.
+    //
+
+    if (me->fn_void != NULL) {
+       (*me->fn_void)(me->thread_arg);
+       omni_thread::exit();
+    }
+
+    if (me->fn_ret != NULL) {
+       void* return_value = (*me->fn_ret)(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    if (me->detached) {
+       me->run(me->thread_arg);
+       omni_thread::exit();
+    } else {
+       void* return_value = me->run_undetached(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    // should never get here.
+#ifndef __BCPLUSPLUS__
+    return 0;
+#endif
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = fn;
+    fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 0);
+    fn_void = NULL;
+    fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = NULL;
+    fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+    _state = STATE_NEW;
+    _priority = pri;
+
+    next_id_mutex->lock();
+    _id = next_id++;
+    next_id_mutex->unlock();
+
+    thread_arg = arg;
+    detached = det;    // may be altered in start_undetached()
+
+    cond_semaphore = CreateSemaphore(NULL, 0, SEMAPHORE_MAX, NULL);
+
+    if (cond_semaphore == NULL)
+       throw omni_thread_fatal(GetLastError());
+
+    cond_next = cond_prev = NULL;
+    cond_waiting = FALSE;
+
+    handle = NULL;
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+    DB(cerr << "destructor called for thread " << id() << endl);
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+    if (handle && !CloseHandle(handle))
+       throw omni_thread_fatal(GetLastError());
+    if (cond_semaphore && !CloseHandle(cond_semaphore))
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_NEW)
+       throw omni_thread_invalid();
+
+#ifndef __BCPLUSPLUS__
+    // MSVC++ or compatiable
+    unsigned int t;
+    handle = (HANDLE)_beginthreadex(
+                        NULL,
+                       stack_size,
+                       omni_thread_wrapper,
+                       (LPVOID)this,
+                       CREATE_SUSPENDED, 
+                       &t);
+    nt_id = t;
+    if (handle == NULL)
+      throw omni_thread_fatal(GetLastError());
+#else
+    // Borland C++
+    handle = (HANDLE)_beginthreadNT(omni_thread_wrapper,
+                                   stack_size,
+                                   (void*)this,
+                                   NULL,
+                                   CREATE_SUSPENDED,
+                                   &nt_id);
+    if (handle == INVALID_HANDLE_VALUE)
+      throw omni_thread_fatal(errno);
+#endif
+
+    if (!SetThreadPriority(handle, nt_priority(_priority)))
+      throw omni_thread_fatal(GetLastError());
+
+    if (ResumeThread(handle) == 0xffffffff)
+       throw omni_thread_fatal(GetLastError());
+
+    _state = STATE_RUNNING;
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+    if ((fn_void != NULL) || (fn_ret != NULL))
+       throw omni_thread_invalid();
+
+    detached = 0;
+    start();
+}
+
+
+//
+// join - simply check error conditions & call WaitForSingleObject.
+//
+
+void
+omni_thread::join(void** status)
+{
+    mutex.lock();
+
+    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+       mutex.unlock();
+       throw omni_thread_invalid();
+    }
+
+    mutex.unlock();
+
+    if (this == self())
+       throw omni_thread_invalid();
+
+    if (detached)
+       throw omni_thread_invalid();
+
+    DB(cerr << "omni_thread::join: doing WaitForSingleObject\n");
+
+    if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0)
+       throw omni_thread_fatal(GetLastError());
+
+    DB(cerr << "omni_thread::join: WaitForSingleObject succeeded\n");
+
+    if (status)
+      *status = return_val;
+
+    delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_RUNNING)
+       throw omni_thread_invalid();
+
+    _priority = pri;
+
+    if (!SetThreadPriority(handle, nt_priority(pri)))
+       throw omni_thread_fatal(GetLastError());
+}
+
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+    t->start();
+    return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+    t->start();
+    return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+    omni_thread* me = self();
+
+    if (me)
+      {
+       me->mutex.lock();
+
+       me->_state = STATE_TERMINATED;
+
+       me->mutex.unlock();
+
+       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+          << me->detached << " return value " << return_value << endl);
+
+       if (me->detached) {
+         delete me;
+       } else {
+         me->return_val = return_value;
+       }
+      }
+    else
+      {
+       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+      }
+#ifndef __BCPLUSPLUS__
+    // MSVC++ or compatiable
+    //   _endthreadex() does not automatically closes the thread handle.
+    //   The omni_thread dtor closes the thread handle.
+    _endthreadex(0);
+#else
+    // Borland C++
+    //   _endthread() does not automatically closes the thread handle.
+    //   _endthreadex() is only available if __MFC_COMPAT__ is defined and
+    //   all it does is to call _endthread().
+    _endthread();
+#endif
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+    LPVOID me;
+
+    me = TlsGetValue(self_tls_index);
+
+    if (me == NULL) {
+      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+    }
+    return (omni_thread*)me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+    Sleep(0);
+}
+
+
+#define MAX_SLEEP_SECONDS (DWORD)4294966       // (2**32-2)/1000
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+    if (secs <= MAX_SLEEP_SECONDS) {
+       Sleep(secs * 1000 + nanosecs / 1000000);
+       return;
+    }
+
+    DWORD no_of_max_sleeps = secs / MAX_SLEEP_SECONDS;
+
+    for (DWORD i = 0; i < no_of_max_sleeps; i++)
+       Sleep(MAX_SLEEP_SECONDS * 1000);
+
+    Sleep((secs % MAX_SLEEP_SECONDS) * 1000 + nanosecs / 1000000);
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+    get_time_now(abs_sec, abs_nsec);
+    *abs_nsec += rel_nsec;
+    *abs_sec += rel_sec + *abs_nsec / 1000000000;
+    *abs_nsec = *abs_nsec % 1000000000;
+}
+
+
+int
+omni_thread::nt_priority(priority_t pri)
+{
+    switch (pri) {
+
+    case PRIORITY_LOW:
+       return THREAD_PRIORITY_LOWEST;
+
+    case PRIORITY_NORMAL:
+       return THREAD_PRIORITY_NORMAL;
+
+    case PRIORITY_HIGH:
+       return THREAD_PRIORITY_HIGHEST;
+    }
+
+    throw omni_thread_invalid();
+    return 0; /* keep msvc++ happy */
+}
+
+
+static void
+get_time_now(unsigned long* abs_sec, unsigned long* abs_nsec)
+{
+    static int days_in_preceding_months[12]
+       = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+    static int days_in_preceding_months_leap[12]
+       = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+    SYSTEMTIME st;
+
+    GetSystemTime(&st);
+    *abs_nsec = st.wMilliseconds * 1000000;
+
+    // this formula should work until 1st March 2100
+
+    DWORD days = ((st.wYear - 1970) * 365 + (st.wYear - 1969) / 4
+                 + ((st.wYear % 4)
+                    ? days_in_preceding_months[st.wMonth - 1]
+                    : days_in_preceding_months_leap[st.wMonth - 1])
+                 + st.wDay - 1);
+
+    *abs_sec = st.wSecond + 60 * (st.wMinute + 60 * (st.wHour + 24 * days));
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+
+    if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &handle,
+                        0, FALSE, DUPLICATE_SAME_ACCESS))
+      throw omni_thread_fatal(GetLastError());
+
+    nt_id = GetCurrentThreadId();
+
+    if (!TlsSetValue(self_tls_index, (LPVOID)this))
+      throw omni_thread_fatal(GetLastError());
+  }
+  inline ~omni_thread_dummy()
+  {
+    if (!TlsSetValue(self_tls_index, (LPVOID)0))
+      throw omni_thread_fatal(GetLastError());
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#if defined(__DMC__) && defined(_WINDLL)
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+  return TRUE;
+}
+#endif
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/omnithread/omnithread.h b/omnithread/omnithread.h
new file mode 100644 (file)
index 0000000..b6df34d
--- /dev/null
@@ -0,0 +1,622 @@
+// -*- Mode: C++; -*-
+//                             Package : omnithread
+// omnithread.h                        Created : 7/94 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+
+//
+// Interface to OMNI thread abstraction.
+//
+// This file declares classes for threads and synchronisation objects
+// (mutexes, condition variables and counting semaphores).
+//
+// Wherever a seemingly arbitrary choice has had to be made as to the interface
+// provided, the intention here has been to be as POSIX-like as possible.  This
+// is why there is no semaphore timed wait, for example.
+//
+
+#ifndef __omnithread_h_
+#define __omnithread_h_
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+class omni_mutex;
+class omni_condition;
+class omni_semaphore;
+class omni_thread;
+
+//
+// OMNI_THREAD_EXPOSE can be defined as public or protected to expose the
+// implementation class - this may be useful for debugging.  Hopefully this
+// won't change the underlying structure which the compiler generates so that
+// this can work without recompiling the library.
+//
+
+#ifndef OMNI_THREAD_EXPOSE
+#define OMNI_THREAD_EXPOSE private
+#endif
+
+//
+// Include implementation-specific header file.
+//
+// This must define 4 CPP macros of the form OMNI_x_IMPLEMENTATION for mutex,
+// condition variable, semaphore and thread.  Each should define any
+// implementation-specific members of the corresponding classes.
+//
+
+
+//
+// For now, we assume they've always got a Posix Threads implementation.
+// If not, it'll take some configure hacking to sort it out, along with
+// the relevant libraries to link with, etc.
+//
+
+#if !defined(OMNITHREAD_POSIX) && !defined(OMNITHREAD_NT) && defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(OMNITHREAD_POSIX)
+#include <ot_posix.h>
+
+#elif defined(OMNITHREAD_NT)
+#include <ot_nt.h>
+
+#ifdef _MSC_VER
+
+// Using MSVC++ to compile. If compiling library as a DLL,
+// define _OMNITHREAD_DLL. If compiling as a statuc library, define
+// _WINSTATIC
+// If compiling an application that is to be statically linked to omnithread,
+// define _WINSTATIC (if the application is  to be dynamically linked, 
+// there is no need to define any of these macros).
+
+#if defined (_OMNITHREAD_DLL) && defined(_WINSTATIC)
+#error "Both _OMNITHREAD_DLL and _WINSTATIC are defined."
+#elif defined(_OMNITHREAD_DLL)
+#define _OMNITHREAD_NTDLL_ __declspec(dllexport)
+#elif !defined(_WINSTATIC)
+#define _OMNITHREAD_NTDLL_ __declspec(dllimport)
+#elif defined(_WINSTATIC)
+#define _OMNITHREAD_NTDLL_
+#endif
+ // _OMNITHREAD_DLL && _WINSTATIC
+
+#else
+
+// Not using MSVC++ to compile
+#define _OMNITHREAD_NTDLL_
+
+#endif
+ // _MSC_VER
+#elif defined(__vxWorks__)
+#include <ot_VxThread.h>
+
+#elif defined(__sunos__)
+#if __OSVERSION__ != 5
+// XXX Workaround for SUN C++ compiler (seen on 4.2) Template.DB code
+//     regeneration bug. See omniORB2/CORBA_sysdep.h for details.
+#if !defined(__SUNPRO_CC) || __OSVERSION__ != '5'
+#error "Only SunOS 5.x or later is supported."
+#endif
+#endif
+#ifdef UseSolarisThreads
+#include <ot_solaris.h>
+#else
+#include <ot_posix.h>
+#endif
+
+#elif defined(__rtems__)
+#include <ot_posix.h>
+#include <sched.h>
+
+#elif defined(__macos__)
+#include <ot_posix.h>
+#include <sched.h>
+
+#else
+#error "No implementation header file"
+#endif
+
+
+#if !defined(__WIN32__)
+#define _OMNITHREAD_NTDLL_
+#endif
+
+#if (!defined(OMNI_MUTEX_IMPLEMENTATION)        || \
+     !defined(OMNI_MUTEX_LOCK_IMPLEMENTATION)   || \
+     !defined(OMNI_MUTEX_TRYLOCK_IMPLEMENTATION)|| \
+     !defined(OMNI_MUTEX_UNLOCK_IMPLEMENTATION) || \
+     !defined(OMNI_CONDITION_IMPLEMENTATION)    || \
+     !defined(OMNI_SEMAPHORE_IMPLEMENTATION)    || \
+     !defined(OMNI_THREAD_IMPLEMENTATION))
+#error "Implementation header file incomplete"
+#endif
+
+
+//
+// This exception is thrown in the event of a fatal error.
+//
+
+class _OMNITHREAD_NTDLL_ omni_thread_fatal {
+public:
+    int error;
+    omni_thread_fatal(int e = 0) : error(e) {}
+};
+
+
+//
+// This exception is thrown when an operation is invoked with invalid
+// arguments.
+//
+
+class _OMNITHREAD_NTDLL_ omni_thread_invalid {};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_mutex {
+
+public:
+    omni_mutex(void);
+    ~omni_mutex(void);
+
+    inline void lock(void)    { OMNI_MUTEX_LOCK_IMPLEMENTATION   }
+    inline void unlock(void)  { OMNI_MUTEX_UNLOCK_IMPLEMENTATION }
+    inline int trylock(void)  { return OMNI_MUTEX_TRYLOCK_IMPLEMENTATION }
+       // if mutex is unlocked, lock it and return 1 (true).
+       // If it's already locked then return 0 (false).
+
+    inline void acquire(void) { lock(); }
+    inline void release(void) { unlock(); }
+       // the names lock and unlock are preferred over acquire and release
+       // since we are attempting to be as POSIX-like as possible.
+
+    friend class omni_condition;
+
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_mutex(const omni_mutex&);
+    omni_mutex& operator=(const omni_mutex&);
+
+OMNI_THREAD_EXPOSE:
+    OMNI_MUTEX_IMPLEMENTATION
+};
+
+//
+// As an alternative to:
+// {
+//   mutex.lock();
+//   .....
+//   mutex.unlock();
+// }
+//
+// you can use a single instance of the omni_mutex_lock class:
+//
+// {
+//   omni_mutex_lock l(mutex);
+//   ....
+// }
+//
+// This has the advantage that mutex.unlock() will be called automatically
+// when an exception is thrown.
+//
+
+class _OMNITHREAD_NTDLL_ omni_mutex_lock {
+    omni_mutex& mutex;
+public:
+    omni_mutex_lock(omni_mutex& m) : mutex(m) { mutex.lock(); }
+    ~omni_mutex_lock(void) { mutex.unlock(); }
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_mutex_lock(const omni_mutex_lock&);
+    omni_mutex_lock& operator=(const omni_mutex_lock&);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_condition {
+
+    omni_mutex* mutex;
+
+public:
+    omni_condition(omni_mutex* m);
+       // constructor must be given a pointer to an existing mutex. The
+       // condition variable is then linked to the mutex, so that there is an
+       // implicit unlock and lock around wait() and timed_wait().
+
+    ~omni_condition(void);
+
+    void wait(void);
+       // wait for the condition variable to be signalled.  The mutex is
+       // implicitly released before waiting and locked again after waking up.
+       // If wait() is called by multiple threads, a signal may wake up more
+       // than one thread.  See POSIX threads documentation for details.
+
+    int timedwait(unsigned long secs, unsigned long nanosecs = 0);
+       // timedwait() is given an absolute time to wait until.  To wait for a
+       // relative time from now, use omni_thread::get_time. See POSIX threads
+       // documentation for why absolute times are better than relative.
+       // Returns 1 (true) if successfully signalled, 0 (false) if time
+       // expired.
+
+    void signal(void);
+       // if one or more threads have called wait(), signal wakes up at least
+       // one of them, possibly more.  See POSIX threads documentation for
+       // details.
+
+    void broadcast(void);
+       // broadcast is like signal but wakes all threads which have called
+       // wait().
+
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_condition(const omni_condition&);
+    omni_condition& operator=(const omni_condition&);
+
+OMNI_THREAD_EXPOSE:
+    OMNI_CONDITION_IMPLEMENTATION
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting (or binary) semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_semaphore {
+
+public:
+    // if max_count == 1, you've got a binary semaphore.
+    omni_semaphore(unsigned int initial = 1, unsigned int max_count = 0x7fffffff);
+    ~omni_semaphore(void);
+
+    void wait(void);
+       // if semaphore value is > 0 then decrement it and carry on. If it's
+       // already 0 then block.
+
+    int trywait(void);
+       // if semaphore value is > 0 then decrement it and return 1 (true).
+       // If it's already 0 then return 0 (false).
+
+    void post(void);
+       // if any threads are blocked in wait(), wake one of them up. Otherwise
+       // increment the value of the semaphore.
+
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_semaphore(const omni_semaphore&);
+    omni_semaphore& operator=(const omni_semaphore&);
+
+OMNI_THREAD_EXPOSE:
+    OMNI_SEMAPHORE_IMPLEMENTATION
+};
+
+//
+// A helper class for semaphores, similar to omni_mutex_lock above.
+//
+
+class _OMNITHREAD_NTDLL_ omni_semaphore_lock {
+    omni_semaphore& sem;
+public:
+    omni_semaphore_lock(omni_semaphore& s) : sem(s) { sem.wait(); }
+    ~omni_semaphore_lock(void) { sem.post(); }
+private:
+    // dummy copy constructor and operator= to prevent copying
+    omni_semaphore_lock(const omni_semaphore_lock&);
+    omni_semaphore_lock& operator=(const omni_semaphore_lock&);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+class _OMNITHREAD_NTDLL_ omni_thread {
+
+public:
+
+    enum priority_t {
+       PRIORITY_LOW,
+       PRIORITY_NORMAL,
+       PRIORITY_HIGH
+    };
+
+    enum state_t {
+       STATE_NEW,              // thread object exists but thread hasn't
+                               // started yet.
+       STATE_RUNNING,          // thread is running.
+       STATE_TERMINATED        // thread has terminated but storage has not
+                               // been reclaimed (i.e. waiting to be joined).
+    };
+
+    //
+    // Constructors set up the thread object but the thread won't start until
+    // start() is called. The create method can be used to construct and start
+    // a thread in a single call.
+    //
+
+    omni_thread(void (*fn)(void*), void* arg = NULL,
+               priority_t pri = PRIORITY_NORMAL);
+    omni_thread(void* (*fn)(void*), void* arg = NULL,
+               priority_t pri = PRIORITY_NORMAL);
+       // these constructors create a thread which will run the given function
+       // when start() is called.  The thread will be detached if given a
+       // function with void return type, undetached if given a function
+       // returning void*. If a thread is detached, storage for the thread is
+       // reclaimed automatically on termination. Only an undetached thread
+       // can be joined.
+
+    void start(void);
+       // start() causes a thread created with one of the constructors to
+       // start executing the appropriate function.
+
+protected:
+
+    omni_thread(void* arg = NULL, priority_t pri = PRIORITY_NORMAL);
+       // this constructor is used in a derived class.  The thread will
+       // execute the run() or run_undetached() member functions depending on
+       // whether start() or start_undetached() is called respectively.
+
+    void start_undetached(void);
+       // can be used with the above constructor in a derived class to cause
+       // the thread to be undetached.  In this case the thread executes the
+       // run_undetached member function.
+
+    virtual ~omni_thread(void);
+       // destructor cannot be called by user (except via a derived class).
+       // Use exit() or cancel() instead. This also means a thread object must
+       // be allocated with new - it cannot be statically or automatically
+       // allocated. The destructor of a class that inherits from omni_thread
+       // shouldn't be public either (otherwise the thread object can be
+       // destroyed while the underlying thread is still running).
+
+public:
+
+    void join(void**);
+       // join causes the calling thread to wait for another's completion,
+       // putting the return value in the variable of type void* whose address
+       // is given (unless passed a null pointer). Only undetached threads
+       // may be joined. Storage for the thread will be reclaimed.
+
+    void set_priority(priority_t);
+       // set the priority of the thread.
+
+    static omni_thread* create(void (*fn)(void*), void* arg = NULL,
+                              priority_t pri = PRIORITY_NORMAL);
+    static omni_thread* create(void* (*fn)(void*), void* arg = NULL,
+                              priority_t pri = PRIORITY_NORMAL);
+       // create spawns a new thread executing the given function with the
+       // given argument at the given priority. Returns a pointer to the
+       // thread object. It simply constructs a new thread object then calls
+       // start.
+
+    static void exit(void* return_value = NULL);
+       // causes the calling thread to terminate.
+
+    static omni_thread* self(void);
+       // returns the calling thread's omni_thread object.  If the
+       // calling thread is not the main thread and is not created
+       // using this library, returns 0. (But see create_dummy()
+       // below.)
+
+    static void yield(void);
+       // allows another thread to run.
+
+    static void sleep(unsigned long secs, unsigned long nanosecs = 0);
+       // sleeps for the given time.
+
+    static void get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                        unsigned long rel_sec = 0, unsigned long rel_nsec=0);
+       // calculates an absolute time in seconds and nanoseconds, suitable for
+       // use in timed_waits on condition variables, which is the current time
+       // plus the given relative offset.
+
+
+    static void stacksize(unsigned long sz);
+    static unsigned long stacksize();
+        // Use this value as the stack size when spawning a new thread.
+        // The default value (0) means that the thread library default is
+        // to be used.
+
+
+    // Per-thread data
+    //
+    // These functions allow you to attach additional data to an
+    // omni_thread. First allocate a key for yourself with
+    // allocate_key(). Then you can store any object whose class is
+    // derived from value_t. Any values still stored in the
+    // omni_thread when the thread exits are deleted.
+    //
+    // These functions are NOT thread safe, so you should be very
+    // careful about setting/getting data in a different thread to the
+    // current thread.
+
+    typedef unsigned int key_t;
+    static key_t allocate_key();
+
+    class value_t {
+    public:
+      virtual ~value_t() {}
+    };
+
+    value_t* set_value(key_t k, value_t* v);
+        // Sets a value associated with the given key. The key must
+        // have been allocated with allocate_key(). If a value has
+        // already been set with the specified key, the old value_t
+        // object is deleted and replaced. Returns the value which was
+        // set, or zero if the key is invalid.
+
+    value_t* get_value(key_t k);
+        // Returns the value associated with the key. If the key is
+        // invalid, or there is no value for the key, returns zero.
+
+    value_t* remove_value(key_t k);
+        // Removes the value associated with the key and returns it.
+        // If the key is invalid, or there is no value for the key,
+        // returns zero.
+
+
+    // Dummy omni_thread
+    //
+    // Sometimes, an application finds itself with threads created
+    // outside of omnithread which must interact with omnithread
+    // features such as the per-thread data. In this situation,
+    // omni_thread::self() would normally return 0. These functions
+    // allow the application to create a suitable dummy omni_thread
+    // object.
+
+    static omni_thread* create_dummy(void);
+        // creates a dummy omni_thread for the calling thread. Future
+        // calls to self() will return the dummy omni_thread. Throws
+        // omni_thread_invalid if this thread already has an
+        // associated omni_thread (real or dummy).
+
+    static void release_dummy();
+        // release the dummy omni_thread for this thread. This
+        // function MUST be called before the thread exits. Throws
+        // omni_thread_invalid if the calling thread does not have a
+        // dummy omni_thread.
+
+    // class ensure_self should be created on the stack. If created in
+    // a thread without an associated omni_thread, it creates a dummy
+    // thread which is released when the ensure_self object is deleted.
+
+    class ensure_self {
+    public:
+      inline ensure_self() : _dummy(0)
+      {
+       _self = omni_thread::self();
+       if (!_self) {
+         _dummy = 1;
+         _self  = omni_thread::create_dummy();
+       }
+      }
+      inline ~ensure_self()
+      {
+       if (_dummy)
+         omni_thread::release_dummy();
+      }
+      inline omni_thread* self() { return _self; }
+    private:
+      omni_thread* _self;
+      int          _dummy;
+    };
+
+
+private:
+
+    virtual void run(void* /*arg*/) {}
+    virtual void* run_undetached(void* /*arg*/) { return NULL; }
+       // can be overridden in a derived class.  When constructed using the
+       // the constructor omni_thread(void*, priority_t), these functions are
+       // called by start() and start_undetached() respectively.
+
+    void common_constructor(void* arg, priority_t pri, int det);
+       // implements the common parts of the constructors.
+
+    omni_mutex mutex;
+       // used to protect any members which can change after construction,
+       // i.e. the following 2 members.
+
+    state_t _state;
+    priority_t _priority;
+
+    static omni_mutex* next_id_mutex;
+    static int next_id;
+    int _id;
+
+    void (*fn_void)(void*);
+    void* (*fn_ret)(void*);
+    void* thread_arg;
+    int detached;
+    int _dummy;
+    value_t**     _values;
+    unsigned long _value_alloc;
+
+    omni_thread(const omni_thread&);
+    omni_thread& operator=(const omni_thread&);
+    // Not implemented
+
+public:
+
+    priority_t priority(void) {
+
+       // return this thread's priority.
+
+       omni_mutex_lock l(mutex);
+       return _priority;
+    }
+
+    state_t state(void) {
+
+       // return thread state (invalid, new, running or terminated).
+
+       omni_mutex_lock l(mutex);
+       return _state;
+    }
+
+    int id(void) { return _id; }
+       // return unique thread id within the current process.
+
+
+    // This class plus the instance of it declared below allows us to execute
+    // some initialisation code before main() is called.
+
+    class _OMNITHREAD_NTDLL_ init_t {
+    public:
+       init_t(void);
+        ~init_t(void);
+    };
+
+    friend class init_t;
+    friend class omni_thread_dummy;
+
+OMNI_THREAD_EXPOSE:
+    OMNI_THREAD_IMPLEMENTATION
+};
+
+#ifndef __rtems__
+static omni_thread::init_t omni_thread_init;
+#else
+// RTEMS calls global Ctor/Dtor in a context that is not
+// a posix thread. Calls to functions to pthread_self() in
+// that context returns NULL. 
+// So, for RTEMS we will make the thread initialization at the
+// beginning of the Init task that has a posix context.
+#endif
+
+#endif
diff --git a/omnithread/ot_VxThread.h b/omnithread/ot_VxThread.h
new file mode 100644 (file)
index 0000000..e96c036
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef __VXTHREAD_H__
+#define __VXTHREAD_H__
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Project:     omniORB
+%% Filename:    $Filename$
+%% Author:      Guillaume/Bill ARRECKX
+%%              Copyright Wavetek Wandel & Goltermann, Plymouth.
+%% Description: OMNI thread implementation classes for VxWorks threads
+%% Notes:
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% $Log$
+%% Revision 1.1  2004/04/10 18:00:52  eb
+%% Initial revision
+%%
+%% Revision 1.1.1.1  2004/03/01 00:20:27  eb
+%% initial checkin
+%%
+%% Revision 1.1  2003/05/25 05:29:04  eb
+%% see ChangeLog
+%%
+%% Revision 1.1.2.1  2003/02/17 02:03:07  dgrisby
+%% vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
+%%
+%% Revision 1.1.1.1  2002/11/19 14:55:21  sokcevti
+%% OmniOrb4.0.0 VxWorks port
+%%
+%% Revision 1.2  2002/06/14 12:45:50  engeln
+%% unnecessary members in condition removed.
+%% ---
+%%
+%% Revision 1.1.1.1  2002/04/02 10:08:49  sokcevti
+%% omniORB4 initial realease
+%%
+%% Revision 1.1  2001/03/23 16:50:23  hartmut
+%% Initial Version 2.8
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+*/
+
+
+///////////////////////////////////////////////////////////////////////////
+// Includes
+///////////////////////////////////////////////////////////////////////////
+#include <vxWorks.h>
+#include <semLib.h>
+#include <taskLib.h>
+
+
+///////////////////////////////////////////////////////////////////////////
+// Externs prototypes
+///////////////////////////////////////////////////////////////////////////
+extern "C" void omni_thread_wrapper(void* ptr);
+
+
+///////////////////////////////////////////////////////////////////////////
+// Exported macros
+// Note: These are added as private members in each class implementation.
+///////////////////////////////////////////////////////////////////////////
+#define OMNI_MUTEX_IMPLEMENTATION \
+   SEM_ID mutexID;     \
+   bool m_bConstructed;
+
+#define OMNI_CONDITION_IMPLEMENTATION \
+   long waiters_; \
+   SEM_ID waiters_lock_; \
+   SEM_ID sema_;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION \
+   SEM_ID semID;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
+       if(semTake(mutexID, WAIT_FOREVER) != OK)        \
+       {       \
+               throw omni_thread_fatal(errno); \
+       }
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
+       if(semGive(mutexID) != OK)      \
+       {       \
+               throw omni_thread_fatal(errno); \
+       }
+
+#define OMNI_THREAD_IMPLEMENTATION \
+   friend void omni_thread_wrapper(void* ptr); \
+   static int vxworks_priority(priority_t); \
+   omni_condition *running_cond; \
+   void* return_val; \
+   int tid; \
+   public: \
+   static void attach(void); \
+   static void detach(void); \
+   static void show(void);
+
+
+///////////////////////////////////////////////////////////////////////////
+// Porting macros
+///////////////////////////////////////////////////////////////////////////
+// This is a wrapper function for the 'main' function which does not exists
+//  as such in VxWorks. The wrapper creates a launch function instead,
+//  which spawns the application wrapped in a omni_thread.
+// Argc will always be null.
+///////////////////////////////////////////////////////////////////////////
+#define main( discarded_argc, discarded_argv ) \
+        omni_discard_retval() \
+          { \
+          throw; \
+          } \
+        int omni_main( int argc, char **argv ); \
+        void launch( ) \
+          { \
+          omni_thread* th = new omni_thread( (void(*)(void*))omni_main );\
+          th->start();\
+          }\
+        int omni_main( int argc, char **argv )
+
+
+#endif // ndef __VXTHREAD_H__
diff --git a/omnithread/ot_mach.h b/omnithread/ot_mach.h
new file mode 100644 (file)
index 0000000..7636192
--- /dev/null
@@ -0,0 +1,51 @@
+//                             Package : omnithread
+// omnithread/posix.h          Created : 7/97 lars immisch lars@ibp.de
+//
+//    Copyright (C) 1994,1995,1996, 1997 Immisch, becker & Partner
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+//
+// OMNI thread implementation classes for posix threads
+//
+
+#ifndef __omnithread_mach_h_
+#define __omnithread_mach_h_
+
+#include <mach/cthreads.h>
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    struct mutex mach_mutex;
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    struct condition mach_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    omni_mutex m;                                      \
+    omni_condition c;                                  \
+    int value;
+
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    cthread_t mach_thread;                             \
+    static int mach_priority(priority_t);              \
+    friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/omnithread/ot_nt.h b/omnithread/ot_nt.h
new file mode 100644 (file)
index 0000000..551ccf2
--- /dev/null
@@ -0,0 +1,85 @@
+//                             Package : omnithread
+// omnithread/nt.h             Created : 6/95 tjr
+//
+//    Copyright (C) 1995, 1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+//
+// OMNI thread implementation classes for NT threads.
+//
+
+#ifndef __omnithread_nt_h_
+#define __omnithread_nt_h_
+
+#ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#  define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#  undef WIN32_LEAN_AND_MEAN
+#  undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#endif
+
+
+#ifndef __BCPLUSPLUS__
+#define OMNI_THREAD_WRAPPER \
+    unsigned __stdcall omni_thread_wrapper(LPVOID ptr);
+#else
+#define OMNI_THREAD_WRAPPER \
+    void _USERENTRY omni_thread_wrapper(void *ptr);
+#endif
+
+extern "C" OMNI_THREAD_WRAPPER;
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    CRITICAL_SECTION crit;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
+    EnterCriticalSection(&crit);
+
+#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION               \
+    TryEnterCriticalSection(&crit);
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
+    LeaveCriticalSection(&crit);
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    CRITICAL_SECTION crit;                             \
+    omni_thread* waiting_head;                         \
+    omni_thread* waiting_tail;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    HANDLE nt_sem;
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    HANDLE handle;                                     \
+    DWORD nt_id;                                       \
+    void* return_val;                                  \
+    HANDLE cond_semaphore;                             \
+    omni_thread* cond_next;                            \
+    omni_thread* cond_prev;                            \
+    BOOL cond_waiting;                                 \
+    static int nt_priority(priority_t);                        \
+    friend class omni_condition;                       \
+    friend OMNI_THREAD_WRAPPER;
+
+#endif
diff --git a/omnithread/ot_posix.h b/omnithread/ot_posix.h
new file mode 100644 (file)
index 0000000..666ccc0
--- /dev/null
@@ -0,0 +1,81 @@
+//                             Package : omnithread
+// omnithread/posix.h          Created : 7/94 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+//
+// OMNI thread implementation classes for posix threads
+//
+
+#ifndef __omnithread_posix_h_
+#define __omnithread_posix_h_
+
+#if defined(__alpha__) && defined(__osf1__) || defined(__hpux__)
+// stop unnecessary definitions of TRY, etc on OSF
+#ifndef EXC_HANDLING
+#define EXC_HANDLING
+#endif
+#endif
+
+#ifndef __POSIX_NT__
+#  include <pthread.h>
+#else
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#    define OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include "pthread_nt.h"
+#  ifdef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#    undef WIN32_LEAN_AND_MEAN
+#    undef OMNI_DEFINED_WIN32_LEAN_AND_MEAN
+#  endif
+#endif
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    pthread_mutex_t posix_mutex;
+
+#define OMNI_MUTEX_LOCK_IMPLEMENTATION                  \
+    pthread_mutex_lock(&posix_mutex);
+
+#define OMNI_MUTEX_TRYLOCK_IMPLEMENTATION               \
+    (pthread_mutex_trylock(&posix_mutex)==0);
+
+#define OMNI_MUTEX_UNLOCK_IMPLEMENTATION                \
+    pthread_mutex_unlock(&posix_mutex);
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    pthread_cond_t posix_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    omni_mutex m;                                      \
+    omni_condition c;                                  \
+    int value;                                         \
+    int max_count;
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    pthread_t posix_thread;                            \
+    static int posix_priority(priority_t);             \
+    friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/omnithread/ot_pthread_nt.h b/omnithread/ot_pthread_nt.h
new file mode 100644 (file)
index 0000000..dbf4356
--- /dev/null
@@ -0,0 +1,186 @@
+/*                             Package : omnithread
+   omnithread/pthread_nt.h     Created : Steven Brenneis <brennes1@rjrt.com>
+  
+      Copyright (C) 1998 Steven Brennes
+  
+      This file is part of the omnithread library
+  
+      The omnithread 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., 51 Franklin Street, Boston, MA  
+      02110-1301, USA
+  
+      Posix Threads implementation for Windows NT, version 4.0
+*/
+
+#ifndef PTHREAD_NT_H_INCLUDED
+#define PTHREAD_NT_H_INCLUDED
+
+#include <errno.h>
+
+#ifndef ETIMEDOUT
+//     May have to be changed if NT starts supporting more errno values
+#define ETIMEDOUT 60
+#endif
+
+#undef PthreadDraftVersion
+#define PthreadDraftVersion 10
+
+#define NoNanoSleep
+
+#define PthreadSupportThreadPriority
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _TIMERS_T_
+#define _TIMERS_T_
+       typedef struct timespec {
+               unsigned long tv_sec;
+               long tv_nsec;
+       } timespec_t;
+#endif
+
+typedef char* __pthreadLongString_t;
+typedef void* __pthreadLongAddr_t;
+typedef __pthreadLongAddr_t* __pthreadLongAddr_p;
+typedef long __pthreadLongInt_t;
+typedef unsigned long __pthreadLongUint_t;
+typedef __pthreadLongAddr_p __pthreadTsd_t;
+
+typedef struct __pthread_mutex_t {
+       unsigned int lock;           /* LOCK, SLOW, TYPE, RECURSIVE  */
+       unsigned int valid;          /* Validation info */
+       __pthreadLongString_t name;   /* Name of mutex */
+       unsigned int arg;            /* printf argument for  name */
+       unsigned int depth;          /* Recursive lock depth */
+       unsigned long sequence;       /* Mutex sequence number */
+       unsigned long owner;          /* Current owner (if known */
+       __pthreadLongAddr_t block;          /* Pointer to blocking struct */
+} pthread_mutex_t;
+
+typedef struct __pthread_mutexattr_t {
+       long valid;
+       __pthreadLongUint_t reserved[15];
+} pthread_mutexattr_t;
+
+typedef struct __pthread_cond_t {
+       unsigned int state;          /* EVENT, SLOW, REFCNT */
+       unsigned int valid;          /* Validation info */
+       __pthreadLongString_t name;   /* Name of condition variable */
+       unsigned int arg;            /* printf argument for name */
+       unsigned long sequence;       /* Condition variable seq # */
+       __pthreadLongAddr_t block;          /* Pointer to blocking struct */
+} pthread_cond_t ;
+
+typedef struct __pthread_condattr_t {
+       long valid;
+       __pthreadLongUint_t reserved[13];
+} pthread_condattr_t ;
+
+typedef struct __pthread_transp_t {
+       __pthreadLongAddr_t reserved1;      /* Reserved to posix_nt */
+       __pthreadLongAddr_t reserved2;      /* Reserved to posix_nt */
+       unsigned short size;           /* Size of data structure */
+       unsigned char reserved3[2];   /* Reserved to posix_nt */
+       __pthreadLongAddr_t reserved4;   /* Reserved to posix_nt */
+       __pthreadLongUint_t sequence;       /* Thread sequence number */
+       __pthreadLongUint_t reserved5[2];   /* Reserved to posix_nt */
+       __pthreadLongAddr_t per_kt_area;    /* Pointer to kernel context */
+       __pthreadLongAddr_t stack_base;     /* Current stack base */
+       __pthreadLongAddr_t stack_reserve; /* Current stack reserve zone */
+       __pthreadLongAddr_t stack_yellow;   /* Current stack yellow zone */
+       __pthreadLongAddr_t stack_guard;    /* Current stack guard zone */
+       __pthreadLongUint_t stack_size;     /* Size of stack */
+       __pthreadTsd_t tsd_values;     /* TSD array (indexed by key) */
+       unsigned long tsd_count;      /* Number of TSD cells */
+       __pthreadLongAddr_t reserved6;      /* Reserved to posix_nt */
+       __pthreadLongAddr_t reserved7;      /* Reserved to posix_nt */
+       unsigned int thread_flags;   /* Dynamic external state */
+} pthread_transp_t, *pthread_transp_p;
+
+typedef pthread_transp_p pthread_t;
+
+typedef struct __pthread_attr_t {
+       long valid;
+       __pthreadLongString_t name;
+       __pthreadLongUint_t arg;
+       __pthreadLongUint_t reserved[19];
+} pthread_attr_t ;
+
+typedef unsigned int pthread_key_t;
+
+typedef struct sched_param {
+       int sched_priority;
+} sched_param_t;
+        
+/*     Function Prototypes */
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+                                                               void *(*start_routine)(void*), void *arg);
+int pthread_detach(pthread_t thread);
+int pthread_join(pthread_t thread, void **value_ptr);
+void pthread_exit(void *value_ptr);
+int pthread_attr_init(pthread_attr_t *attr);
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+int pthread_attr_getstacksize(const pthread_attr_t *attr, 
+                                                                                       size_t *stacksize);
+int pthread_cond_init(pthread_cond_t *cond,
+                                                               const pthread_condattr_t *attr);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond, 
+                                                                                       pthread_mutex_t *mutex,
+                                                                                       const struct timespec *abstime);
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
+int pthread_key_delete(pthread_key_t key);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_init(pthread_mutex_t *mutex, 
+                                                                       const pthread_mutexattr_t *attr);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+pthread_t pthread_self();
+int pthread_setspecific(pthread_key_t key, const void *value);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_getschedparam(pthread_t thread, int *policy,
+                                                                                       struct sched_param *param);
+int pthread_setschedparam(pthread_t thread, int policy,
+                                                                               const struct sched_param *param);
+int pthread_attr_setschedparam(pthread_attr_t *attr, 
+                                                                                               const struct sched_param *param);
+int pthread_attr_getschedparam(const pthread_attr_t *attr, 
+                                                                                               struct sched_param *param);
+
+int pthread_delay_np(const struct timespec *interval);
+int pthread_get_expiration_np(const struct timespec *delta,
+                                                                                               struct timespec *abstime);
+
+# define SCHED_FIFO 1
+# define SCHED_RR 2
+# define SCHED_OTHER 3
+
+int sched_yield();
+int sched_get_priority_max(int policy);
+int sched_get_priority_min(int policy);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //      PTHREAD_NT_H_INCLUDED
diff --git a/omnithread/ot_solaris.h b/omnithread/ot_solaris.h
new file mode 100644 (file)
index 0000000..f4fea0b
--- /dev/null
@@ -0,0 +1,47 @@
+//                             Package : omnithread
+// omnithread/solaris.h                Created : 7/94 tjr
+//
+//    Copyright (C) 1994,1995,1996, 1997 Olivetti & Oracle Research Laboratory
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+// OMNI thread implementation classes for solaris threads.
+//
+
+#ifndef __omnithread_solaris_h_
+#define __omnithread_solaris_h_
+
+#include <thread.h>
+
+extern "C" void* omni_thread_wrapper(void* ptr);
+
+#define OMNI_MUTEX_IMPLEMENTATION                      \
+    mutex_t sol_mutex;
+
+#define OMNI_CONDITION_IMPLEMENTATION                  \
+    cond_t sol_cond;
+
+#define OMNI_SEMAPHORE_IMPLEMENTATION                  \
+    sema_t sol_sem;
+
+#define OMNI_THREAD_IMPLEMENTATION                     \
+    thread_t sol_thread;                               \
+    static int sol_priority(priority_t);               \
+    friend void* omni_thread_wrapper(void* ptr);
+
+#endif
diff --git a/omnithread/posix.cc b/omnithread/posix.cc
new file mode 100644 (file)
index 0000000..b82e86d
--- /dev/null
@@ -0,0 +1,972 @@
+//                             Package : omnithread
+// omnithread/posix.cc         Created : 7/94 tjr
+//
+//    Copyright (C) 2006 Free Software Foundation, Inc.
+//    Copyright (C) 1994-1999 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+
+//
+// Implementation of OMNI thread abstraction for posix threads
+//
+// The source below tests for the definition of the macros:
+//     PthreadDraftVersion
+//     PthreadSupportThreadPriority
+//     NoNanoSleep
+//     NeedPthreadInit
+//
+// As different draft versions of the pthread standard P1003.4a/P1003.1c
+// define slightly different APIs, the macro 'PthreadDraftVersion'
+// identifies the draft version supported by this particular platform.
+//
+// Some unix variants do not support thread priority unless a real-time
+// kernel option is installed. The macro 'PthreadSupportThreadPriority',
+// if defined, enables the use of thread priority. If it is not defined,
+// setting or changing thread priority will be silently ignored.
+//
+// nanosleep() is defined in Posix P1003.4 since Draft 9 (?).
+// Not all platforms support this standard. The macro 'NoNanoSleep'
+// identifies platform that don't.
+//
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <omnithread.h>
+
+#ifdef HAVE_NANOSLEEP
+#undef NoNanoSleep
+#else
+#define NoNanoSleep
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+// typedef of struct timeval and gettimeofday();
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#if defined(__linux__) && defined(_MIT_POSIX_THREADS)
+#include <pthread/mit/sys/timers.h>
+#endif
+
+#if defined(__irix__) && defined(PthreadSupportThreadPriority)
+#if _POSIX_THREAD_PRIORITY_SCHEDULING
+#include <sched.h>
+#endif
+#endif
+
+#define DB(x) // x
+//#include <iostream.h> or #include <iostream> if DB is on.
+
+#if (PthreadDraftVersion <= 6)
+#define ERRNO(x) (((x) != 0) ? (errno) : 0)
+#ifdef __VMS
+// pthread_setprio returns old priority on success (draft version 4:
+// OpenVms version < 7)
+#define THROW_ERRORS(x) { if ((x) == -1) throw omni_thread_fatal(errno); }
+#else
+#define THROW_ERRORS(x) { if ((x) != 0) throw omni_thread_fatal(errno); }
+#endif
+#else
+#define ERRNO(x) (x)
+#define THROW_ERRORS(x) { int rc = (x); \
+                         if (rc != 0) throw omni_thread_fatal(rc); }
+#endif
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_mutex_init(&posix_mutex, pthread_mutexattr_default));
+#else
+    THROW_ERRORS(pthread_mutex_init(&posix_mutex, 0));
+#endif
+}
+
+omni_mutex::~omni_mutex(void)
+{
+    THROW_ERRORS(pthread_mutex_destroy(&posix_mutex));
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_cond_init(&posix_cond, pthread_condattr_default));
+#else
+    THROW_ERRORS(pthread_cond_init(&posix_cond, 0));
+#endif
+}
+
+omni_condition::~omni_condition(void)
+{
+    THROW_ERRORS(pthread_cond_destroy(&posix_cond));
+}
+
+void
+omni_condition::wait(void)
+{
+    THROW_ERRORS(pthread_cond_wait(&posix_cond, &mutex->posix_mutex));
+}
+
+int
+omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+
+again:
+    int rc = ERRNO(pthread_cond_timedwait(&posix_cond,
+                                         &mutex->posix_mutex, &rqts));
+    if (rc == 0)
+       return 1;
+
+#if (PthreadDraftVersion <= 6)
+    if (rc == EAGAIN)
+       return 0;
+#endif
+
+    // Some versions of unix produces this errno when the wait was
+    // interrupted by a unix signal or fork.
+    // Some versions of the glibc 2.0.x produces this errno when the 
+    // program is debugged under gdb. Straightly speaking this is non-posix
+    // compliant. We catch this here to make debugging possible.
+    if (rc == EINTR)
+      goto again;
+
+    if (rc == ETIMEDOUT)
+       return 0;
+
+    throw omni_thread_fatal(rc);
+#ifdef _MSC_VER
+    return 0;
+#endif
+}
+
+void
+omni_condition::signal(void)
+{
+    THROW_ERRORS(pthread_cond_signal(&posix_cond));
+}
+
+void
+omni_condition::broadcast(void)
+{
+    THROW_ERRORS(pthread_cond_broadcast(&posix_cond));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting (or binary) semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial, unsigned int _max_count) : c(&m)
+{
+    value = initial;
+    max_count = _max_count;
+    if (value < 0 || max_count < 1)
+      throw omni_thread_fatal(0);
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+}
+
+void
+omni_semaphore::wait(void)
+{
+    omni_mutex_lock l(m);
+
+    while (value == 0)
+       c.wait();
+
+    value--;
+}
+
+int
+omni_semaphore::trywait(void)
+{
+    omni_mutex_lock l(m);
+
+    if (value == 0)
+       return 0;
+
+    value--;
+    return 1;
+}
+
+void
+omni_semaphore::post(void)
+{
+    {
+        omni_mutex_lock l(m);
+       if (value < max_count)
+         value++;
+    }
+
+    c.signal();
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// static variables
+//
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static pthread_key_t self_key;
+
+#ifdef PthreadSupportThreadPriority
+static int lowest_priority;
+static int normal_priority;
+static int highest_priority;
+#endif
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
+// omniORB requires a larger stack size than the default (21120) on OSF/1
+static size_t stack_size = 32768;
+#elif defined(__rtems__)
+static size_t stack_size = ThreadStackSize;
+#elif defined(__aix__)
+static size_t stack_size = 262144;
+#else
+static size_t stack_size = 0;
+#endif
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+  static int the_count = 0;
+  return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+    if (count()++ != 0)        // only do it once however many objects get created.
+       return;
+
+    DB(cerr << "omni_thread::init: posix 1003.4a/1003.1c (draft "
+       << PthreadDraftVersion << ") implementation initialising\n");
+
+#ifdef NeedPthreadInit
+
+    pthread_init();
+
+#endif
+
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_keycreate(&self_key, NULL));
+#else
+    THROW_ERRORS(pthread_key_create(&self_key, NULL));
+#endif
+
+#ifdef PthreadSupportThreadPriority
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__VMS)
+
+    lowest_priority = PRI_OTHER_MIN;
+    highest_priority = PRI_OTHER_MAX;
+
+#elif defined(__hpux__)
+
+    lowest_priority = PRI_OTHER_MIN;
+    highest_priority = PRI_OTHER_MAX;
+
+#elif defined(__sunos__) && (__OSVERSION__ == 5)
+
+    // a bug in pthread_attr_setschedparam means lowest priority is 1 not 0
+
+    lowest_priority  = 1;
+    highest_priority = 3;
+
+#else
+
+    lowest_priority = sched_get_priority_min(SCHED_FIFO);
+    highest_priority = sched_get_priority_max(SCHED_FIFO);
+
+#endif
+
+    switch (highest_priority - lowest_priority) {
+
+    case 0:
+    case 1:
+       normal_priority = lowest_priority;
+       break;
+
+    default:
+       normal_priority = lowest_priority + 1;
+       break;
+    }
+
+#endif   /* PthreadSupportThreadPriority */
+
+    next_id_mutex = new omni_mutex;
+
+    //
+    // Create object for this (i.e. initial) thread.
+    //
+
+    omni_thread* t = new omni_thread;
+
+    t->_state = STATE_RUNNING;
+
+    t->posix_thread = pthread_self ();
+
+    DB(cerr << "initial thread " << t->id() << endl);
+
+    THROW_ERRORS(pthread_setspecific(self_key, (void*)t));
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion == 4)
+
+    THROW_ERRORS(pthread_setprio(t->posix_thread,
+                                posix_priority(PRIORITY_NORMAL)));
+
+#elif (PthreadDraftVersion == 6)
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+
+    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(PRIORITY_NORMAL)));
+
+    THROW_ERRORS(pthread_setschedattr(t->posix_thread, attr));
+
+#else
+
+    struct sched_param sparam;
+
+    sparam.sched_priority = posix_priority(PRIORITY_NORMAL);
+
+    THROW_ERRORS(pthread_setschedparam(t->posix_thread, SCHED_OTHER, &sparam));
+
+#endif   /* PthreadDraftVersion */
+
+#endif   /* PthreadSupportThreadPriority */
+}
+
+omni_thread::init_t::~init_t(void)
+{
+    if (--count() != 0) return;
+
+    omni_thread* self = omni_thread::self();
+    if (!self) return;
+
+    pthread_setspecific(self_key, 0);
+    delete self;
+
+    delete next_id_mutex;
+}
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void* 
+omni_thread_wrapper(void* ptr)
+{
+    omni_thread* me = (omni_thread*)ptr;
+
+    DB(cerr << "omni_thread_wrapper: thread " << me->id()
+       << " started\n");
+
+    THROW_ERRORS(pthread_setspecific(self_key, me));
+
+    //
+    // Now invoke the thread function with the given argument.
+    //
+
+    if (me->fn_void != NULL) {
+       (*me->fn_void)(me->thread_arg);
+       omni_thread::exit();
+    }
+
+    if (me->fn_ret != NULL) {
+       void* return_value = (*me->fn_ret)(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    if (me->detached) {
+       me->run(me->thread_arg);
+       omni_thread::exit();
+    } else {
+       void* return_value = me->run_undetached(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    // should never get here.
+
+    return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = fn;
+    fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 0);
+    fn_void = NULL;
+    fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = NULL;
+    fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+    _state = STATE_NEW;
+    _priority = pri;
+
+    next_id_mutex->lock();
+    _id = next_id++;
+    next_id_mutex->unlock();
+
+    thread_arg = arg;
+    detached = det;    // may be altered in start_undetached()
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+    // posix_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+    DB(cerr << "destructor called for thread " << id() << endl);
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_NEW)
+       throw omni_thread_invalid();
+
+    pthread_attr_t attr;
+
+#if (PthreadDraftVersion == 4)
+    pthread_attr_create(&attr);
+#else
+    pthread_attr_init(&attr);
+#endif
+
+#if (PthreadDraftVersion == 8)
+    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_UNDETACHED);
+#endif
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion <= 6)
+
+    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(_priority)));
+
+#else
+
+    struct sched_param sparam;
+
+    sparam.sched_priority = posix_priority(_priority);
+
+    THROW_ERRORS(pthread_attr_setschedparam(&attr, &sparam));
+
+#endif /* PthreadDraftVersion */
+
+#endif /* PthreadSupportThreadPriority */
+
+#if !defined(__linux__)
+    if (stack_size) {
+      THROW_ERRORS(pthread_attr_setstacksize(&attr, stack_size));
+    }
+#endif
+
+
+#if (PthreadDraftVersion == 4)
+    THROW_ERRORS(pthread_create(&posix_thread, attr, omni_thread_wrapper,
+                               (void*)this));
+    pthread_attr_delete(&attr);
+#else
+    THROW_ERRORS(pthread_create(&posix_thread, &attr, omni_thread_wrapper,
+                               (void*)this));
+    pthread_attr_destroy(&attr);
+#endif
+
+    _state = STATE_RUNNING;
+
+    if (detached) {
+
+#if (PthreadDraftVersion <= 6)
+       THROW_ERRORS(pthread_detach(&posix_thread));
+#else
+       THROW_ERRORS(pthread_detach(posix_thread));
+#endif
+    }
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+    if ((fn_void != NULL) || (fn_ret != NULL))
+       throw omni_thread_invalid();
+
+    detached = 0;
+    start();
+}
+
+
+//
+// join - simply check error conditions & call pthread_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+    mutex.lock();
+
+    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+       mutex.unlock();
+       throw omni_thread_invalid();
+    }
+
+    mutex.unlock();
+
+    if (this == self())
+       throw omni_thread_invalid();
+
+    if (detached)
+       throw omni_thread_invalid();
+
+    DB(cerr << "omni_thread::join: doing pthread_join\n");
+
+    THROW_ERRORS(pthread_join(posix_thread, status));
+
+    DB(cerr << "omni_thread::join: pthread_join succeeded\n");
+
+#if (PthreadDraftVersion == 4)
+    // With draft 4 pthreads implementations (HPUX 10.x and
+    // Digital Unix 3.2), have to detach the thread after 
+    // join. If not, the storage for the thread will not be
+    // be reclaimed.
+    THROW_ERRORS(pthread_detach(&posix_thread));
+#endif
+
+    delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_RUNNING)
+       throw omni_thread_invalid();
+
+    _priority = pri;
+
+#ifdef PthreadSupportThreadPriority
+
+#if (PthreadDraftVersion == 4)
+
+    THROW_ERRORS(pthread_setprio(posix_thread, posix_priority(pri)));
+
+#elif (PthreadDraftVersion == 6)
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+
+    THROW_ERRORS(pthread_attr_setprio(&attr, posix_priority(pri)));
+
+    THROW_ERRORS(pthread_setschedattr(posix_thread, attr));
+
+#else
+
+    struct sched_param sparam;
+
+    sparam.sched_priority = posix_priority(pri);
+
+    THROW_ERRORS(pthread_setschedparam(posix_thread, SCHED_OTHER, &sparam));
+
+#endif   /* PthreadDraftVersion */
+
+#endif   /* PthreadSupportThreadPriority */
+}
+
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+    omni_thread* me = self();
+
+    if (me)
+      {
+       me->mutex.lock();
+
+       me->_state = STATE_TERMINATED;
+
+       me->mutex.unlock();
+
+       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+          << me->detached << " return value " << return_value << endl);
+
+       if (me->detached)
+         delete me;
+      }
+    else
+      {
+       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+      }
+
+    pthread_exit(return_value);
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+    omni_thread* me;
+
+#if (PthreadDraftVersion <= 6)
+
+    THROW_ERRORS(pthread_getspecific(self_key, (void**)&me));
+
+#else
+
+    me = (omni_thread *)pthread_getspecific(self_key);
+
+#endif
+
+    if (!me) {
+      // This thread is not created by omni_thread::start because it
+      // doesn't has a class omni_thread instance attached to its key.
+      DB(cerr << "omni_thread::self: called with a non-omnithread. NULL is returned." << endl);
+    }
+
+    return me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+#if (PthreadDraftVersion == 6)
+
+    pthread_yield(NULL);
+
+#elif (PthreadDraftVersion < 9)
+
+    pthread_yield();
+
+#else
+
+    THROW_ERRORS(sched_yield());
+
+#endif
+}
+
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+
+#ifndef NoNanoSleep
+
+    timespec remain;
+    while (nanosleep(&rqts, &remain)) {
+      if (errno == EINTR) {
+       rqts.tv_sec  = remain.tv_sec;
+       rqts.tv_nsec = remain.tv_nsec;
+       continue;
+      }
+      else
+       throw omni_thread_fatal(errno);
+    }
+#else
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined (__POSIX_NT__)
+
+    if (pthread_delay_np(&rqts) != 0)
+       throw omni_thread_fatal(errno);
+
+#elif defined(__linux__) || defined(__aix__)
+
+    if (secs > 2000) {
+      while ((secs = ::sleep(secs))) ;
+    } else {
+       usleep(secs * 1000000 + (nanosecs / 1000));
+    }
+
+#elif defined(__darwin__) || defined(__macos__)
+
+    // Single UNIX Specification says argument of usleep() must be
+    // less than 1,000,000.
+    secs += nanosecs / 1000000000;
+    nanosecs %= 1000000000;
+    while ((secs = ::sleep(secs))) ;
+    usleep(nanosecs / 1000);
+
+#else
+
+    throw omni_thread_invalid();
+
+#endif
+#endif /* NoNanoSleep */
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+    timespec abs;
+
+#if defined(__osf1__) && defined(__alpha__) || defined(__hpux__) && (__OSVERSION__ == 10) || defined(__VMS) || defined(__SINIX__) || defined(__POSIX_NT__)
+
+    timespec rel;
+    rel.tv_sec = rel_sec;
+    rel.tv_nsec = rel_nsec;
+    THROW_ERRORS(pthread_get_expiration_np(&rel, &abs));
+
+#else
+
+#ifdef HAVE_CLOCK_GETTIME      /* __linux__ || __aix__ */
+
+    clock_gettime(CLOCK_REALTIME, &abs);
+
+#elif defined(HAVE_GETTIMEOFDAY)       /* defined(__linux__) || defined(__aix__) || defined(__SCO_VERSION__) || defined(__darwin__) || defined(__macos__) */
+
+    struct timeval tv;
+    gettimeofday(&tv, NULL); 
+    abs.tv_sec = tv.tv_sec;
+    abs.tv_nsec = tv.tv_usec * 1000;
+
+#else
+#error no get time support
+#endif /* __linux__ || __aix__ */
+
+    abs.tv_nsec += rel_nsec;
+    abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+    abs.tv_nsec = abs.tv_nsec % 1000000000;
+
+#endif /* __osf1__ && __alpha__ */
+
+    *abs_sec = abs.tv_sec;
+    *abs_nsec = abs.tv_nsec;
+}
+
+
+int
+omni_thread::posix_priority(priority_t pri)
+{
+#ifdef PthreadSupportThreadPriority
+    switch (pri) {
+
+    case PRIORITY_LOW:
+       return lowest_priority;
+
+    case PRIORITY_NORMAL:
+       return normal_priority;
+
+    case PRIORITY_HIGH:
+       return highest_priority;
+
+    }
+#endif
+
+    throw omni_thread_invalid();
+#ifdef _MSC_VER
+    return 0;
+#endif
+}
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+    posix_thread = pthread_self();
+    THROW_ERRORS(pthread_setspecific(self_key, (void*)this));
+  }
+  inline ~omni_thread_dummy()
+  {
+    THROW_ERRORS(pthread_setspecific(self_key, 0));
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/omnithread/solaris.cc b/omnithread/solaris.cc
new file mode 100644 (file)
index 0000000..b0139d2
--- /dev/null
@@ -0,0 +1,615 @@
+//                             Package : omnithread
+// omnithread/solaris.cc       Created : 7/94 tjr
+//
+//    Copyright (C) 1994-1999 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+//
+// Implementation of OMNI thread abstraction for solaris threads.
+//
+
+#include <stdlib.h>
+#include <errno.h>
+#include <omnithread.h>
+
+#define DB(x) // x 
+// #include <iostream> or #include <iostream.h> if DB is on.
+
+#define THROW_ERRORS(x) { int rc = (x); \
+                         if (rc != 0) throw omni_thread_fatal(rc); }
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_mutex::omni_mutex(void)
+{
+    THROW_ERRORS(mutex_init(&sol_mutex, USYNC_THREAD, 0));
+}
+
+omni_mutex::~omni_mutex(void)
+{
+    THROW_ERRORS(mutex_destroy(&sol_mutex));
+}
+
+void
+omni_mutex::lock(void)
+{
+    THROW_ERRORS(mutex_lock(&sol_mutex));
+}
+
+void
+omni_mutex::unlock(void)
+{
+    THROW_ERRORS(mutex_unlock(&sol_mutex));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+    THROW_ERRORS(cond_init(&sol_cond, USYNC_THREAD, 0));
+}
+
+omni_condition::~omni_condition(void)
+{
+    THROW_ERRORS(cond_destroy(&sol_cond));
+}
+
+void
+omni_condition::wait(void)
+{
+    THROW_ERRORS(cond_wait(&sol_cond, &mutex->sol_mutex));
+}
+
+int
+omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+
+ again:
+    int rc = cond_timedwait(&sol_cond, &mutex->sol_mutex, &rqts);
+
+    if (rc == 0)
+       return 1;
+
+    if (rc == EINTR)
+        goto again;
+
+    if (rc == ETIME)
+       return 0;
+
+    throw omni_thread_fatal(rc);
+}
+
+void
+omni_condition::signal(void)
+{
+    THROW_ERRORS(cond_signal(&sol_cond));
+}
+
+void
+omni_condition::broadcast(void)
+{
+    THROW_ERRORS(cond_broadcast(&sol_cond));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+omni_semaphore::omni_semaphore(unsigned int initial)
+{
+    THROW_ERRORS(sema_init(&sol_sem, initial, USYNC_THREAD, NULL));
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+    THROW_ERRORS(sema_destroy(&sol_sem));
+}
+
+void
+omni_semaphore::wait(void)
+{
+    THROW_ERRORS(sema_wait(&sol_sem));
+}
+
+void
+omni_semaphore::post(void)
+{
+    THROW_ERRORS(sema_post(&sol_sem));
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// Static variables
+//
+
+int omni_thread::init_t::count = 0;
+
+omni_mutex* omni_thread::next_id_mutex;
+int omni_thread::next_id = 0;
+
+static thread_key_t self_key;
+
+static size_t stack_size = 0;
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+omni_thread::init_t::init_t(void)
+{
+    if (count++ != 0)  // only do it once however many objects get created.
+       return;
+
+    DB(cerr << "omni_thread::init: solaris implementation initialising\n");
+
+    THROW_ERRORS(thr_keycreate(&self_key, NULL));
+
+    next_id_mutex = new omni_mutex;
+
+    //
+    // Create object for this (i.e. initial) thread.
+    //
+
+    omni_thread* t = new omni_thread;
+
+    t->_state = STATE_RUNNING;
+
+    t->sol_thread = thr_self();
+
+    DB(cerr << "initial thread " << t->id() << " sol_thread " << t->sol_thread
+       << endl);
+
+    THROW_ERRORS(thr_setspecific(self_key, (void*)t));
+
+    THROW_ERRORS(thr_setprio(t->sol_thread, sol_priority(PRIORITY_NORMAL)));
+}
+
+
+//
+// Wrapper for thread creation.
+//
+
+extern "C" void*
+omni_thread_wrapper(void* ptr)
+{
+    omni_thread* me = (omni_thread*)ptr;
+
+    DB(cerr << "omni_thread::wrapper: thread " << me->id()
+       << " started\n");
+
+    THROW_ERRORS(thr_setspecific(self_key, me));
+
+    //
+    // Now invoke the thread function with the given argument.
+    //
+
+    if (me->fn_void != NULL) {
+       (*me->fn_void)(me->thread_arg);
+       omni_thread::exit();
+    }
+
+    if (me->fn_ret != NULL) {
+       void* return_value = (*me->fn_ret)(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    if (me->detached) {
+       me->run(me->thread_arg);
+       omni_thread::exit();
+    } else {
+       void* return_value = me->run_undetached(me->thread_arg);
+       omni_thread::exit(return_value);
+    }
+
+    // should never get here.
+
+    return NULL;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = fn;
+    fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 0);
+    fn_void = NULL;
+    fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+    common_constructor(arg, pri, 1);
+    fn_void = NULL;
+    fn_ret = NULL;
+}
+
+// common part of all constructors.
+
+void
+omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+    _state = STATE_NEW;
+    _priority = pri;
+
+    next_id_mutex->lock();
+    _id = next_id++;
+    next_id_mutex->unlock();
+
+    thread_arg = arg;
+    detached = det;    // may be altered in start_undetached()
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+    // sol_thread is set up in initialisation routine or start().
+}
+
+
+//
+// Destructor for omni_thread.
+//
+
+omni_thread::~omni_thread(void)
+{
+    DB(cerr << "destructor called for thread " << id() << endl);
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+}
+
+
+//
+// Start the thread
+//
+
+void
+omni_thread::start(void)
+{
+    long flags = 0;
+
+    if (detached)
+       flags |= THR_DETACHED;
+
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_NEW)
+       throw omni_thread_invalid();
+
+    THROW_ERRORS(thr_create(0, stack_size, omni_thread_wrapper, (void*)this, flags,
+                           &sol_thread));
+
+    _state = STATE_RUNNING;
+
+    THROW_ERRORS(thr_setprio(sol_thread, sol_priority(_priority)));
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+
+void
+omni_thread::start_undetached(void)
+{
+    if ((fn_void != NULL) || (fn_ret != NULL))
+       throw omni_thread_invalid();
+
+    detached = 0;
+    start();
+}
+
+
+//
+// join - simply check error conditions & call thr_join.
+//
+
+void
+omni_thread::join(void** status)
+{
+    mutex.lock();
+
+    if ((_state != STATE_RUNNING) && (_state != STATE_TERMINATED)) {
+       mutex.unlock();
+       throw omni_thread_invalid();
+    }
+
+    mutex.unlock();
+
+    if (this == self())
+       throw omni_thread_invalid();
+
+    if (detached)
+       throw omni_thread_invalid();
+
+    DB(cerr << "omni_thread::join: doing thr_join\n");
+
+    THROW_ERRORS(thr_join(sol_thread, (thread_t *)NULL, status));
+
+    DB(cerr << "omni_thread::join: thr_join succeeded\n");
+
+    delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+
+void
+omni_thread::set_priority(priority_t pri)
+{
+    omni_mutex_lock l(mutex);
+
+    if (_state != STATE_RUNNING)
+       throw omni_thread_invalid();
+
+    _priority = pri;
+
+    THROW_ERRORS(thr_setprio(sol_thread, sol_priority(pri)));
+}
+
+
+//
+// create - construct a new thread object and start it running.  Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version
+
+omni_thread*
+omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+// undetached version
+
+omni_thread*
+omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+    omni_thread* t = new omni_thread(fn, arg, pri);
+
+    t->start();
+
+    return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread.  This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start().  By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.  Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+
+void
+omni_thread::exit(void* return_value)
+{
+    omni_thread* me = self();
+
+    if (me)
+      {
+       me->mutex.lock();
+
+       me->_state = STATE_TERMINATED;
+
+       me->mutex.unlock();
+
+       DB(cerr << "omni_thread::exit: thread " << me->id() << " detached "
+          << me->detached << " return value " << return_value << endl);
+
+       if (me->detached)
+         delete me;
+      }
+    else
+      {
+       DB(cerr << "omni_thread::exit: called with a non-omnithread. Exit quietly." << endl);
+      }
+
+    thr_exit(return_value);
+}
+
+
+omni_thread*
+omni_thread::self(void)
+{
+    omni_thread* me;
+
+    THROW_ERRORS(thr_getspecific(self_key, (void**)&me));
+
+    if (!me) {
+      // This thread is not created by omni_thread::start because it
+      // doesn't has a class omni_thread instance attached to its key.
+      DB(cerr << "omni_thread::self: called with a non-ominthread. NULL is returned." << endl);
+    }
+
+    return me;
+}
+
+
+void
+omni_thread::yield(void)
+{
+    thr_yield();
+}
+
+
+void
+omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+    timespec rqts = { secs, nanosecs };
+    timespec remain;
+    while (nanosleep(&rqts, &remain)) {
+      if (errno == EINTR) {
+       rqts.tv_sec  = remain.tv_sec;
+       rqts.tv_nsec = remain.tv_nsec;
+       continue;
+      }
+      else
+       throw omni_thread_fatal(errno);
+    }
+}
+
+
+void
+omni_thread::get_time(unsigned long* abs_sec, unsigned long* abs_nsec,
+                     unsigned long rel_sec, unsigned long rel_nsec)
+{
+    timespec abs;
+    clock_gettime(CLOCK_REALTIME, &abs);
+    abs.tv_nsec += rel_nsec;
+    abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+    abs.tv_nsec = abs.tv_nsec % 1000000000;
+    *abs_sec = abs.tv_sec;
+    *abs_nsec = abs.tv_nsec;
+}
+
+
+int
+omni_thread::sol_priority(priority_t pri)
+{
+    switch (pri) {
+
+    case PRIORITY_LOW:
+       return 0;
+
+    case PRIORITY_NORMAL:
+       return 1;
+
+    case PRIORITY_HIGH:
+       return 2;
+    }
+
+    throw omni_thread_invalid();
+}
+
+
+void
+omni_thread::stacksize(unsigned long sz)
+{
+  stack_size = sz;
+}
+
+unsigned long
+omni_thread::stacksize()
+{
+  return stack_size;
+}
+
+
+//
+// Dummy thread
+//
+
+#error This dummy thread code is not tested. It might work if you're lucky.
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+    sol_thread = thr_self();
+    THROW_ERRORS(thr_setspecific(self_key, (void*)this));
+  }
+  inline ~omni_thread_dummy()
+  {
+    THROW_ERRORS(thr_setspecific(self_key, 0));
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC
diff --git a/omnithread/threaddata.cc b/omnithread/threaddata.cc
new file mode 100644 (file)
index 0000000..d54c439
--- /dev/null
@@ -0,0 +1,83 @@
+//                             Package : omnithread
+// omnithread/threaddata.cc    Created : 10/2000 dpg1
+//
+//    Copyright (C) 2000 AT&T Laboratories Cambridge
+//
+//    This file is part of the omnithread library
+//
+//    The omnithread 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., 51 Franklin Street, Boston, MA  
+//    02110-1301, USA
+//
+
+// Implementation of per-thread data
+
+#ifndef INSIDE_THREAD_IMPL_CC
+#error "threaddata.cc must be #included by a thread implementation."
+#endif
+
+
+static omni_thread::key_t allocated_keys = 0;
+
+omni_thread::key_t
+omni_thread::allocate_key()
+{
+  omni_mutex_lock l(*next_id_mutex);
+  return ++allocated_keys;
+}
+
+omni_thread::value_t*
+omni_thread::set_value(key_t k, value_t* v)
+{
+  if (k == 0) return 0;
+  if (k > _value_alloc) {
+    next_id_mutex->lock();
+    key_t alloc = allocated_keys;
+    next_id_mutex->unlock();
+
+    if (k > alloc) return 0;
+
+    value_t** nv = new value_t*[alloc];
+    key_t i = 0;
+    if (_values) {
+      for (; i < _value_alloc; i++)
+       nv[i] = _values[i];
+      delete [] _values;
+    }
+    for (; i < alloc; i++)
+      nv[i] = 0;
+
+    _values = nv;
+    _value_alloc = alloc;
+  }
+  if (_values[k-1]) delete _values[k-1];
+  _values[k-1] = v;
+  return v;
+}
+
+omni_thread::value_t*
+omni_thread::get_value(key_t k)
+{
+  if (k > _value_alloc) return 0;
+  return _values[k-1];
+}
+
+omni_thread::value_t*
+omni_thread::remove_value(key_t k)
+{
+  if (k > _value_alloc) return 0;
+  value_t* v = _values[k-1];
+  _values[k-1] = 0;
+  return v;
+}
diff --git a/omnithread/vxWorks.cc b/omnithread/vxWorks.cc
new file mode 100644 (file)
index 0000000..25634ce
--- /dev/null
@@ -0,0 +1,1160 @@
+//////////////////////////////////////////////////////////////////////////////
+// Filename:    vxWorks.cc
+// Author:             Tihomir Sokcevic
+//                                     Acterna, Eningen.
+// Description: vxWorks adaptation of the omnithread wrapper classes
+// Notes:               Munching strategy is imperative
+//////////////////////////////////////////////////////////////////////////////
+// $Log$
+// Revision 1.1  2004/04/10 18:00:52  eb
+// Initial revision
+//
+// Revision 1.1.1.1  2004/03/01 00:20:27  eb
+// initial checkin
+//
+// Revision 1.1  2003/05/25 05:29:04  eb
+// see ChangeLog
+//
+// Revision 1.1.2.1  2003/02/17 02:03:11  dgrisby
+// vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).
+//
+// Revision 1.1.1.1  2002/11/19 14:58:04  sokcevti
+// OmniOrb4.0.0 VxWorks port
+//
+// Revision 1.4  2002/10/15 07:54:09  kuttlest
+// change semaphore from SEM_FIFO to SEM_PRIO
+// ---
+//
+// Revision 1.3  2002/07/05 07:38:52  engeln
+// made priority redefinable on load time by defining int variables
+//     omni_thread_prio_low = 220;
+//     omni_thread_prio_normal = 110;
+//     omni_thread_prio_high = 55;
+// the default priority is prio_normal.
+// The normal priority default has been increased from 200 to 110 and the
+//     high priority from 100 to 55.
+// ---
+//
+// Revision 1.2  2002/06/14 12:44:57  engeln
+// replaced possibly unsafe wakeup procedure in broadcast.
+// ---
+//
+// Revision 1.1.1.1  2002/04/02 10:09:34  sokcevti
+// omniORB4 initial realease
+//
+// Revision 1.0        2001/10/23 14:22:45     sokcevti
+// Initial Version 4.00
+// ---
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Include files
+//////////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <omnithread.h>
+#include <sysLib.h>
+
+#include <assert.h>            // assert
+#include <intLib.h>            // intContext
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Local defines
+//////////////////////////////////////////////////////////////////////////////
+#define ERRNO(x) (((x) != 0) ? (errno) : 0)
+#define THROW_ERRORS(x) { if((x) != OK) throw omni_thread_fatal(errno); }
+#define OMNI_THREAD_ID 0x7F7155AAl
+#define OMNI_STACK_SIZE 32768l
+
+#ifdef _DEBUG
+       #include <fstream>
+       #define DBG_TRACE(X) X
+#else // _DEBUG
+       #define DBG_TRACE(X)
+#endif // _DEBUG
+
+#define DBG_ASSERT(X)
+
+#define DBG_THROW(X) X
+
+int omni_thread_prio_low = 220;
+int omni_thread_prio_normal = 110;
+int omni_thread_prio_high = 55;
+///////////////////////////////////////////////////////////////////////////
+//
+// Mutex
+//
+///////////////////////////////////////////////////////////////////////////
+omni_mutex::omni_mutex(void):m_bConstructed(false)
+{
+       mutexID = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
+
+       DBG_ASSERT(assert(mutexID != NULL));
+
+       if(mutexID==NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::omni_mutex()  tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(-1));
+       }
+
+       m_bConstructed = true;
+}
+
+omni_mutex::~omni_mutex(void)
+{
+       m_bConstructed = false;
+
+       STATUS status = semDelete(mutexID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::~omni_mutex()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+/*
+void omni_mutex::lock(void)
+{
+       DBG_ASSERT(assert(!intContext()));              // not in ISR context
+       DBG_ASSERT(assert(m_bConstructed));
+
+       STATUS status = semTake(mutexID, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::lock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+void omni_mutex::unlock(void)
+{
+       DBG_ASSERT(assert(m_bConstructed));
+
+       STATUS status = semGive(mutexID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_mutex::unlock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+*/
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Condition variable
+//
+///////////////////////////////////////////////////////////////////////////
+omni_condition::omni_condition(omni_mutex* m) : mutex(m)
+{
+       DBG_TRACE(cout<<"omni_condition::omni_condition  mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       waiters_ = 0;
+
+       sema_ = semCCreate(SEM_Q_PRIORITY, 0);
+       if(sema_ == NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       waiters_lock_ = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
+       if(waiters_lock_ == NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+}
+
+omni_condition::~omni_condition(void)
+{
+       STATUS status = semDelete(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       status = semDelete(sema_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+void omni_condition::wait(void)
+{
+       DBG_TRACE(cout<<"omni_condition::wait            mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       // Prevent race conditions on the <waiters_> count.
+
+       STATUS status = semTake(waiters_lock_,WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       ++waiters_;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // disable task lock to have an atomic unlock+semTake
+       taskLock();
+
+       // We keep the lock held just long enough to increment the count of
+       // waiters by one.      Note that we can't keep it held across the call
+       // to wait() since that will deadlock other calls to signal().
+       mutex->unlock();
+
+       // Wait to be awakened by a cond_signal() or cond_broadcast().
+       status = semTake(sema_,WAIT_FOREVER);
+
+       // reenable task rescheduling
+       taskUnlock();
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // Reacquire lock to avoid race conditions on the <waiters_> count.
+       status = semTake(waiters_lock_,WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // We're ready to return, so there's one less waiter.
+       --waiters_;
+
+       // Release the lock so that other collaborating threads can make
+       // progress.
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // Bad things happened, so let's just return below.
+
+       // We must always regain the <external_mutex>, even when errors
+       // occur because that's the guarantee that we give to our callers.
+       mutex->lock();
+}
+
+
+// The time given is absolute. Return 0 is timeout
+int omni_condition::timedwait(unsigned long secs, unsigned long nanosecs)
+{
+       STATUS result = OK;
+       timespec now;
+       unsigned long timeout;
+       int ticks;
+
+       // Prevent race conditions on the <waiters_> count.
+       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       ++waiters_;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       clock_gettime(CLOCK_REALTIME, &now);
+
+       if(((unsigned long)secs <= (unsigned long)now.tv_sec) &&
+               (((unsigned long)secs < (unsigned long)now.tv_sec) ||
+               (nanosecs < (unsigned long)now.tv_nsec)))
+               timeout = 0;
+       else
+               timeout = (secs-now.tv_sec) * 1000 + (nanosecs-now.tv_nsec) / 1000000l;
+
+       // disable task lock to have an atomic unlock+semTake
+       taskLock();
+
+       // We keep the lock held just long enough to increment the count
+       // of waiters by one.
+       mutex->unlock();
+
+       // Wait to be awakened by a signal() or broadcast().
+       ticks = (timeout * sysClkRateGet()) / 1000L;
+       result = semTake(sema_, ticks);
+
+       // reenable task rescheduling
+       taskUnlock();
+
+       // Reacquire lock to avoid race conditions.
+       status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       --waiters_;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::timedwait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // A timeout has occured - fires exception if the origin is other than timeout
+       if(result!=OK && !(errno == S_objLib_OBJ_TIMEOUT || errno == S_objLib_OBJ_UNAVAILABLE))
+       {
+               DBG_TRACE(cout<<"omni_condition::timedwait! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       // We must always regain the <external_mutex>, even when errors
+       // occur because that's the guarantee that we give to our callers.
+       mutex->lock();
+
+       if(result!=OK) // timeout
+               return 0;
+
+       return 1;
+}
+
+void omni_condition::signal(void)
+{
+       DBG_TRACE(cout<<"omni_condition::signal          mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       int have_waiters = waiters_ > 0;
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       if(have_waiters != 0)
+       {
+               status = semGive(sema_);
+
+               DBG_ASSERT(assert(status == OK));
+
+               if(status != OK)
+               {
+                       DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+                       DBG_THROW(throw omni_thread_fatal(errno));
+               }
+       }
+}
+
+void omni_condition::broadcast(void)
+{
+       DBG_TRACE(cout<<"omni_condition::broadcast       mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);
+
+       int have_waiters = 0;
+
+       // The <external_mutex> must be locked before this call is made.
+       // This is needed to ensure that <waiters_> and <was_broadcast_> are
+       // consistent relative to each other.
+       STATUS status = semTake(waiters_lock_, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       if(waiters_ > 0)
+       {
+               // We are broadcasting, even if there is just one waiter...
+               // Record the fact that we are broadcasting.    This helps the
+               // cond_wait() method know how to optimize itself.      Be sure to
+               // set this with the <waiters_lock_> held.
+               have_waiters = 1;
+       }
+
+       status = semGive(waiters_lock_);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+
+       if(have_waiters)
+       {
+               // Wake up all the waiters.
+               status = semFlush(sema_);
+
+                       DBG_ASSERT(assert(status == OK));
+
+                       if(status != OK)
+                       {
+                               DBG_TRACE(cout<<"omni_condition::broadcast1! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);
+                               DBG_THROW(throw omni_thread_fatal(errno));
+                       }
+
+       }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Counting semaphore
+//
+///////////////////////////////////////////////////////////////////////////
+omni_semaphore::omni_semaphore(unsigned int initial)
+{
+
+       DBG_ASSERT(assert(0 <= (int)initial));          // POSIX expects only unsigned init values
+
+       semID = semCCreate(SEM_Q_PRIORITY, (int)initial);
+
+       DBG_ASSERT(assert(semID!=NULL));
+
+       if(semID==NULL)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::omni_semaphore"<<endl);
+               DBG_THROW(throw omni_thread_fatal(-1));
+       }
+}
+
+omni_semaphore::~omni_semaphore(void)
+{
+       STATUS status = semDelete(semID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::~omni_semaphore"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+void omni_semaphore::wait(void)
+{
+       DBG_ASSERT(assert(!intContext()));              // no wait in ISR
+
+       STATUS status = semTake(semID, WAIT_FOREVER);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::wait"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+int omni_semaphore::trywait(void)
+{
+       STATUS status = semTake(semID, NO_WAIT);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               if(errno == S_objLib_OBJ_UNAVAILABLE)
+               {
+                       return 0;
+               }
+               else
+               {
+                       DBG_ASSERT(assert(false));
+
+                       DBG_TRACE(cout<<"Exception: omni_semaphore::trywait"<<endl);
+                       DBG_THROW(throw omni_thread_fatal(errno));
+               }
+       }
+
+       return 1;
+}
+
+void omni_semaphore::post(void)
+{
+       STATUS status = semGive(semID);
+
+       DBG_ASSERT(assert(status == OK));
+
+       if(status != OK)
+       {
+               DBG_TRACE(cout<<"Exception: omni_semaphore::post"<<endl);
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Thread
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//
+// static variables
+//
+omni_mutex* omni_thread::next_id_mutex = 0;
+int omni_thread::next_id = 0;
+
+// omniORB requires a larger stack size than the default (21120) on OSF/1
+static size_t stack_size = OMNI_STACK_SIZE;
+
+
+//
+// Initialisation function (gets called before any user code).
+//
+
+static int& count() {
+  static int the_count = 0;
+  return the_count;
+}
+
+omni_thread::init_t::init_t(void)
+{
+       // Only do it once however many objects get created.
+       if(count()++ != 0)
+               return;
+
+       attach();
+}
+
+omni_thread::init_t::~init_t(void)
+{
+    if (--count() != 0) return;
+
+    omni_thread* self = omni_thread::self();
+    if (!self) return;
+
+    taskTcb(taskIdSelf())->spare1 = 0;
+    delete self;
+
+    delete next_id_mutex;
+}
+
+
+//
+// Wrapper for thread creation.
+//
+extern "C" void omni_thread_wrapper(void* ptr)
+{
+       omni_thread* me = (omni_thread*)ptr;
+
+       DBG_TRACE(cout<<"omni_thread_wrapper: thread "<<me->id()<<" started\n");
+
+       //
+       // We can now tweaked the task info since the tcb exist now
+       //
+       me->mutex.lock();       // To ensure that start has had time to finish
+       taskTcb(me->tid)->spare1 = OMNI_THREAD_ID;
+       taskTcb(me->tid)->spare2 = (int)ptr;
+       me->mutex.unlock();
+
+       //
+       // Now invoke the thread function with the given argument.
+       //
+       if(me->fn_void != NULL)
+       {
+               (*me->fn_void)(me->thread_arg);
+               omni_thread::exit();
+       }
+
+       if(me->fn_ret != NULL)
+       {
+               void* return_value = (*me->fn_ret)(me->thread_arg);
+               omni_thread::exit(return_value);
+       }
+
+       if(me->detached)
+       {
+               me->run(me->thread_arg);
+               omni_thread::exit();
+       }
+       else
+       {
+               void* return_value = me->run_undetached(me->thread_arg);
+               omni_thread::exit(return_value);
+       }
+}
+
+
+//
+// Special functions for VxWorks only
+//
+void omni_thread::attach(void)
+{
+       DBG_TRACE(cout<<"omni_thread_attach: VxWorks mapping thread initialising\n");
+
+       int _tid = taskIdSelf();
+
+       // Check the task is not already attached
+       if(taskTcb(_tid)->spare1 == OMNI_THREAD_ID)
+               return;
+
+       // Create the mutex required to lock the threads debugging id (create before the thread!!!)
+       if(next_id_mutex == 0)
+               next_id_mutex = new omni_mutex;
+
+       // Create a thread object for THIS running process
+       omni_thread* t = new omni_thread;
+
+       // Lock its mutex straigh away!
+       omni_mutex_lock l(t->mutex);
+
+       // Adjust data members of this instance
+       t->_state = STATE_RUNNING;
+       t->tid = taskIdSelf();
+
+       // Set the thread values so it can be recongnised as a omni_thread
+       // Set the id last can possibly prevent race condition
+       taskTcb(t->tid)->spare2 = (int)t;
+       taskTcb(t->tid)->spare1 = OMNI_THREAD_ID;
+
+       // Create the running_mutex at this stage, but leave it empty. We are not running
+       //      in the task context HERE, so taking it would be disastrous.
+       t->running_cond = new omni_condition(&t->mutex);
+}
+
+
+void omni_thread::detach(void)
+{
+       DBG_TRACE(cout<<"omni_thread_detach: VxWorks detaching thread mapping\n");
+
+       int _tid = taskIdSelf();
+
+       // Check the task has a OMNI_THREAD attached
+       if(taskTcb(_tid)->spare1 != OMNI_THREAD_ID)
+               return;
+
+       // Invalidate the id NOW !
+       taskTcb(_tid)->spare1 = 0;
+
+       // Even if NULL, it is safe to delete the thread
+       omni_thread* t = (omni_thread*)taskTcb(_tid)->spare2;
+       // Fininsh cleaning the tcb structure
+       taskTcb(_tid)->spare2 = 0;
+
+       delete t;
+}
+
+
+//
+// Constructors for omni_thread - set up the thread object but don't
+// start it running.
+//
+
+// construct a detached thread running a given function.
+omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
+{
+       common_constructor(arg, pri, 1);
+       fn_void = fn;
+       fn_ret = NULL;
+}
+
+// construct an undetached thread running a given function.
+omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
+{
+       common_constructor(arg, pri, 0);
+       fn_void = NULL;
+       fn_ret = fn;
+}
+
+// construct a thread which will run either run() or run_undetached().
+
+omni_thread::omni_thread(void* arg, priority_t pri)
+{
+       common_constructor(arg, pri, 1);
+       fn_void = NULL;
+       fn_ret = NULL;
+}
+
+// common part of all constructors.
+void omni_thread::common_constructor(void* arg, priority_t pri, int det)
+{
+       _state = STATE_NEW;
+       _priority = pri;
+
+       // Set the debugging id
+       next_id_mutex->lock();
+       _id = next_id++;
+       next_id_mutex->unlock();
+
+       // Note : tid can only be setup when the task is up and running
+       tid = 0;
+
+       thread_arg = arg;
+       detached = det;         // may be altered in start_undetached()
+
+    _dummy       = 0;
+    _values      = 0;
+    _value_alloc = 0;
+}
+
+//
+// Destructor for omni_thread.
+//
+omni_thread::~omni_thread(void)
+{
+       DBG_TRACE(cout<<"omni_thread::~omni_thread for thread "<<id()<<endl);
+
+    if (_values) {
+        for (key_t i=0; i < _value_alloc; i++) {
+           if (_values[i]) {
+               delete _values[i];
+           }
+        }
+       delete [] _values;
+    }
+
+       delete running_cond;
+}
+
+
+//
+// Start the thread
+//
+void omni_thread::start(void)
+{
+       omni_mutex_lock l(mutex);
+
+       DBG_ASSERT(assert(_state == STATE_NEW));
+
+       if(_state != STATE_NEW)
+               DBG_THROW(throw omni_thread_invalid());
+
+       // Allocate memory for the task. (The returned id cannot be trusted by the task)
+       tid = taskSpawn(
+               NULL,                                                            // Task name
+               vxworks_priority(_priority),    // Priority
+               0,                                                                       // Option
+               stack_size,                                              // Stack size
+               (FUNCPTR)omni_thread_wrapper, // Priority
+               (int)this,                                                      // First argument is this
+               0,0,0,0,0,0,0,0,0                                // Remaining unused args
+               );
+
+       DBG_ASSERT(assert(tid!=ERROR));
+
+       if(tid==ERROR)
+               DBG_THROW(throw omni_thread_invalid());
+
+       _state = STATE_RUNNING;
+
+       // Create the running_mutex at this stage, but leave it empty. We are not running
+       //      in the task context HERE, so taking it would be disastrous.
+       running_cond = new omni_condition(&mutex);
+}
+
+
+//
+// Start a thread which will run the member function run_undetached().
+//
+void omni_thread::start_undetached(void)
+{
+       DBG_ASSERT(assert(!((fn_void != NULL) || (fn_ret != NULL))));
+
+       if((fn_void != NULL) || (fn_ret != NULL))
+               DBG_THROW(throw omni_thread_invalid());
+
+       detached = 0;
+
+       start();
+}
+
+
+//
+// join - Wait for the task to complete before returning to the calling process
+//
+void omni_thread::join(void** status)
+{
+       mutex.lock();
+
+       if((_state != STATE_RUNNING) && (_state != STATE_TERMINATED))
+       {
+               mutex.unlock();
+
+               DBG_ASSERT(assert(false));
+
+               DBG_THROW(throw omni_thread_invalid());
+       }
+
+       mutex.unlock();
+
+       DBG_ASSERT(assert(this != self()));
+
+       if(this == self())
+               DBG_THROW(throw omni_thread_invalid());
+
+       DBG_ASSERT(assert(!detached));
+
+       if(detached)
+               DBG_THROW(throw omni_thread_invalid());
+
+       mutex.lock();
+       running_cond->wait();
+       mutex.unlock();
+
+       if(status)
+               *status = return_val;
+
+       delete this;
+}
+
+
+//
+// Change this thread's priority.
+//
+void omni_thread::set_priority(priority_t pri)
+{
+       omni_mutex_lock l(mutex);
+
+       DBG_ASSERT(assert(_state == STATE_RUNNING));
+
+       if(_state != STATE_RUNNING)
+       {
+               DBG_THROW(throw omni_thread_invalid());
+       }
+
+       _priority = pri;
+
+       if(taskPrioritySet(tid, vxworks_priority(pri))==ERROR)
+       {
+               DBG_ASSERT(assert(false));
+
+               DBG_THROW(throw omni_thread_fatal(errno));
+       }
+}
+
+
+//
+// create - construct a new thread object and start it running.        Returns thread
+// object if successful, null pointer if not.
+//
+
+// detached version (the entry point is a void)
+omni_thread* omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
+{
+       omni_thread* t = new omni_thread(fn, arg, pri);
+
+       t->start();
+
+       return t;
+}
+
+// undetached version (the entry point is a void*)
+omni_thread* omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
+{
+       omni_thread* t = new omni_thread(fn, arg, pri);
+
+       t->start();
+
+       return t;
+}
+
+
+//
+// exit() _must_ lock the mutex even in the case of a detached thread. This is
+// because a thread may run to completion before the thread that created it has
+// had a chance to get out of start(). By locking the mutex we ensure that the
+// creating thread must have reached the end of start() before we delete the
+// thread object.      Of course, once the call to start() returns, the user can
+// still incorrectly refer to the thread object, but that's their problem.
+//
+void omni_thread::exit(void* return_value)
+{
+       omni_thread* me = self();
+
+       if(me)
+       {
+               me->mutex.lock();
+
+               me->return_val = return_value;
+               me->_state = STATE_TERMINATED;
+               me->running_cond->signal();
+
+               me->mutex.unlock();
+
+               DBG_TRACE(cout<<"omni_thread::exit: thread "<<me->id()<<" detached "<<me->detached<<" return value "<<(int)return_value<<endl);
+
+               if(me->detached)
+                       delete me;
+       }
+       else
+               DBG_TRACE(cout<<"omni_thread::exit: called with a non-omnithread. Exit quietly."<<endl);
+
+       taskDelete(taskIdSelf());
+}
+
+
+omni_thread* omni_thread::self(void)
+{
+       if(taskTcb(taskIdSelf())->spare1 != OMNI_THREAD_ID)
+               return NULL;
+
+       return (omni_thread*)taskTcb(taskIdSelf())->spare2;
+}
+
+
+void omni_thread::yield(void)
+{
+       taskDelay(NO_WAIT);
+}
+
+
+void omni_thread::sleep(unsigned long secs, unsigned long nanosecs)
+{
+       int tps = sysClkRateGet();
+
+       // Convert to us to avoid overflow in the multiplication
+       //      tps should always be less than 1000 !
+       nanosecs /= 1000;
+
+       taskDelay(secs*tps + (nanosecs*tps)/1000000l);
+}
+
+
+void omni_thread::get_time( unsigned long* abs_sec,
+                                                       unsigned long* abs_nsec,
+                                                       unsigned long rel_sec,
+                                                       unsigned long rel_nsec)
+{
+       timespec abs;
+       clock_gettime(CLOCK_REALTIME, &abs);
+       abs.tv_nsec += rel_nsec;
+       abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;
+       abs.tv_nsec = abs.tv_nsec % 1000000000;
+       *abs_sec = abs.tv_sec;
+       *abs_nsec = abs.tv_nsec;
+}
+
+
+int omni_thread::vxworks_priority(priority_t pri)
+{
+       switch (pri)
+       {
+       case PRIORITY_LOW:
+               return omni_thread_prio_low;
+
+       case PRIORITY_NORMAL:
+               return omni_thread_prio_normal;
+
+       case PRIORITY_HIGH:
+               return omni_thread_prio_high;
+       }
+
+       DBG_ASSERT(assert(false));
+
+       DBG_THROW(throw omni_thread_invalid());
+}
+
+
+void omni_thread::stacksize(unsigned long sz)
+{
+       stack_size = sz;
+}
+
+
+unsigned long omni_thread::stacksize()
+{
+       return stack_size;
+}
+
+
+void omni_thread::show(void)
+{
+       omni_thread *pThread;
+       int s1, s2;
+       int tid = taskIdSelf();
+
+       printf("TaskId is %.8x\n", tid);
+
+       s1 = taskTcb(tid)->spare1;
+
+       if(s1 != OMNI_THREAD_ID)
+       {
+               printf("Spare 1 is %.8x, and not recongnized\n", s1);
+
+               return;
+       }
+       else
+       {
+               printf("Spare 1 indicate an omni_thread.\n");
+       }
+
+       s2 = taskTcb(tid)->spare2;
+
+       if(s2 == 0)
+       {
+               printf("Spare 2 is NULL! - No thread object attached !!\n");
+
+               return;
+       }
+       else
+       {
+               printf("Thread object at %.8x\n", s2);
+       }
+
+       pThread = (omni_thread *)s2;
+
+       state_t status = pThread->_state;
+
+       printf("        | Thread status is ");
+
+       switch (status)
+       {
+       case STATE_NEW:
+               printf("NEW\n");                break;
+       case STATE_RUNNING:
+               printf("STATE_RUNNING\n"); break;
+       case STATE_TERMINATED:
+               printf("TERMINATED\n"); break;
+       default:
+               printf("Illegal (=%.8x)\n", (unsigned int)status);
+
+               return;
+       }
+
+       if(pThread->tid != tid)
+       {
+               printf("        | Task ID in thread object is different!! (=%.8x)\n", pThread->tid);
+
+               return;
+       }
+       else
+       {
+               printf("        | Task ID in thread consistent\n");
+       }
+
+       printf("\n");
+}
+
+
+//
+// Dummy thread
+//
+
+class omni_thread_dummy : public omni_thread {
+public:
+  inline omni_thread_dummy() : omni_thread()
+  {
+    _dummy = 1;
+    _state = STATE_RUNNING;
+
+       // Adjust data members of this instance
+       tid = taskIdSelf();
+
+       // Set the thread values so it can be recongnised as a omni_thread
+       // Set the id last can possibly prevent race condition
+       taskTcb(tid)->spare2 = (int)this;
+       taskTcb(tid)->spare1 = OMNI_THREAD_ID;
+   }
+  inline ~omni_thread_dummy()
+  {
+       taskTcb(taskIdSelf())->spare1 = 0;
+  }
+};
+
+omni_thread*
+omni_thread::create_dummy()
+{
+  if (omni_thread::self())
+    throw omni_thread_invalid();
+
+  return new omni_thread_dummy;
+}
+
+void
+omni_thread::release_dummy()
+{
+  omni_thread* self = omni_thread::self();
+  if (!self || !self->_dummy)
+    throw omni_thread_invalid();
+
+  omni_thread_dummy* dummy = (omni_thread_dummy*)self;
+  delete dummy;
+}
+
+
+#define INSIDE_THREAD_IMPL_CC
+#include "threaddata.cc"
+#undef INSIDE_THREAD_IMPL_CC