Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57471 - in sandbox/stm/branches/vbe: boost/stm boost/stm/non_tx boost/stm/synch boost/stm/tx libs/stm/example
From: vicente.botet_at_[hidden]
Date: 2009-11-07 17:40:53


Author: viboes
Date: 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
New Revision: 57471
URL: http://svn.boost.org/trac/boost/changeset/57471

Log:
TBoost.STM vbe: Separating object from mixin

Added:
   sandbox/stm/branches/vbe/boost/stm/non_tx/mixin.hpp (contents, props changed)
   sandbox/stm/branches/vbe/boost/stm/tx/mixin.hpp (contents, props changed)
Text files modified:
   sandbox/stm/branches/vbe/boost/stm/non_tx.hpp | 1
   sandbox/stm/branches/vbe/boost/stm/non_tx/numeric.hpp | 6 ++--
   sandbox/stm/branches/vbe/boost/stm/non_tx/object.hpp | 50 ++++-----------------------------
   sandbox/stm/branches/vbe/boost/stm/non_tx/pointer.hpp | 10 +++---
   sandbox/stm/branches/vbe/boost/stm/synch/mutex.hpp | 42 ++++++++++++++++++++--------
   sandbox/stm/branches/vbe/boost/stm/tx.hpp | 1
   sandbox/stm/branches/vbe/boost/stm/tx/numeric.hpp | 6 ++--
   sandbox/stm/branches/vbe/boost/stm/tx/object.hpp | 58 ++++++---------------------------------
   sandbox/stm/branches/vbe/boost/stm/tx/pointer.hpp | 13 ++++----
   sandbox/stm/branches/vbe/libs/stm/example/non_tx_counter.cpp | 2
   10 files changed, 67 insertions(+), 122 deletions(-)

Modified: sandbox/stm/branches/vbe/boost/stm/non_tx.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/non_tx.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/non_tx.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -14,6 +14,7 @@
 #ifndef BOOST_STM_NON_TX__HPP
 #define BOOST_STM_NON_TX__HPP
 
+#include <boost/stm/non_tx/mixin.hpp>
 #include <boost/stm/non_tx/object.hpp>
 #include <boost/stm/non_tx/numeric.hpp>
 #include <boost/stm/non_tx/pointer.hpp>

Added: sandbox/stm/branches/vbe/boost/stm/non_tx/mixin.hpp
==============================================================================
--- (empty file)
+++ sandbox/stm/branches/vbe/boost/stm/non_tx/mixin.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -0,0 +1,86 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Justin E. Gottchlich 2009.
+// (C) Copyright Vicente J. Botet Escriba 2009.
+// Distributed under the Boost
+// Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or
+// copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/stm for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_STM_NON_TX_MIXIN__HPP
+#define BOOST_STM_NON_TX_MIXIN__HPP
+
+//-----------------------------------------------------------------------------
+#include <boost/stm/transaction.hpp>
+#include <boost/stm/non_tx/detail/cache_map.hpp>
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+namespace boost { namespace stm { namespace non_tx {
+
+//-----------------------------------------------------------------------------
+// class object wraps a non object type providing
+// a transactional view on a transactional context
+// a non-transactional view on a non-transactional context
+// Note: the sizeof(object<T>)==sizeof(T)
+//-----------------------------------------------------------------------------
+
+template <typename Final, typename T>
+class mixin {
+protected:
+ T val_;
+public:
+ //-----------------------------------------------------------------------------
+ mixin() : val_() {}
+
+ // constructors
+ template<typename F, typename U>
+ mixin(mixin<F,U> const& r) : val_(r.value()) {}
+
+ // contructor from a convertible to T
+ template <typename U>
+ mixin(U v) : val_(v) {}
+
+ //-----------------------------------------------------------------------------
+ // accessors
+ operator T() const { return value(); }
+ operator T&() { return ref(); }
+
+ //-----------------------------------------------------------------------------
+ T& ref() {
+ transaction* tx=current_transaction();
+ if (tx!=0) {
+ if (tx->forced_to_abort()) {
+ tx->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+
+ detail::cache<T>* r(tx->write_ptr(detail::cache_map::get(&val_)));
+ return *(r->get());
+ }
+ return val_;
+ }
+
+ //-----------------------------------------------------------------------------
+ T value() const {
+ transaction* tx=current_transaction();
+ if (tx!=0) {
+ if (tx->forced_to_abort()) {
+ tx->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+ detail::cache<T>* r(tx->read_ptr(detail::cache_map::get(&val_)));
+ return *(r->get());
+ }
+ return val_;
+ }
+};
+
+}}}
+#endif
+
+

Modified: sandbox/stm/branches/vbe/boost/stm/non_tx/numeric.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/non_tx/numeric.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/non_tx/numeric.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -15,7 +15,7 @@
 #define BOOST_STM_NON_TX_NUMERIC__HPP
 
 //-----------------------------------------------------------------------------
-#include <boost/stm/non_tx/object.hpp>
+#include <boost/stm/non_tx/mixin.hpp>
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
@@ -29,9 +29,9 @@
 //-----------------------------------------------------------------------------
 
 template <typename T>
-class numeric : public object< numeric<T>, T >
+class numeric : public mixin< numeric<T>, T >
 {
- typedef object< numeric<T> ,T > base_type;
+ typedef mixin< numeric<T> ,T > base_type;
 public:
     //-----------------------------------------------------------------------------
     numeric() : base_type(0) {}

Modified: sandbox/stm/branches/vbe/boost/stm/non_tx/object.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/non_tx/object.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/non_tx/object.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -15,8 +15,7 @@
 #define BOOST_STM_NON_TX_OBJECT__HPP
 
 //-----------------------------------------------------------------------------
-#include <boost/stm/transaction.hpp>
-#include <boost/stm/non_tx/detail/cache_map.hpp>
+#include <boost/stm/non_tx/mixin.hpp>
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
@@ -29,55 +28,20 @@
 // Note: the sizeof(object<T>)==sizeof(T)
 //-----------------------------------------------------------------------------
 
-template <typename Final, typename T>
-class object {
-protected:
- T val_;
+template <typename T>
+struct object : mixin< object<T>, T> {
 public:
+ typedef mixin< object<T>, T > base_type;
     //-----------------------------------------------------------------------------
- object() : val_() {}
+ object() : base_type() {}
 
     // constructors
     template<typename F, typename U>
- object(object<F,U> const& r) : val_(r.value()) {}
+ object(object<U> const& r) : base_type(r) {}
 
     // contructor from a convertible to T
     template <typename U>
- object(U v) : val_(v) {}
-
- //-----------------------------------------------------------------------------
- // accessors
- operator T() const { return value(); }
- operator T&() { return ref(); }
-
- //-----------------------------------------------------------------------------
- T& ref() {
- transaction* tx=current_transaction();
- if (tx!=0) {
- if (tx->forced_to_abort()) {
- tx->lock_and_abort();
- throw aborted_transaction_exception("aborting transaction");
- }
-
- detail::cache<T>* r(tx->write_ptr(detail::cache_map::get(&val_)));
- return *(r->get());
- }
- return val_;
- }
-
- //-----------------------------------------------------------------------------
- T value() const {
- transaction* tx=current_transaction();
- if (tx!=0) {
- if (tx->forced_to_abort()) {
- tx->lock_and_abort();
- throw aborted_transaction_exception("aborting transaction");
- }
- detail::cache<T>* r(tx->read_ptr(detail::cache_map::get(&val_)));
- return *(r->get());
- }
- return val_;
- }
+ object(U v) :base_type(v) {}
 };
 
 }}}

Modified: sandbox/stm/branches/vbe/boost/stm/non_tx/pointer.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/non_tx/pointer.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/non_tx/pointer.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -15,7 +15,7 @@
 #define BOOST_STM_NON_TX_POINTER__HPP
 
 //-----------------------------------------------------------------------------
-#include <boost/stm/non_tx/object.hpp>
+#include <boost/stm/non_tx/mixin.hpp>
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
@@ -30,9 +30,9 @@
 //-----------------------------------------------------------------------------
 
 template <typename T>
-class pointer : public object< pointer<T> ,T* >
+class pointer : public mixin< pointer<T> ,T* >
 {
- typedef object< pointer<T> , T* > base_type;
+ typedef mixin< pointer<T> , T* > base_type;
     
 public:
     //-----------------------------------------------------------------------------
@@ -62,9 +62,9 @@
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 template <typename C, typename R>
-class pointer_to_member : public transaction_object< pointer_to_member<C,R> >
+class pointer_to_member : public mixin< pointer_to_member<C,R>, R C::* >
 {
- typedef object< pointer_to_member<C,R> ,R C::*> base_type;
+ typedef mixin< pointer_to_member<C,R>, R C::*> base_type;
 public:
     //-----------------------------------------------------------------------------
     pointer_to_member() : base_type(static_cast<R C::*>(0)) {}

Modified: sandbox/stm/branches/vbe/boost/stm/synch/mutex.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/synch/mutex.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/synch/mutex.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -22,15 +22,15 @@
 namespace boost { namespace stm {
 
 template <typename Lockable>
-class latm_exclusive_lock_adapter : public boost::synchro::poly::exclusive_lock
+class exclusive_lock_adapter : public boost::synchro::poly::exclusive_lock
 {
 public:
     typedef Lockable lockable_type;
 
- BOOST_COPY_CONSTRUCTOR_DELETE(latm_exclusive_lock_adapter) /*< disable copy construction >*/
- BOOST_COPY_ASSIGNEMENT_DELETE(latm_exclusive_lock_adapter) /*< disable copy asignement >*/
- latm_exclusive_lock_adapter() {}
- ~latm_exclusive_lock_adapter() {}
+ BOOST_COPY_CONSTRUCTOR_DELETE(exclusive_lock_adapter) /*< disable copy construction >*/
+ BOOST_COPY_ASSIGNEMENT_DELETE(exclusive_lock_adapter) /*< disable copy asignement >*/
+ exclusive_lock_adapter() {}
+ ~exclusive_lock_adapter() {}
 
     void lock() {stm::lock(lock_);}
     void unlock() {stm::unlock(lock_);}
@@ -42,16 +42,34 @@
 };
 
 template <typename Lockable>
-void lock(latm_exclusive_lock_adapter<Lockable>& lock) {transaction::pthread_lock(&lock);}
+class exclusive_ref_lock_adapter
+{
+public:
+ typedef Lockable lockable_type;
+
+ exclusive_ref_lock_adapter(lockable_type& lock): lock_(lock) {}
+ ~exclusive_ref_lock_adapter() {}
+
+ void lock() {stm::lock(lock_);}
+ void unlock() {stm::unlock(lock_);}
+ bool try_lock() { return stm::try_lock(lock_);}
+
+protected:
+ lockable_type* the_lock() { return &lock_; }
+ mutable lockable_type& lock_;
+};
+
+template <typename Lockable>
+void lock(exclusive_lock_adapter<Lockable>& lock) {transaction::pthread_lock(&lock);}
 template <typename Lockable>
-bool try_lock(latm_exclusive_lock_adapter<Lockable>& lock) {return transaction::pthread_trylock(&lock);}
+bool try_lock(exclusive_lock_adapter<Lockable>& lock) {return transaction::pthread_trylock(&lock);}
 template <typename Lockable>
-void unlock(latm_exclusive_lock_adapter<Lockable>& lock) {transaction::pthread_unlock(&lock);}
+void unlock(exclusive_lock_adapter<Lockable>& lock) {transaction::pthread_unlock(&lock);}
 
 #if 0
 template <typename TimedLock>
-class latm_timed_lock_adapter
- : public latm_exclusive_lock_adapter<TimedLock>
+class timed_lock_adapter
+ : public exclusive_lock_adapter<TimedLock>
 {
 public:
     typedef TimedLock lockable_base_type;
@@ -64,7 +82,7 @@
     template<typename Rep, typename Period>
     bool try_lock_for(chrono::duration<Rep, Period> const & rel_time)
     {return transaction::try_lock_for(the_lock(), rel_time);}
-
+
 
     template<typename Clock, typename Duration>
     void lock_until(chrono::time_point<Clock, Duration> const & abs_time)
@@ -72,7 +90,7 @@
     template<typename Rep, typename Period>
     void lock_for(chrono::duration<Rep, Period> const & rel_time)
     {transaction::::lock_for(the_lock(), rel_time);}
-
+
 protected:
     //TimedLock& the_lock() {return *static_cast<TimedLock*>(&this->lock_);}
 };

Modified: sandbox/stm/branches/vbe/boost/stm/tx.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/tx.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/tx.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -19,6 +19,7 @@
 #include <boost/stm/tx/shallow_transaction_object.hpp>
 #include <boost/stm/tx/deep_transaction_object.hpp>
 #include <boost/stm/tx_ptr.hpp>
+#include <boost/stm/tx/mixin.hpp>
 #include <boost/stm/tx/object.hpp>
 #include <boost/stm/tx/numeric.hpp>
 #include <boost/stm/tx/pointer.hpp>

Added: sandbox/stm/branches/vbe/boost/stm/tx/mixin.hpp
==============================================================================
--- (empty file)
+++ sandbox/stm/branches/vbe/boost/stm/tx/mixin.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -0,0 +1,85 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Justin E. Gottchlich 2009.
+// (C) Copyright Vicente J. Botet Escriba 2009.
+// Distributed under the Boost
+// Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or
+// copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/stm for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_STM_TX_MIXIN__HPP
+#define BOOST_STM_TX_MIXIN__HPP
+
+//-----------------------------------------------------------------------------
+#include <boost/stm/transaction.hpp>
+#include <boost/stm/transaction_object.hpp>
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+namespace boost { namespace stm { namespace tx {
+
+//-----------------------------------------------------------------------------
+// mixin transactional object class that wraps a object type providing
+// a transparent transactional view on a transactional context
+// a non-transactional view on a non-transactional context
+// Note: the sizeof(object<T>)>>>>=sizeof(T)
+//-----------------------------------------------------------------------------
+template <typename Final, typename T, typename Base=base_transaction_object>
+class mixin : public transaction_object< Final, Base >
+{
+protected:
+ T val_;
+public:
+ typedef Final final_type;
+ typedef T value_type;
+ //-----------------------------------------------------------------------------
+ mixin() : val_() {}
+
+ //
+ template<typename F, typename U>
+ mixin(mixin<F,U> const& r) : val_(r.value()) {}
+
+ // contructor from a convertible to T
+ template <typename U>
+ mixin(U v) : val_(v) {}
+
+ operator T() const { return value(); }
+ operator T&() { return ref(); }
+
+ //-----------------------------------------------------------------------------
+ // accessors
+ T& ref() {
+ transaction* tx=current_transaction();
+ if (tx!=0) {
+ if (tx->forced_to_abort()) {
+ tx->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+
+ return tx->write(*this).val_;
+ }
+ return val_;
+ }
+
+ //-----------------------------------------------------------------------------
+ T value() const {
+ transaction* tx=current_transaction();
+ if (tx!=0) {
+ if (tx->forced_to_abort()) {
+ tx->lock_and_abort();
+ throw aborted_transaction_exception("aborting transaction");
+ }
+ return tx->read(*this).val_;
+ }
+ return val_;
+ }
+};
+
+}}}
+#endif //BOOST_STM_TX_MIXIN__HPP
+
+

Modified: sandbox/stm/branches/vbe/boost/stm/tx/numeric.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/tx/numeric.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/tx/numeric.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -15,7 +15,7 @@
 #define BOOST_STM_TX_NUMERIC__HPP
 
 //-----------------------------------------------------------------------------
-#include <boost/stm/tx/object.hpp>
+#include <boost/stm/tx/mixin.hpp>
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
@@ -28,9 +28,9 @@
 // Note: the sizeof(numeric<T>)>>>>=sizeof(T)
 //-----------------------------------------------------------------------------
 template <typename T>
-class numeric : public object< numeric<T>, T >
+class numeric : public mixin< numeric<T>, T >
 {
- typedef object< numeric<T> ,T > base_type;
+ typedef mixin< numeric<T> ,T > base_type;
 public:
     //-----------------------------------------------------------------------------
     numeric() : base_type(0) {}

Modified: sandbox/stm/branches/vbe/boost/stm/tx/object.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/tx/object.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/tx/object.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -15,71 +15,33 @@
 #define BOOST_STM_TX_OBJECT__HPP
 
 //-----------------------------------------------------------------------------
-#include <boost/stm/transaction.hpp>
-#include <boost/stm/transaction_object.hpp>
+#include <boost/stm/tx/mixin.hpp>
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
 namespace boost { namespace stm { namespace tx {
 
 //-----------------------------------------------------------------------------
-// mixing transactional object class that wraps a object type providing
+// transactional object class that wraps a object type providing
 // a transparent transactional view on a transactional context
 // a non-transactional view on a non-transactional context
 // Note: the sizeof(object<T>)>>>>=sizeof(T)
 //-----------------------------------------------------------------------------
-template <typename Final, typename T>
-class object : public transaction_object< Final >
+template <typename T>
+class object : public mixin< object<T>, T >
 {
-protected:
- T val_;
 public:
- typedef Final final_type;
- typedef T value_type;
+ typedef mixin< object<T>, T > base_type;
     //-----------------------------------------------------------------------------
- object() : val_() {}
-
- //
- template<typename F, typename U>
- object(object<F,U> const& r) : val_(r.value()) {}
-
+ object() : base_type() {}
+ template<typename U>
+ object(object<U> const& r) : base_type(r) {}
     // contructor from a convertible to T
     template <typename U>
- object(U v) : val_(v) {}
-
- operator T() const { return value(); }
- operator T&() { return ref(); }
-
- //-----------------------------------------------------------------------------
- // accessors
- T& ref() {
- transaction* tx=current_transaction();
- if (tx!=0) {
- if (tx->forced_to_abort()) {
- tx->lock_and_abort();
- throw aborted_transaction_exception("aborting transaction");
- }
-
- return tx->write(*this).val_;
- }
- return val_;
- }
-
- //-----------------------------------------------------------------------------
- T value() const {
- transaction* tx=current_transaction();
- if (tx!=0) {
- if (tx->forced_to_abort()) {
- tx->lock_and_abort();
- throw aborted_transaction_exception("aborting transaction");
- }
- return tx->read(*this).val_;
- }
- return val_;
- }
+ object(U v) : base_type(v) {}
 };
 
 }}}
-#endif
+#endif //BOOST_STM_TX_OBJECT__HPP
 
 

Modified: sandbox/stm/branches/vbe/boost/stm/tx/pointer.hpp
==============================================================================
--- sandbox/stm/branches/vbe/boost/stm/tx/pointer.hpp (original)
+++ sandbox/stm/branches/vbe/boost/stm/tx/pointer.hpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -15,23 +15,22 @@
 #define BOOST_STM_TX_POINTER__HPP
 
 //-----------------------------------------------------------------------------
-#include <boost/stm/tx/object.hpp>
+#include <boost/stm/tx/mixin.hpp>
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
 namespace boost { namespace stm { namespace tx {
 
 //-----------------------------------------------------------------------------
-// mixing transactional object smart pointer providing
-// typycal smart pointer operators +
+// smart pointer providing typycal smart pointer operators +
 // a transparent transactional view on a transactional context.
 // a non-transactional view on a non-transactional context
 // Note: the sizeof(pointer<T>)>>>>=sizeof(T*)
 //-----------------------------------------------------------------------------
 template <typename T>
-class pointer : public object< pointer<T> ,T* >
+class pointer : public mixin< pointer<T> ,T* >
 {
- typedef object< pointer<T> , T* > base_type;
+ typedef mixin< pointer<T> , T* > base_type;
     
 public:
     //-----------------------------------------------------------------------------
@@ -59,9 +58,9 @@
 };
 
 template <typename C, typename R>
-class pointer_to_member : public transaction_object< pointer_to_member<C,R> >
+class pointer_to_member : public mixin< pointer_to_member<C,R>, R C::*>
 {
- typedef object< pointer_to_member<C,R> ,R C::*> base_type;
+ typedef mixin< pointer_to_member<C,R>, R C::*> base_type;
 public:
     //-----------------------------------------------------------------------------
     pointer_to_member() : base_type(static_cast<R C::*>(0)) {}

Modified: sandbox/stm/branches/vbe/libs/stm/example/non_tx_counter.cpp
==============================================================================
--- sandbox/stm/branches/vbe/libs/stm/example/non_tx_counter.cpp (original)
+++ sandbox/stm/branches/vbe/libs/stm/example/non_tx_counter.cpp 2009-11-07 17:40:51 EST (Sat, 07 Nov 2009)
@@ -28,7 +28,7 @@
     thread_initializer thi;
 
     BOOST_STM_ATOMIC(_) {
- non_tx::wr_ptr<int> tx_counter(t, counter);
+ non_tx::wr_ptr<int> tx_counter(_, counter);
         ++(*tx_counter);
     } BOOST_STM_END_ATOMIC
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk