[Avida-SVN] r1381 - in development: Avida.xcodeproj source/analyze source/drivers source/main source/targets/avida-viewer source/tools

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Sat Mar 3 16:20:47 PST 2007


Author: brysonda
Date: 2007-03-03 19:20:46 -0500 (Sat, 03 Mar 2007)
New Revision: 1381

Added:
   development/source/tools/cConditionVariable.h
   development/source/tools/cMutex.h
   development/source/tools/cRWLock.h
   development/source/tools/platform.h
Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/source/analyze/cAnalyze.h
   development/source/analyze/cAnalyzeJobQueue.cc
   development/source/analyze/cAnalyzeJobQueue.h
   development/source/analyze/cAnalyzeJobWorker.cc
   development/source/analyze/cMutationalNeighborhood.cc
   development/source/analyze/cMutationalNeighborhood.h
   development/source/drivers/cDriverManager.cc
   development/source/drivers/cDriverManager.h
   development/source/main/cTaskLib.cc
   development/source/targets/avida-viewer/cAnalyzeScreen.cc
   development/source/targets/avida-viewer/cTextWindow.h
   development/source/targets/avida-viewer/cView.cc
   development/source/tools/cDataFileManager.cc
   development/source/tools/cRandom.cc
   development/source/tools/cRandom.h
   development/source/tools/cThread.cc
   development/source/tools/cThread.h
   development/source/tools/cTools.cc
   development/source/tools/tList.h
   development/source/tools/tObjectFactory.h
Log:
Implement a full complement of wrapper objects for various threading constructs, include cMutex, cConditionVariable, and cRWLock.  All of these, as well as cThread itself now, have been written to support three different compile modes (pthread, Windows threads, and disabled).   The code for Windows threading has been written, but it is impossible to test it at the moment as some of the features require Windows Vista (earlier version do not support conds or rwlocks).   The default on windows is to still disable threading, but using the new wrapper objects rather than pthread construct overrides.

Add platform.h to tools.  This header file handles determining various platform features so that outside of it conditional compilation can be standardized on the macro function AVIDA_PLATFORM(FEATURE).   For example, to test if Avida is being compiled on windows #if AVIDA_PLATFORM(WINDOWS).

Fix cAnalyze::m_ctx so that it is a reference rather than a copy.  This should fix all of the LandscapeActions so that they work on batches in analyze mode, as expected.

Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/Avida.xcodeproj/project.pbxproj	2007-03-04 00:20:46 UTC (rev 1381)
@@ -443,6 +443,10 @@
 		7005A70109BA0FA90007E16E /* cTestCPUInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cTestCPUInterface.h; sourceTree = "<group>"; };
 		7005A70209BA0FA90007E16E /* cTestCPUInterface.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cTestCPUInterface.cc; sourceTree = "<group>"; };
 		7005A70909BA0FBE0007E16E /* cOrgInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgInterface.h; sourceTree = "<group>"; };
+		7009DF370B991AC100070F8F /* cMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cMutex.h; sourceTree = "<group>"; };
+		7009DF400B991C6200070F8F /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform.h; sourceTree = "<group>"; };
+		7009E09D0B9A29BC00070F8F /* cConditionVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cConditionVariable.h; sourceTree = "<group>"; };
+		7009E0C50B9A2FAC00070F8F /* cRWLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cRWLock.h; sourceTree = "<group>"; };
 		700AE91B09DB65F200A073FD /* cTaskContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cTaskContext.h; sourceTree = "<group>"; };
 		700E11BC0A0815B600B604CD /* cDataEntry.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cDataEntry.cc; sourceTree = "<group>"; };
 		700E12610A097A0800B604CD /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
@@ -1599,6 +1603,10 @@
 				70BCB21C0AB7ADA6003FF331 /* cArgContainer.cc */,
 				70BCB2470AB7B634003FF331 /* cArgSchema.h */,
 				703D4D6D0ABA374A0032C8A0 /* cArgSchema.cc */,
+				7009DF370B991AC100070F8F /* cMutex.h */,
+				7009DF400B991C6200070F8F /* platform.h */,
+				7009E09D0B9A29BC00070F8F /* cConditionVariable.h */,
+				7009E0C50B9A2FAC00070F8F /* cRWLock.h */,
 			);
 			path = tools;
 			sourceTree = "<group>";

Modified: development/source/analyze/cAnalyze.h
===================================================================
--- development/source/analyze/cAnalyze.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/analyze/cAnalyze.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -114,7 +114,7 @@
   cWorld* m_world;
   cInstSet& inst_set;
   cTestCPU* m_testcpu;
-  cAvidaContext m_ctx;
+  cAvidaContext& m_ctx;
   cAnalyzeJobQueue m_jobqueue;
 
   // This is the storage for the resource information from resource.dat.  It 

Modified: development/source/analyze/cAnalyzeJobQueue.cc
===================================================================
--- development/source/analyze/cAnalyzeJobQueue.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/analyze/cAnalyzeJobQueue.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -3,7 +3,7 @@
  *  Avida
  *
  *  Created by David on 2/18/06.
- *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *  Copyright 2006-2007 Michigan State University. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or
@@ -39,10 +39,6 @@
     m_rng_pool[i] = new cRandomMT(world->GetRandom().GetInt(0x7FFFFFFF));
   }
   
-  pthread_mutex_init(&m_mutex, NULL);
-  pthread_cond_init(&m_cond, NULL);
-  pthread_cond_init(&m_term_cond, NULL);
-
   for (int i = 0; i < m_workers.GetSize(); i++) {
     m_workers[i] = new cAnalyzeJobWorker(this);
     m_workers[i]->Start();
@@ -53,7 +49,7 @@
 {
   const int num_workers = m_workers.GetSize();
   
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   
   // Clean out any waiting jobs
   cAnalyzeJob* job;
@@ -62,37 +58,33 @@
   // Set job count so that all workers receive NULL jobs
   m_jobs = num_workers;
   
-  pthread_mutex_unlock(&m_mutex);
+  m_mutex.Unlock();
   
   // Signal all workers to check job queue
-  pthread_cond_broadcast(&m_cond);
+  m_cond.Broadcast();
   
   for (int i = 0; i < num_workers; i++) {
     m_workers[i]->Join();
     delete m_workers[i];
   }
-  
-  pthread_mutex_destroy(&m_mutex);
-  pthread_cond_destroy(&m_cond);
 }
 
 void cAnalyzeJobQueue::AddJob(cAnalyzeJob* job)
 {
-  pthread_mutex_lock(&m_mutex);
+  cMutexAutoLock lock(m_mutex);
   job->SetID(m_last_jobid++);
   m_queue.PushRear(job);
   m_jobs++;
-  pthread_mutex_unlock(&m_mutex);
 }
 
 void cAnalyzeJobQueue::AddJobImmediate(cAnalyzeJob* job)
 {
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   job->SetID(m_last_jobid++);
   m_queue.PushRear(job);
   m_jobs++;
-  pthread_mutex_unlock(&m_mutex);
-  pthread_cond_signal(&m_cond);
+  m_mutex.Unlock(); // should unlock prior to signaling condition variable
+  m_cond.Signal();
 }
 
 
@@ -101,7 +93,7 @@
   if (m_world->GetVerbosity() >= VERBOSE_DETAILS)
     m_world->GetDriver().NotifyComment("waking worker threads...");
 
-  pthread_cond_broadcast(&m_cond);
+  m_cond.Broadcast();
 }
 
 
@@ -110,14 +102,14 @@
   if (m_world->GetVerbosity() >= VERBOSE_DETAILS)
     m_world->GetDriver().NotifyComment("waking worker threads...");
 
-  pthread_cond_broadcast(&m_cond);
+  m_cond.Broadcast();
   
   // Wait for term signal
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   while (m_jobs > 0 || m_pending > 0) {
-    pthread_cond_wait(&m_term_cond, &m_mutex);
+    m_term_cond.Wait(m_mutex);
   }
-  pthread_mutex_unlock(&m_mutex);
+  m_mutex.Unlock();
 
   if (m_world->GetVerbosity() >= VERBOSE_DETAILS)
     m_world->GetDriver().NotifyComment("job queue complete");

Modified: development/source/analyze/cAnalyzeJobQueue.h
===================================================================
--- development/source/analyze/cAnalyzeJobQueue.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/analyze/cAnalyzeJobQueue.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -28,18 +28,22 @@
 #ifndef cAnalyzeJob
 #include "cAnalyzeJob.h"
 #endif
+#ifndef cConditionVariable_h
+#include "cConditionVariable.h"
+#endif
+#ifndef cMutex_h
+#include "cMutex.h"
+#endif
+#ifndef cRandom_h
+#include "cRandom.h"
+#endif
 #ifndef tArray_h
 #include "tArray.h"
 #endif
 #ifndef tList_h
 #include "tList.h"
 #endif
-#ifndef cRandom_h
-#include "cRandom.h"
-#endif
 
-#include <pthread.h>
-
 class cAnalyzeJobWorker;
 class cWorld;
 
@@ -57,11 +61,11 @@
   tList<cAnalyzeJob> m_queue;
   int m_last_jobid;
   cRandomMT* m_rng_pool[MT_RANDOM_POOL_SIZE];
-  pthread_mutex_t m_mutex;
-  pthread_cond_t m_cond;
-  pthread_cond_t m_term_cond;
+  cMutex m_mutex;
+  cConditionVariable m_cond;
+  cConditionVariable m_term_cond;
   
-  volatile int m_jobs;      // count of waiting jobs, used in pthread_cond constructs
+  volatile int m_jobs;      // count of waiting jobs, used in condition variable constructs
   volatile int m_pending;   // count of currently executing jobs
   
   tArray<cAnalyzeJobWorker*> m_workers;

Modified: development/source/analyze/cAnalyzeJobWorker.cc
===================================================================
--- development/source/analyze/cAnalyzeJobWorker.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/analyze/cAnalyzeJobWorker.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -36,33 +36,31 @@
   cAnalyzeJob* job = NULL;
   
   while (1) {
-    pthread_mutex_lock(&m_queue->m_mutex);
+    m_queue->m_mutex.Lock();
     while (m_queue->m_jobs == 0) {
-      pthread_cond_wait(&m_queue->m_cond, &m_queue->m_mutex);
+      m_queue->m_cond.Wait(m_queue->m_mutex);
     }
     job = m_queue->m_queue.Pop();
     m_queue->m_jobs--;
     m_queue->m_pending++; 
-    pthread_mutex_unlock(&m_queue->m_mutex);
+    m_queue->m_mutex.Unlock();
     
     if (job) {
       // Set RNG from the waiting pool and execute the job
       ctx.SetRandom(m_queue->GetRandom(job->GetID()));
       job->Run(ctx);
       delete job;
-      pthread_mutex_lock(&m_queue->m_mutex);
+      m_queue->m_mutex.Lock();
       int pending = --m_queue->m_pending;
-      pthread_mutex_unlock(&m_queue->m_mutex);
-      if (!pending) pthread_cond_signal(&m_queue->m_term_cond);
+      m_queue->m_mutex.Unlock();
+      if (!pending) m_queue->m_term_cond.Signal();
     } else {
       // Terminate worker on NULL job receipt
-      pthread_mutex_lock(&m_queue->m_mutex);
+      m_queue->m_mutex.Lock();
       int pending = --m_queue->m_pending;
-      pthread_mutex_unlock(&m_queue->m_mutex);
-      if (!pending) pthread_cond_signal(&m_queue->m_term_cond);
+      m_queue->m_mutex.Unlock();
+      if (!pending) m_queue->m_term_cond.Signal();
       break;
     }
   }
-  
-  pthread_exit(NULL);
 }

Modified: development/source/analyze/cMutationalNeighborhood.cc
===================================================================
--- development/source/analyze/cMutationalNeighborhood.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/analyze/cMutationalNeighborhood.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -44,10 +44,10 @@
 
 void cMutationalNeighborhood::Process(cAvidaContext& ctx)
 {
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   if (m_initialized) {
     int cur_site = m_cur_site++;
-    pthread_mutex_unlock(&m_mutex);
+    m_mutex.Unlock();
 
     if (cur_site < m_base_genome.GetSize()) {
       // Create test infrastructure
@@ -77,9 +77,9 @@
     return;
   }
   
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   if (++m_completed == m_base_genome.GetSize()) ProcessComplete(ctx); 
-  pthread_mutex_unlock(&m_mutex);
+  m_mutex.Unlock();
 }
 
 
@@ -115,7 +115,7 @@
   
   // Unlock internal mutex (was locked on Process() entrance)
   //  - will allow workers to begin processing if job queue already active
-  pthread_mutex_unlock(&m_mutex);
+  m_mutex.Unlock();
   
   // Load enough jobs to process all sites
   cAnalyzeJobQueue& jobqueue = m_world->GetAnalyze().GetJobQueue();

Modified: development/source/analyze/cMutationalNeighborhood.h
===================================================================
--- development/source/analyze/cMutationalNeighborhood.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/analyze/cMutationalNeighborhood.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -28,6 +28,9 @@
 #ifndef cGenome_h
 #include "cGenome.h"
 #endif
+#ifndef cMutex_h
+#include "cMutex.h"
+#endif
 #ifndef cString_h
 #include "cString.h"
 #endif
@@ -62,7 +65,7 @@
   // Internal state information
   // --------------------------------------------------------------------------
   pthread_rwlock_t m_rwlock;
-  pthread_mutex_t m_mutex;
+  cMutex m_mutex;
   
   bool m_initialized;
   int m_cur_site;
@@ -189,7 +192,6 @@
   : m_world(world), m_initialized(false), m_inst_set(inst_set), m_target(target), m_base_genome(genome)
   {
     pthread_rwlock_init(&m_rwlock, NULL);
-    pthread_mutex_init(&m_mutex, NULL);
     
     // Acquire write lock, to prevent any Results instances before computing
     pthread_rwlock_wrlock(&m_rwlock);
@@ -197,7 +199,6 @@
   ~cMutationalNeighborhood()
   {
     pthread_rwlock_destroy(&m_rwlock);
-    pthread_mutex_destroy(&m_mutex);
   }
   
   void Process(cAvidaContext& ctx);

Modified: development/source/drivers/cDriverManager.cc
===================================================================
--- development/source/drivers/cDriverManager.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/drivers/cDriverManager.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -36,7 +36,6 @@
 
 cDriverManager::cDriverManager()
 {
-  pthread_mutex_init(&m_mutex, NULL);
   m_actlib = cActionLibrary::ConstructDefaultActionLibrary();
 }
 
@@ -53,8 +52,6 @@
   }
   
   delete m_actlib;
-  
-  pthread_mutex_destroy(&m_mutex);
 }
 
 void cDriverManager::Initialize()
@@ -76,33 +73,33 @@
 void cDriverManager::Register(cAvidaDriver* drv)
 {
   assert(m_dm);
-  pthread_mutex_lock(&m_dm->m_mutex);
+  m_dm->m_mutex.Lock();
   m_dm->m_adrvs.Push(drv);
-  pthread_mutex_unlock(&m_dm->m_mutex);
+  m_dm->m_mutex.Unlock();
 }
 
 void cDriverManager::Register(cWorldDriver* drv)
 {
   assert(m_dm);
-  pthread_mutex_lock(&m_dm->m_mutex);
+  m_dm->m_mutex.Lock();
   m_dm->m_wdrvs.Push(drv);
-  pthread_mutex_unlock(&m_dm->m_mutex);
+  m_dm->m_mutex.Unlock();
 }
 
 void cDriverManager::Unregister(cAvidaDriver* drv)
 {
   assert(m_dm);
-  pthread_mutex_lock(&m_dm->m_mutex);
+  m_dm->m_mutex.Lock();
   m_dm->m_adrvs.Remove(drv);
-  pthread_mutex_unlock(&m_dm->m_mutex);
+  m_dm->m_mutex.Unlock();
 }
 
 void cDriverManager::Unregister(cWorldDriver* drv)
 {
   assert(m_dm);
-  pthread_mutex_lock(&m_dm->m_mutex);
+  m_dm->m_mutex.Lock();
   m_dm->m_wdrvs.Remove(drv);
-  pthread_mutex_unlock(&m_dm->m_mutex);
+  m_dm->m_mutex.Unlock();
 }
 
 cActionLibrary* cDriverManager::GetActionLibrary()

Modified: development/source/drivers/cDriverManager.h
===================================================================
--- development/source/drivers/cDriverManager.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/drivers/cDriverManager.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -28,9 +28,10 @@
 #ifndef tList_h
 #include "tList.h"
 #endif
+#ifndef cMutex_h
+#include "cMutex.h"
+#endif
 
-#include <pthread.h>
-
 class cActionLibrary;
 class cAvidaDriver;
 class cWorldDriver;
@@ -44,7 +45,7 @@
   tList<cAvidaDriver> m_adrvs;
   tList<cWorldDriver> m_wdrvs;
   
-  pthread_mutex_t m_mutex;
+  cMutex m_mutex;
   cActionLibrary* m_actlib;
   
   cDriverManager();

Modified: development/source/main/cTaskLib.cc
===================================================================
--- development/source/main/cTaskLib.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/main/cTaskLib.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -30,12 +30,14 @@
 #include "tHashTable.h"
 #include "cTaskState.h"
 
+#include "platform.h"
+
 #include <cstdlib>
 #include <cmath>
 #include <climits>
 
 // Various workarounds for Visual Studio shortcomings
-#ifdef WIN32
+#if AVIDA_PLATFORM(WINDOWS)
 # define llabs(x) _abs64(x)
 # define log2(x) (log(x)/log(2.0))
 #endif

Modified: development/source/targets/avida-viewer/cAnalyzeScreen.cc
===================================================================
--- development/source/targets/avida-viewer/cAnalyzeScreen.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/targets/avida-viewer/cAnalyzeScreen.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -22,9 +22,11 @@
 #include "cPopulationCell.h"
 #include "cOrganism.h"
 
+#include "platform.h"
+
 #include <csignal>
 
-#ifdef WIN32
+#if AVIDA_PLATFORM(WINDOWS)
 # include <process.h>
 # define kill(x, y)
 #else

Modified: development/source/targets/avida-viewer/cTextWindow.h
===================================================================
--- development/source/targets/avida-viewer/cTextWindow.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/targets/avida-viewer/cTextWindow.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -19,6 +19,9 @@
 #ifndef cBaseTextWindow_h
 #include "cBaseTextWindow.h"
 #endif
+#ifndef platform_h
+#include "platform.h"
+#endif
 
 #include <csignal>
 #include <cstdarg>
@@ -69,7 +72,7 @@
 
   // These function return the number of characters wide or high
   // (respectively) that the screen is.
-#ifdef WIN32
+#if AVIDA_PLATFROM(WINDOWS)
   // Windows returns the screen width and height
   inline int Width() { return win_id->_maxx; }
   inline int Height() { return win_id->_maxy; }

Modified: development/source/targets/avida-viewer/cView.cc
===================================================================
--- development/source/targets/avida-viewer/cView.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/targets/avida-viewer/cView.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -29,10 +29,12 @@
 #include "cEnvironmentScreen.h"
 #include "cAnalyzeScreen.h"
 
+#include "platform.h"
+
 #include <csignal>
 #include <fstream>
 
-#ifdef WIN32
+#if AVIDA_PLATFORM(WINDOWS)
 # include <process.h>
 # define kill(x, y)
 #else

Added: development/source/tools/cConditionVariable.h
===================================================================
--- development/source/tools/cConditionVariable.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cConditionVariable.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -0,0 +1,123 @@
+/*
+ *  cConditionVariable.h
+ *  Avida
+ *
+ *  Created by David on 3/3/07.
+ *  Copyright 2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  This program 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; version 2
+ *  of the License.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef cConditionVariable_h
+#define cConditionVariable_h
+
+#ifndef cMutex_h
+#include "cMutex.h"
+#endif
+#ifndef platform_h
+#include "platform.h"
+#endif
+
+
+#if AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(UNIX)
+
+// Use POSIX Threads
+# include <pthread.h>
+
+class cConditionVariable
+{
+private:
+  pthread_cond_t m_cond;
+  
+  cConditionVariable(const cConditionVariable&); // @not_implemented
+  cConditionVariable& operator=(const cConditionVariable&); // @not_implemented
+  
+  
+public:
+  inline cConditionVariable() { pthread_cond_init(&m_cond, NULL); }
+  inline ~cConditionVariable() { pthread_cond_destroy(&m_cond); }
+
+#ifdef DEBUG
+  void Wait(cMutex& mutex)
+  {
+    mutex.m_locked = false;
+    pthread_cond_wait(&m_cond, &(mutex.m_mutex));
+    mutex.m_locked = true;
+  }
+#else
+  inline void Wait(cMutex& mutex) { pthread_cond_wait(&m_cond, &(mutex.m_mutex)); }
+#endif
+  
+  inline void Signal() { pthread_cond_signal(&m_cond); }
+  inline void Broadcast() { pthread_cond_broadcast(&m_cond); }
+};
+
+#elif AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(WINDOWS)
+
+// Use Windows Threading
+# include <windows.h>
+class cConditionVariable
+{
+private:
+  CONDITION_VARIABLE m_cond;
+  
+  cConditionVariable(const cConditionVariable&); // @not_implemented
+  cConditionVariable& operator=(const cConditionVariable&); // @not_implemented
+  
+  
+public:
+  inline cConditionVariable() { InitializeConditionVariable(&m_cond); }
+  inline ~cConditionVariable() { ; }
+
+#ifdef DEBUG
+  void Wait(cMutex& mutex)
+  {
+    mutex.m_locked = false;
+    SleepConditionVariableCS(&m_cond, &(mutex.m_mutex));
+    mutex.m_locked = true;
+  }
+#else
+  inline void Wait(cMutex& mutex) { SleepConditionVariableCS(&m_cond, &(mutex.m_mutex)); }
+#endif
+  
+  inline void Signal() { WakeConditionVariable(&m_cond); }
+  inline void Broadcast() { WakeAllConditionVariable(&m_cond); }
+};
+
+
+#else
+
+// Disable Threading
+class cConditionVariable
+{
+private:
+  cConditionVariable(const cConditionVariable&); // @not_implemented
+  cConditionVariable& operator=(const cConditionVariable&); // @not_implemented
+  
+public:
+  inline cConditionVariable() { ; }
+  inline ~cConditionVariable() { ; }
+  
+  inline void Wait(cMutex& mutex) { ; }
+  
+  inline void Signal() { ; }
+  inline void Broadcast() { ; }
+};
+
+#endif
+
+#endif

Modified: development/source/tools/cDataFileManager.cc
===================================================================
--- development/source/tools/cDataFileManager.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cDataFileManager.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -11,8 +11,9 @@
 #include "cDataFileManager.h"
 
 #include "cTools.h"
+#include "platform.h"
 
-#ifdef WIN32
+#if AVIDA_PLATFORM(WINDOWS)
 # include <direct.h>
 #else
 # include <unistd.h>

Added: development/source/tools/cMutex.h
===================================================================
--- development/source/tools/cMutex.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cMutex.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -0,0 +1,207 @@
+/*
+ *  cMutex.h
+ *  Avida
+ *
+ *  Created by David on 3/2/07.
+ *  Copyright 2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  This program 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; version 2
+ *  of the License.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef cMutex_h
+#define cMutex_h
+
+#ifndef platform_h
+#include "platform.h"
+#endif
+
+
+#if AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(UNIX)
+
+// Use POSIX Threads
+# include <pthread.h>
+
+#ifdef DEBUG
+# define PTHREAD_MUTEX_CHKRTN(OP) \
+  { \
+    int ret = OP; \
+    ASSERT_MSG(ret == 0, "OP failed"); \
+  }
+#else
+# define PTHREAD_MUTEX_CHKRTN(OP) OP
+#endif
+
+class cMutex
+{
+  friend class cConditionVariable;
+private:
+  pthread_mutex_t m_mutex;
+#ifdef DEBUG
+  bool m_locked;
+#endif
+  
+  cMutex(const cMutex&); // @not_implemented
+  cMutex& operator=(const cMutex&); // @not_implemented
+  
+
+public:
+#ifdef DEBUG
+  cMutex() : m_locked(false) { PTHREAD_MUTEX_CHKRTN(pthread_mutex_init(&m_mutex, NULL)); }
+#else
+  inline cMutex() { PTHREAD_MUTEX_CHKRTN(pthread_mutex_init(&m_mutex, NULL)); }
+#endif
+  
+  inline ~cMutex()
+  {
+    ASSERT_MSG(!m_locked, "destroying locked mutex");
+    PTHREAD_MUTEX_CHKRTN(pthread_mutex_destroy(&m_mutex));
+  }
+
+#ifdef DEBUG
+  void Lock()
+  {
+    PTHREAD_MUTEX_CHKRTN(pthread_mutex_lock(&m_mutex));
+    m_locked = true;
+  }
+#else
+  inline void Lock() { PTHREAD_MUTEX_CHKRTN(pthread_mutex_lock(&m_mutex)); }
+#endif
+
+#ifdef DEBUG
+  void Unlock()
+  {
+    ASSERT_MSG(m_locked, "mutex not locked");
+    PTHREAD_MUTEX_CHKRTN(pthread_mutex_unlock(&m_mutex));
+    m_locked = false;
+  }
+#else
+  inline void Unlock() { PTHREAD_MUTEX_CHKRTN(pthread_mutex_unlock(&m_mutex)); }
+#endif
+};
+
+#elif AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(WINDOWS)
+
+// Use Windows Threading
+# include <windows.h>
+
+class cMutex
+{
+  friend class cConditionVariable;
+private:
+  CRITICAL_SECTION m_mutex;
+#ifdef DEBUG
+  bool m_locked;
+#endif
+  
+  cMutex(const cMutex&); // @not_implemented
+  cMutex& operator=(const cMutex&); // @not_implemented
+  
+  
+public:
+#ifdef DEBUG
+  cMutex() : m_locked(false) { InitializeCriticalSection(&m_mutex); }
+#else
+  inline cMutex() { InitializeCriticalSection(&m_mutex); }
+#endif
+  
+  inline ~cMutex()
+  {
+    ASSERT_MSG(!m_locked, "destroying locked mutex");
+    DeleteCriticalSection(&m_mutex);
+  }
+  
+#ifdef DEBUG
+  void Lock()
+  {
+    EnterCriticalSection(&m_mutex);
+    m_locked = true;
+  }
+#else
+  inline void Lock() { EnterCriticalSection(&m_mutex); }
+#endif
+  
+#ifdef DEBUG
+  void Unlock()
+  {
+    ASSERT_MSG(m_locked, "mutex not locked");
+    LeaveCriticalSection(&m_mutex);
+    m_locked = false;
+  }
+#else
+  inline void Unlock() { LeaveCriticalSection(&m_mutex); }
+#endif
+};
+
+
+#else
+
+// Disable Threading
+class cMutex
+{
+private:
+#ifdef DEBUG
+  bool m_locked;
+#endif
+  
+  cMutex(const cMutex&); // @not_implemented
+  cMutex& operator=(const cMutex&); // @not_implemented
+  
+  
+public:
+#ifdef DEBUG
+  cMutex() : m_locked(false) { ; }
+#else
+  inline cMutex() { ; }
+#endif
+  
+  inline ~cMutex() { ASSERT_MSG(!m_locked, "destroying locked mutex"); }
+  
+#ifdef DEBUG
+  void Lock() { m_locked = true; }
+#else
+  inline void Lock() { ; }
+#endif
+  
+#ifdef DEBUG
+  void Unlock()
+  {
+    ASSERT_MSG(m_locked, "mutex not locked");
+    m_locked = false;
+  }
+#else
+  inline void Unlock() { ; }
+#endif  
+};
+
+#endif
+
+
+class cMutexAutoLock
+{
+private:
+  cMutex& m_mutex;
+  
+  cMutexAutoLock(); // @not_implemented
+  cMutexAutoLock(const cMutexAutoLock&); // @not_implemented
+  cMutexAutoLock& operator=(const cMutexAutoLock&); // @not_implemented
+  
+public:
+  inline explicit cMutexAutoLock(cMutex& mutex) : m_mutex(mutex) { m_mutex.Lock(); }
+  inline ~cMutexAutoLock() { m_mutex.Unlock(); }
+};
+  
+#endif

Added: development/source/tools/cRWLock.h
===================================================================
--- development/source/tools/cRWLock.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cRWLock.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -0,0 +1,103 @@
+/*
+ *  cRWLock.h
+ *  Avida
+ *
+ *  Created by David on 3/3/07.
+ *  Copyright 2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  This program 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; version 2
+ *  of the License.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef cRWLock_h
+#define cRWLock_h
+
+#ifndef platform_h
+#include "platform.h"
+#endif
+
+
+#if AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(UNIX)
+
+// Use POSIX Threads
+# include <pthread.h>
+
+class cRWLock
+{
+private:
+  pthread_rwlock_t m_rwlock;
+  
+  cRWLock(const cRWLock&); // @not_implemented
+  cRWLock& operator=(const cRWLock&); // @not_implemented
+  
+public:
+  inline cRWLock() { pthread_rwlock_init(&m_rwlock, NULL); }
+  inline ~cRWLock() { pthread_rwlock_destroy(&m_rwlock); }
+
+  inline void ReadLock() { pthread_rwlock_rdlock(&m_rwlock); }
+  inline void ReadUnlock() { pthread_rwlock_unlock(&m_rwlock); }  
+
+  inline void WriteLock() { pthread_rwlock_wrlock(&m_rwlock); }
+  inline void WriteUnlock() { pthread_rwlock_unlock(&m_rwlock); }  
+};
+
+#elif AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(WINDOWS)
+
+// Use Windows Threading
+# include <windows.h>
+
+class cRWLock
+{
+private:
+  SRWLOCK m_rwlock;
+  
+  cRWLock(const cRWLock&); // @not_implemented
+  cRWLock& operator=(const cRWLock&); // @not_implemented
+  
+public:
+  inline cRWLock() { InitializeSRWLock(&m_rwlock); }
+  inline ~cRWLock() { ; }
+  
+  inline void ReadLock() { AcquireSRWLockShared(&m_rwlock); }
+  inline void ReadUnlock() { ReleaseSRWLockShared(&m_rwlock); }  
+
+  inline void WriteLock() { AcquireSRWLockExclusive(&m_rwlock); }
+  inline void WriteUnlock() { ReleaseSRWLockExclusive(&m_rwlock); }  
+};
+
+
+
+#else
+
+class cRWLock
+{
+private:
+  cRWLock(const cRWLock&); // @not_implemented
+  cRWLock& operator=(const cRWLock&); // @not_implemented
+  
+public:
+  inline cRWLock() { ; }
+  inline ~cRWLock() { ; }
+  
+  inline void ReadLock() { ; }
+  inline void ReadUnlock() { ; }  
+  
+  inline void WriteLock() { ; }
+  inline void WriteUnlock() { ; }  
+};
+
+
+#endif

Modified: development/source/tools/cRandom.cc
===================================================================
--- development/source/tools/cRandom.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cRandom.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -10,9 +10,10 @@
 
 #include "cRandom.h"
 
+#include "platform.h"
 #include "tArray.h"
 
-#ifdef WIN32
+#if AVIDA_PLATFORM(WINDOWS)
 # include <process.h>
 #else
 # include <unistd.h>
@@ -71,9 +72,8 @@
 
 void cRandomMT::ResetSeed(const int in_seed)
 {
-  pthread_mutex_lock(&m_mutex);
+  cMutexAutoLock lock(m_mutex);
   cRandom::ResetSeed(in_seed);
-  pthread_mutex_unlock(&m_mutex);
 }
 
 
@@ -130,9 +130,8 @@
 
 unsigned int cRandomMT::Get()
 {
-  pthread_mutex_lock(&m_mutex);
+  cMutexAutoLock lock(m_mutex);
   unsigned int value = cRandom::Get();
-  pthread_mutex_unlock(&m_mutex);
   return value;
 }
 
@@ -161,14 +160,14 @@
   // Using Rejection Method and saving of initial exponential random variable
   double expRV2;
   
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   while (1) {
     expRV2 = -log(cRandom::Get() * _RAND_FAC);
     expRV -= (expRV2-1)*(expRV2-1)/2;
     if (expRV > 0) break;
     expRV = -log(cRandom::Get() * _RAND_FAC);
   }
-  pthread_mutex_unlock(&m_mutex);
+  m_mutex.Unlock();
   
   if (P(.5)) 
     return expRV2;

Modified: development/source/tools/cRandom.h
===================================================================
--- development/source/tools/cRandom.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cRandom.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -11,6 +11,10 @@
 #ifndef cRandom_h
 #define cRandom_h
 
+#ifndef cMutex_h
+#include "cMutex.h"
+#endif
+
 #if USE_tMemTrack
 # ifndef tMemTrack_h
 #  include "tMemTrack.h"
@@ -20,7 +24,6 @@
 #include <ctime>
 #include <climits>
 #include <cmath>
-#include <pthread.h>
 
 /**
  * A versatile and fast pseudo random number generator.
@@ -244,13 +247,13 @@
 class cRandomMT : public cRandom
 {
 private:
-  pthread_mutex_t m_mutex;
+  cMutex m_mutex;
   
   unsigned int Get();
 
 public:
-  cRandomMT(const int in_seed = -1) : cRandom(in_seed) { pthread_mutex_init(&m_mutex, NULL); }
-  ~cRandomMT() { pthread_mutex_destroy(&m_mutex); }
+  cRandomMT(const int in_seed = -1) : cRandom(in_seed) { ; }
+  ~cRandomMT() { ; }
 
   void ResetSeed(const int in_seed);
 

Modified: development/source/tools/cThread.cc
===================================================================
--- development/source/tools/cThread.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cThread.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -24,58 +24,43 @@
 
 #include "cThread.h"
 
-cThread::~cThread()
-{
-  pthread_mutex_destroy(&m_mutex);
-#ifndef WIN32_PTHREAD_HACK
-  if (m_running) pthread_detach(m_thread);
-#endif
-}
+#if AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(UNIX)
 
+cThread::~cThread() { if (m_running) pthread_detach(m_thread); }
 
-int cThread::Start()
+bool cThread::Start()
 {
-  int rval = 0;
-  
-  pthread_mutex_lock(&m_mutex);
+  m_mutex.Lock();
   if (!m_running) {
     m_running = true;
-    pthread_mutex_unlock(&m_mutex);
+    m_mutex.Unlock();
 
-#ifndef WIN32_PTHREAD_HACK
     // Create thread, mark as running when successful
-    rval = pthread_create(&m_thread, NULL, &cThread::EntryPoint, this);
+    int rval = pthread_create(&m_thread, NULL, &cThread::EntryPoint, this);
     if (rval) m_running = false;
-#else
-    Run();
-#endif
   } else {
-    pthread_mutex_unlock(&m_mutex);
+    m_mutex.Unlock();
   }
   
-  return rval;
+  return m_running;
 }
 
 void cThread::Stop()
 {
-#ifndef WIN32_PTHREAD_HACK
   if (m_running) {
     // Close and clean up thread, set running to false
     pthread_cancel(m_thread);
     pthread_join(m_thread, NULL);
     m_running = false;
   }
-#endif
 }
 
 void cThread::Join()
 {
-#ifndef WIN32_PTHREAD_HACK
   if (m_running) {
     pthread_join(m_thread, NULL);
     m_running = false;
   }
-#endif
 }
 
 void* cThread::EntryPoint(void* arg)
@@ -85,5 +70,55 @@
   cThread* thread = static_cast<cThread*>(arg);
   thread->Run();
   
+  pthread_exit(NULL);
   return NULL;
 }
+
+
+#elif AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(WINDOWS)
+
+cThread::~cThread() { if (m_thread) CloseHandle(m_thread); }
+
+bool cThread::Start()
+{
+  cMutexAutoLock lock(m_mutex);
+
+  if (m_thread == 0) {
+    unsigned long tid = 0;
+    m_thread = (HANDLE)_beginthreadex(0, 0, &cThread::EntryPoint, this, 0, &tid);
+
+    if (m_thread) return true;
+    return false;
+  }
+  
+  return true;
+}
+
+void cThread::Stop()
+{
+  if (m_thread) {
+    if (CloseHandle(m_thread) == TRUE) {
+      m_thread = 0;
+    }
+  }
+  
+}
+
+void cThread::Join()
+{
+  if (m_thread) WaitForSingleObject(m_thread, INFINITE);
+}
+
+unsigned int __stdcall cThread::EntryPoint(void* arg)
+{
+  // Common entry point to start cThread objects
+  // Calls Run method of appropriate subclass to do the actual work
+  cThread* thread = static_cast<cThread*>(arg);
+  thread->Run();
+
+  _endthreadex(0);
+  return 0;
+}
+
+
+#endif

Modified: development/source/tools/cThread.h
===================================================================
--- development/source/tools/cThread.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cThread.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -3,7 +3,7 @@
  *  Avida
  *
  *  Created by David on 2/18/06.
- *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *  Copyright 2006-2007 Michigan State University. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or
@@ -25,19 +25,25 @@
 #ifndef cThread_h
 #define cThread_h
 
-#ifndef NULL
-#define NULL 0
+#ifndef cMutex_h
+#include "cMutex.h"
 #endif
 
+
+#if AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(UNIX)
+
+// Use POSIX Threads
 #include <pthread.h>
 
 class cThread
 {
 protected:
   pthread_t m_thread;
-  pthread_mutex_t m_mutex;
+  cMutex m_mutex;
   bool m_running;
 
+  void Stop();
+  
   virtual void Run() = 0;
   
   static void* EntryPoint(void* arg);
@@ -46,24 +52,61 @@
   cThread& operator=(const cThread&); // @not_implemented
 
 public:
-  cThread() : m_running(false) { pthread_mutex_init(&m_mutex, NULL); }
+  cThread() : m_running(false) { ; }
   virtual ~cThread();
   
-  int Start();
+  bool Start();
+  void Join();
+};
+
+#elif AVIDA_PLATFORM(THREADS) && AVIDA_PLATFORM(WINDOWS)
+
+// Use Windows Threading
+#include <windows.h>
+
+class cThread
+{
+protected:
+  HANDLE m_thread;
+  cMutex m_mutex;
+  
   void Stop();
+
+  virtual void Run() = 0;
+  
+  static unsigned int __stdcall EntryPoint(void* arg);
+  
+  cThread(const cThread&); // @not_implemented
+  cThread& operator=(const cThread&); // @not_implemented
+  
+public:
+  cThread() : m_thread(0) { ; }
+  virtual ~cThread();
+  
+  bool Start();
   void Join();
 };
 
+#else
 
-#ifdef ENABLE_UNIT_TESTS
-namespace nThread {
-  /**
-   * Run unit tests
-   *
-   * @param full Run full test suite; if false, just the fast tests.
-   **/
-  void UnitTests(bool full = false);
-}
-#endif  
+// Disable Threading
+class cThread
+{
+protected:
+  virtual void Run() = 0;
+  
+  cThread(const cThread&); // @not_implemented
+  cThread& operator=(const cThread&); // @not_implemented
+  
+public:
+  inline cThread() { ; }
+  virtual ~cThread() { ; }
+  
+  inline bool Start() { Run(); return true; }
+  inline void Join() { ; }
+};
 
 #endif
+
+
+#endif

Modified: development/source/tools/cTools.cc
===================================================================
--- development/source/tools/cTools.cc	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/cTools.cc	2007-03-04 00:20:46 UTC (rev 1381)
@@ -16,10 +16,11 @@
 #include <cstdio>
 
 #include "cString.h"
+#include "platform.h"
 
 
-// mkdir undefined in win32
-#ifdef WIN32
+// mkdir undefined in ms windows
+#if AVIDA_PLATFORM(WINDOWS)
 # include <direct.h>
 # ifndef ACCESSPERMS
 #  define ACCESSPERMS 0

Added: development/source/tools/platform.h
===================================================================
--- development/source/tools/platform.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/platform.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -0,0 +1,58 @@
+/*
+ *  platform.h
+ *  Avida
+ *
+ *  Created by David on 3/2/07.
+ *  Copyright 2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  This program 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; version 2
+ *  of the License.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef platform_h
+#define platform_h
+
+#define AVIDA_PLATFORM(PROP) (defined(AVIDA_PLATFORM_##PROP) && AVIDA_PLATFORM_##PROP)
+
+#if defined(WIN32) || defined(_WIN32)
+# define AVIDA_PLATFORM_WINDOWS 1
+# ifdef ENABLE_THREADS
+#  define AVIDA_PLATFORM_THREADS 1
+# else
+#  define AVIDA_PLATFORM_THREADS 0
+# endif
+#endif
+
+#if defined(__APPLE__) || defined(unix) || defined(__unix) || defined(__unix__) || defined (__NetBSD__) || defined(_AIX)
+# define AVIDA_PLATFORM_UNIX 1
+# define AVIDA_PLATFORM_THREADS 1
+#endif
+
+
+#ifdef DEBUG
+# include <cstdlib>
+# include <iostream>
+# define ASSERT_MSG(VALUE, MSG) if (!(VALUE)) { std::cerr << "Error: " << MSG << std::endl; abort(); }
+#else
+# define ASSERT_MSG(VALUE, MSG)
+#endif
+
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#endif

Modified: development/source/tools/tList.h
===================================================================
--- development/source/tools/tList.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/tList.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -32,6 +32,11 @@
 # endif
 #endif
 
+#ifndef platform_h
+#include "platform.h"
+#endif
+
+
 #ifndef NULL
 #define NULL 0
 #endif
@@ -47,7 +52,7 @@
   
 // @DMB - Visual Studio doesn't like usage of 'this' in initializers 
 //        and throws a lot of useless warnings. 
-#ifdef WIN32 
+#if AVIDA_PLATFORM(WINDOWS) 
   tListNode() : data(NULL) { next = this; prev = this; } 
 #else 
   tListNode() : data(NULL), next(this), prev(this) { ; } 

Modified: development/source/tools/tObjectFactory.h
===================================================================
--- development/source/tools/tObjectFactory.h	2007-03-03 21:42:02 UTC (rev 1380)
+++ development/source/tools/tObjectFactory.h	2007-03-04 00:20:46 UTC (rev 1381)
@@ -25,6 +25,9 @@
 #ifndef tObjectFactory_h
 #define tObjectFactory_h
 
+#ifndef cMutex_h
+#include "cMutex.h"
+#endif
 #ifndef tDictionary_h
 #include "tDictionary.h"
 #endif
@@ -35,8 +38,6 @@
 #include "tList.h"
 #endif
 
-#include <pthread.h>
-
 class cString;
 
 
@@ -76,43 +77,38 @@
   typedef BaseType (*CreateObjectFunction)();
   
   tDictionary<CreateObjectFunction> m_create_funcs;
-  mutable pthread_mutex_t m_mutex;
+  mutable cMutex m_mutex;
   
 public:
-  tObjectFactory() { pthread_mutex_init(&m_mutex, NULL); }
-  virtual ~tObjectFactory() { pthread_mutex_destroy(&m_mutex); }
+  tObjectFactory() { ; }
+  virtual ~tObjectFactory() { ; }
 
   template<typename ClassType> bool Register(const cString& key)
   {
+    cMutexAutoLock lock(m_mutex);
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return false;
     }
     
     m_create_funcs.Add(key, &nObjectFactory::createObject<BaseType, ClassType>);
-    pthread_mutex_unlock(&m_mutex);
     return true;
   }
   
   bool Unregister(const cString& key)
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     CreateObjectFunction func = m_create_funcs.Remove(key);
-    pthread_mutex_unlock(&m_mutex);
     return (func != NULL);
   }
   
   virtual BaseType Create(const cString& key)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return func();
     }
-    pthread_mutex_unlock(&m_mutex);
     return NULL;
   }
   
@@ -120,9 +116,8 @@
   {
     tList<cString> names;
     tList<CreateObjectFunction> funcs;
+    cMutexAutoLock lock(m_mutex);
     
-    pthread_mutex_lock(&m_mutex);
-    
     m_create_funcs.AsLists(names, funcs);
     objects.Resize(names.GetSize());
     
@@ -132,15 +127,12 @@
       m_create_funcs.Find(*names_it.Get(), func);
       objects[i] = func();
     }
-
-    pthread_mutex_unlock(&m_mutex);
   }
   
   bool Supports(const cString& key) const
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     bool supports = m_create_funcs.HasEntry(key);
-    pthread_mutex_unlock(&m_mutex);
     return supports;
   }
 };
@@ -152,51 +144,45 @@
   typedef BaseType (*CreateObjectFunction)(Arg1Type);
   
   tDictionary<CreateObjectFunction> m_create_funcs;
-  mutable pthread_mutex_t m_mutex;
+  mutable cMutex m_mutex;
   
 public:
-  tObjectFactory() { pthread_mutex_init(&m_mutex, NULL); }
-  virtual ~tObjectFactory() { pthread_mutex_destroy(&m_mutex); }
+  tObjectFactory() { ; }
+  virtual ~tObjectFactory() { ; }
   
   template<typename ClassType> bool Register(const cString& key)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return false;
     }
     
     m_create_funcs.Add(key, &nObjectFactory::createObject<BaseType, ClassType, Arg1Type>);
-    pthread_mutex_unlock(&m_mutex);
     return true;
   }
   
   bool Unregister(const cString& key)
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     CreateObjectFunction func = m_create_funcs.Remove(key);
-    pthread_mutex_unlock(&m_mutex);
     return (func != NULL);
   }
   
   virtual BaseType Create(const cString& key, Arg1Type arg1)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return func(arg1);
     }
-    pthread_mutex_unlock(&m_mutex);
     return NULL;
   }
 
   bool Supports(const cString& key) const
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     bool supports = m_create_funcs.HasEntry(key);
-    pthread_mutex_unlock(&m_mutex);
     return supports;
   }
 };
@@ -208,51 +194,45 @@
   typedef BaseType (*CreateObjectFunction)(Arg1Type, Arg2Type);
   
   tDictionary<CreateObjectFunction> m_create_funcs;
-  mutable pthread_mutex_t m_mutex;
+  mutable cMutex m_mutex;
   
 public:
-  tObjectFactory() { pthread_mutex_init(&m_mutex, NULL); }
-  virtual ~tObjectFactory() { pthread_mutex_destroy(&m_mutex); }
+  tObjectFactory() { ; }
+  virtual ~tObjectFactory() { ; }
   
   template<typename ClassType> bool Register(const cString& key)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return false;
     }
     
     m_create_funcs.Add(key, &nObjectFactory::createObject<BaseType, ClassType, Arg1Type, Arg2Type>);
-    pthread_mutex_unlock(&m_mutex);
     return true;
   }
   
   bool Unregister(const cString& key)
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     CreateObjectFunction func = m_create_funcs.Remove(key);
-    pthread_mutex_unlock(&m_mutex);
     return (func != NULL);
   }
   
   virtual BaseType Create(const cString& key, Arg1Type arg1, Arg2Type arg2)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return func(arg1, arg2);
     }
-    pthread_mutex_unlock(&m_mutex);
     return NULL;
   }
 
   bool Supports(const cString& key) const
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     bool supports = m_create_funcs.HasEntry(key);
-    pthread_mutex_unlock(&m_mutex);
     return supports;
   }
 };
@@ -264,51 +244,45 @@
   typedef BaseType (*CreateObjectFunction)(Arg1Type, Arg2Type, Arg3Type);
   
   tDictionary<CreateObjectFunction> m_create_funcs;
-  mutable pthread_mutex_t m_mutex;
+  mutable cMutex m_mutex;
   
 public:
-  tObjectFactory() { pthread_mutex_init(&m_mutex, NULL); }
-  virtual ~tObjectFactory() { pthread_mutex_destroy(&m_mutex); }
+  tObjectFactory() { ; }
+  virtual ~tObjectFactory() { ; }
   
   template<typename ClassType> bool Register(const cString& key)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return false;
     }
     
     m_create_funcs.Add(key, &nObjectFactory::createObject<BaseType, ClassType, Arg1Type, Arg2Type, Arg3Type>);
-    pthread_mutex_unlock(&m_mutex);
     return true;
   }
   
   bool Unregister(const cString& key)
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     CreateObjectFunction func = m_create_funcs.Remove(key);
-    pthread_mutex_unlock(&m_mutex);
     return (func != NULL);
   }
   
   virtual BaseType Create(const cString& key, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3)
   {
     CreateObjectFunction func;
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     if (m_create_funcs.Find(key, func)) {
-      pthread_mutex_unlock(&m_mutex);
       return func(arg1, arg2, arg3);
     }
-    pthread_mutex_unlock(&m_mutex);
     return NULL;
   }
 
   bool Supports(const cString& key) const
   {
-    pthread_mutex_lock(&m_mutex);
+    cMutexAutoLock lock(m_mutex);
     bool supports = m_create_funcs.HasEntry(key);
-    pthread_mutex_unlock(&m_mutex);
     return supports;
   }
 };




More information about the Avida-cvs mailing list