[Avida-SVN] r2940 - in development: . Avida.xcodeproj source/tools
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Wed Nov 12 21:10:39 PST 2008
Author: brysonda
Date: 2008-11-13 00:10:38 -0500 (Thu, 13 Nov 2008)
New Revision: 2940
Added:
development/source/tools/cRCObject.cc
development/source/tools/cRCObject.h
development/source/tools/tRCPtr.h
Modified:
development/Avida.xcodeproj/project.pbxproj
development/CMakeLists.txt
development/source/tools/cString.cc
development/source/tools/cString.h
development/source/tools/tAutoRelease.h
Log:
First pass implementation of cRCObject and tRCPtr for creating and managing reference counted objects. Operation should be correct, but not yet thread-safe.
Replace/encapsulate cString's cStringValue reference counting with cRCObject.
Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj 2008-11-13 02:00:06 UTC (rev 2939)
+++ development/Avida.xcodeproj/project.pbxproj 2008-11-13 05:10:38 UTC (rev 2940)
@@ -34,6 +34,8 @@
56F555E70C3B402A00E2E929 /* viewer-text.cc in Sources */ = {isa = PBXBuildFile; fileRef = 56F555E40C3B402A00E2E929 /* viewer-text.cc */; };
700E2996085A1F6000CF158A /* avida in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCC3164D07626CF3008F7A48 /* avida */; };
700E2B87085DE54400CF158A /* avida-viewer in CopyFiles */ = {isa = PBXBuildFile; fileRef = 700E2B83085DE50C00CF158A /* avida-viewer */; };
+ 70211A5D0ECBD531004A293A /* cRCObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 70211A5B0ECBD531004A293A /* cRCObject.h */; };
+ 70211A5E0ECBD531004A293A /* cRCObject.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70211A5C0ECBD531004A293A /* cRCObject.cc */; };
7023EC3A0C0A431B00362B9C /* avida.cc in Sources */ = {isa = PBXBuildFile; fileRef = DCC3109C0762539E008F7A48 /* avida.cc */; };
7023EC3B0C0A431B00362B9C /* cActionLibrary.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051BA0A1F66B400CBB8B6 /* cActionLibrary.cc */; };
7023EC3C0C0A431B00362B9C /* cAnalyze.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70422A1C091B141000A5E67F /* cAnalyze.cc */; };
@@ -407,6 +409,9 @@
701D93E6094CBF71008B845F /* cDefaultAnalyzeDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cDefaultAnalyzeDriver.h; sourceTree = "<group>"; };
701D93E7094CBF71008B845F /* cDefaultAnalyzeDriver.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cDefaultAnalyzeDriver.cc; sourceTree = "<group>"; };
701EF27E0BEA5D2300DAE168 /* main.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cc; sourceTree = "<group>"; };
+ 70211A5B0ECBD531004A293A /* cRCObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cRCObject.h; sourceTree = "<group>"; };
+ 70211A5C0ECBD531004A293A /* cRCObject.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cRCObject.cc; sourceTree = "<group>"; };
+ 70211A6C0ECBDB72004A293A /* tRCPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tRCPtr.h; sourceTree = "<group>"; };
7023EC330C0A426900362B9C /* libavida-core.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libavida-core.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7027621909D73E5900741717 /* cOrgSourceMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgSourceMessage.h; sourceTree = "<group>"; };
7027621A09D73E7700741717 /* cOrgSinkMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgSinkMessage.h; sourceTree = "<group>"; };
@@ -1647,6 +1652,9 @@
70EFD65E0D975B5E00FAD32A /* cConstBurstSchedule.h */,
70EFD65F0D975B5E00FAD32A /* cConstBurstSchedule.cc */,
70B984B40EBB71B500A828B1 /* tDataCommandManager.h */,
+ 70211A5B0ECBD531004A293A /* cRCObject.h */,
+ 70211A5C0ECBD531004A293A /* cRCObject.cc */,
+ 70211A6C0ECBDB72004A293A /* tRCPtr.h */,
);
path = tools;
sourceTree = "<group>";
@@ -1706,6 +1714,7 @@
files = (
2A57A4000D6B954D00FC54C7 /* cProbDemeProbSchedule.h in Headers */,
709A1EEB0EB6C42D006090AF /* cOrgMovementPredicate.h in Headers */,
+ 70211A5D0ECBD531004A293A /* cRCObject.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2060,6 +2069,7 @@
70BB2AE20EA5303F008269D2 /* cDriverStatusConduit.cc in Sources */,
709A1EEC0EB6C42D006090AF /* cResourceHistory.cc in Sources */,
70E60C4B0EC0088300718740 /* cGenotypeBatch.cc in Sources */,
+ 70211A5E0ECBD531004A293A /* cRCObject.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: development/CMakeLists.txt
===================================================================
--- development/CMakeLists.txt 2008-11-13 02:00:06 UTC (rev 2939)
+++ development/CMakeLists.txt 2008-11-13 05:10:38 UTC (rev 2940)
@@ -296,6 +296,7 @@
${TOOLS_DIR}/cProbDemeProbSchedule.cc
${TOOLS_DIR}/cProbSchedule.cc
${TOOLS_DIR}/cRandom.cc
+ ${TOOLS_DIR}/cRCObject.cc
${TOOLS_DIR}/cRunningAverage.cc
${TOOLS_DIR}/cSchedule.cc
${TOOLS_DIR}/cString.cc
Added: development/source/tools/cRCObject.cc
===================================================================
--- development/source/tools/cRCObject.cc (rev 0)
+++ development/source/tools/cRCObject.cc 2008-11-13 05:10:38 UTC (rev 2940)
@@ -0,0 +1,27 @@
+/*
+ * cRCObject.cc
+ * Avida
+ *
+ * Created by David on 11/12/08.
+ * Copyright 2008 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.
+ *
+ */
+
+#include "cRCObject.h"
+
+cRCObject::~cRCObject() { ; }
Added: development/source/tools/cRCObject.h
===================================================================
--- development/source/tools/cRCObject.h (rev 0)
+++ development/source/tools/cRCObject.h 2008-11-13 05:10:38 UTC (rev 2940)
@@ -0,0 +1,49 @@
+/*
+ * cRCObject.h
+ * Avida
+ *
+ * Created by David on 11/12/08.
+ * Copyright 2008 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 cRCObject_h
+#define cRCObject_h
+
+
+class cRCObject
+{
+private:
+ volatile int m_ref_count;
+ volatile bool m_exclusive;
+
+public:
+ cRCObject() : m_ref_count(0), m_exclusive(false) { ; }
+ cRCObject(const cRCObject&) : m_ref_count(0), m_exclusive(false) { ; }
+ virtual ~cRCObject() = 0;
+
+ cRCObject& operator=(const cRCObject&) { return *this; }
+
+ void AddReference() { m_ref_count++; }
+ void RemoveReference() { if (--m_ref_count == 0) delete this; }
+
+ bool SetExclusive() { if (!(m_ref_count > 1)) m_exclusive = true; return m_exclusive; }
+ bool IsExclusive() { return m_exclusive; }
+};
+
+#endif
Modified: development/source/tools/cString.cc
===================================================================
--- development/source/tools/cString.cc 2008-11-13 02:00:06 UTC (rev 2939)
+++ development/source/tools/cString.cc 2008-11-13 05:10:38 UTC (rev 2940)
@@ -34,24 +34,24 @@
// ** class cStringData **
// -- Constructors --
-cString::cStringData::cStringData(int in_size) : m_refs(1), m_size(in_size), m_data(new char[m_size + 1])
+cString::cStringData::cStringData(int in_size) : m_size(in_size), m_data(new char[m_size + 1])
{
assert(m_data != NULL); // Memory Allocation Error: Out of Memory
m_data[0] = '\0';
m_data[m_size] = '\0';
}
-cString::cStringData::cStringData(int in_size, const char* in) : m_refs(1), m_size(in_size), m_data(new char[m_size + 1])
+cString::cStringData::cStringData(int in_size, const char* in) : m_size(in_size), m_data(new char[m_size + 1])
{
assert(m_data != NULL); // Memory Allocation Error: Out of Memory
for (short i = 0; i < m_size; i++) m_data[i] = in[i];
m_data[m_size] = '\0';
}
-cString::cStringData::cStringData(const cStringData& in) : m_refs(1), m_size(in.GetSize()), m_data(new char[m_size + 1])
+cString::cStringData::cStringData(const cStringData& in) : cRCObject(*this), m_size(in.GetSize()), m_data(new char[m_size + 1])
{
assert(m_data != NULL); // Memory Allocation Error: Out of Memory
- for (short i = 0; i < m_size; i++) m_data[i] = in[i];
+ for (int i = 0; i < m_size; i++) m_data[i] = in[i];
m_data[m_size] = '\0';
}
@@ -605,8 +605,8 @@
assert (in_size == 0 || in != NULL); // NULL input string
// Allocate a new string
- cStringData * new_value = new cStringData(GetSize()+in_size);
- assert (new_value != NULL); // Memory Allocation Error: Out of Memory
+ tRCPtr<cStringData> new_value(new cStringData(GetSize() + in_size));
+ assert (new_value); // Memory Allocation Error: Out of Memory
for(int i=0; i<GetSize(); ++i ) { // Copy self up to pos
(*new_value)[i] = this->operator[](i);
}
@@ -614,7 +614,7 @@
assert(in[i] != '\0'); // Input String Contains '\\0' or too Short
(*new_value)[i+GetSize()] = in[i];
}
- TakeValue(new_value); // Reassing data to new data
+ value = new_value; // Reassign data to new data
return(*this);
}
@@ -637,8 +637,8 @@
// Allocate a new string
const int new_size = GetSize() + in_size - excise;
- cStringData * new_value = new cStringData(new_size);
- assert (new_value != NULL); // Memory Allocation Error: Out of Memory
+ tRCPtr<cStringData> new_value(new cStringData(new_size));
+ assert (new_value); // Memory Allocation Error: Out of Memory
for(int i = 0; i < pos; ++i ){ // Copy self up to pos
(*new_value)[i] = this->operator[](i);
@@ -651,8 +651,8 @@
(*new_value)[i+in_size-excise] = this->operator[](i);
}
- TakeValue(new_value); // Reassing data to new data
- return(*this);
+ value = new_value; // Reassign data to new data
+ return *this;
}
@@ -671,8 +671,8 @@
// Allocate a new string
const int new_size = GetSize() - excise;
- cStringData * new_value = new cStringData(new_size);
- assert (new_value != NULL); // Memory Allocation Error: Out of Memory
+ tRCPtr<cStringData> new_value(new cStringData(new_size));
+ assert (new_value); // Memory Allocation Error: Out of Memory
for(int i = 0; i < pos; i++){ // Copy self up to pos
(*new_value)[i] = this->operator[](i);
@@ -681,7 +681,7 @@
(*new_value)[i-excise] = this->operator[](i);
}
- TakeValue(new_value); // Reassing data to new data
+ value = new_value; // Reassign data to new data
return out_string;
}
Modified: development/source/tools/cString.h
===================================================================
--- development/source/tools/cString.h 2008-11-13 02:00:06 UTC (rev 2939)
+++ development/source/tools/cString.h 2008-11-13 05:10:38 UTC (rev 2940)
@@ -32,6 +32,9 @@
#include <cstring>
#include <cassert>
+#include "cRCObject.h"
+#include "tRCPtr.h"
+
#if USE_tMemTrack
# ifndef tMemTrack_h
# include "tMemTrack.h"
@@ -39,7 +42,6 @@
#endif
#define MAX_STRING_LENGTH 4096
-#define MAX_STRING_REF_COUNT 32767
#define CONTINUE_LINE_CHAR '\\'
/**
@@ -82,15 +84,13 @@
friend class cCharProxy; // Telling rvalue vs lvalue ....
// cStringData -- Holds the actual data and is reference count --
- class cStringData
+ class cStringData : public cRCObject
{
// NOTE: Terminating NULL is always there (you can't assign!!)
private:
- short m_refs; // Number of references
int m_size; // size of data (NOT INCLUDING TRAILING NULL)
char* m_data;
-
cStringData(); // @not_implemented
public:
@@ -100,7 +100,6 @@
~cStringData()
{
- assert(m_refs == 0); // Deleting cStringData with References!!
delete [] m_data;
}
@@ -132,58 +131,41 @@
assert(index != m_size); // Cannot Change Terminating NULL
return m_data[index];
}
-
- bool IsShared() { return (m_refs > 1); }
- bool AtMaxRefs() { return (m_refs >= MAX_STRING_REF_COUNT); }
-
- short RemoveRef()
- {
- assert(m_refs > 0); // Reference count corrupted
- return (--m_refs);
- }
-
- cStringData* NewRef() { ++m_refs; return this; }
};
public:
static const int MAX_LENGTH;
- cString(const char* in = "") : value(new cStringData(strlen(in), in))
+ cString(const char* in_str = "") : value(new cStringData(strlen(in_str), in_str))
{
- assert( in != NULL ); // NULL input string
- assert( value != NULL ); // Memory Allocation Error: Out of Memory
+ assert( in_str != NULL ); // NULL input string
+ assert( value ); // Memory Allocation Error: Out of Memory
}
cString(const char* in, int in_size) : value(new cStringData(in_size, in))
{
assert(in_size >= 0);
assert( in != NULL ); // NULL input string
- assert( value != NULL ); // Memory Allocation Error: Out of Memory
+ assert( value ); // Memory Allocation Error: Out of Memory
}
explicit cString(const int size) : value(new cStringData(size))
{
- assert( value != NULL ); // Memory Allocation Error: Out of Memory
+ assert( value ); // Memory Allocation Error: Out of Memory
}
- cString(const cString& in) { CopyString(in); }
+ cString(const cString& in_str) :value(in_str.value) { ; }
- ~cString() { if (value->RemoveRef() == 0) delete value; }
+ ~cString() { ; }
// Cast to const char *
operator const char* () const { return value->GetData(); }
// Assignment Operators
- cString& operator=(const cString & in)
- {
- if( value->RemoveRef() == 0 ) delete value;
- CopyString(in);
- return *this;
- }
+ cString& operator=(const cString& in_str) { value = in_str.value; return *this; }
cString& operator=(const char* in)
{
assert( in != NULL ); // NULL input string
- if( value->RemoveRef() == 0 ) delete value;
value = new cStringData(strlen(in),in);
- assert(value != NULL); // Memory Allocation Error: Out of Memory
+ assert(value); // Memory Allocation Error: Out of Memory
return *this;
}
@@ -588,21 +570,6 @@
protected:
// -- Internal Functions --
- void CopyString(const cString & in) {
- if (in.value->AtMaxRefs() == true) {
- cStringData * old_data = in.value;
- old_data->RemoveRef(); // remove our reference count
- // Copy the _value_ of the old reference. (we need to const-cast here...)
- ( (cString &) in ).value = new cStringData(*old_data);
- }
- value = in.value->NewRef();
- }
-
- void TakeValue(cStringData * new_ref){ // If you made new_value!
- if( value->RemoveRef() == 0 ) delete value;
- value = new_ref;
- }
-
// Methods that take input string size (unsafe to call from outside)
cString & AppendStr(const int in_size, const char * in); // Optimized
cString & InsertStr(const int in_size, const char * in,
@@ -611,7 +578,7 @@
// -- Internal Data --
protected:
- cStringData * value;
+ tRCPtr<cStringData> value;
// }}} End Internals
};
@@ -629,8 +596,7 @@
void cString::CopyOnWrite()
{
- if (value->IsShared()) { // if it is shared
- value->RemoveRef(); // remove our reference count
+ if (!value->SetExclusive()) { // if it is shared
value = new cStringData(*value); // make own copy of value
}
}
Modified: development/source/tools/tAutoRelease.h
===================================================================
--- development/source/tools/tAutoRelease.h 2008-11-13 02:00:06 UTC (rev 2939)
+++ development/source/tools/tAutoRelease.h 2008-11-13 05:10:38 UTC (rev 2940)
@@ -46,7 +46,8 @@
inline bool IsNull() const { return !(m_value); }
//! Access the contents
- inline T& operator*() { return *m_value; }
+ inline T* operator->() const { return m_value; }
+ inline T& operator*() const { return *m_value; }
//! Take control of the contents
inline T* Release() { T* value = m_value; m_value = NULL; return value; }
Added: development/source/tools/tRCPtr.h
===================================================================
--- development/source/tools/tRCPtr.h (rev 0)
+++ development/source/tools/tRCPtr.h 2008-11-13 05:10:38 UTC (rev 2940)
@@ -0,0 +1,75 @@
+/*
+ * tRCPtr.h
+ * Avida
+ *
+ * Created by David on 11/12/08.
+ * Copyright 2008 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 tRCPtr_h
+#define tRCPtr_h
+
+template<class T> class tRCPtr
+{
+private:
+ T* m_ptr;
+
+ void handleNewPointer();
+
+public:
+ tRCPtr(T* ptr = NULL) : m_ptr(ptr) { handleNewPointer(); }
+ tRCPtr(const tRCPtr& rhs) : m_ptr(rhs.m_ptr) { handleNewPointer(); }
+ ~tRCPtr() { if (m_ptr) m_ptr->RemoveReference(); }
+
+ tRCPtr& operator=(const tRCPtr& rhs);
+
+ inline bool operator!() const { return !m_ptr; }
+ inline operator bool() const { return !operator!(); }
+
+ inline T* operator->() const { return m_ptr; }
+ inline T& operator*() const { return *m_ptr; }
+
+ template<class S> inline S* operator->() const { return m_ptr; }
+ template<class S> inline S& operator->() const { return *m_ptr; }
+
+ template<class S> operator tRCPtr<S>() { return tRCPtr<S>(m_ptr); }
+};
+
+template<class T> inline void tRCPtr<T>::handleNewPointer()
+{
+ if (!m_ptr) return;
+
+ if (m_ptr->IsExclusive()) m_ptr = new T(*m_ptr);
+
+ m_ptr->AddReference();
+}
+
+template<class T> tRCPtr<T>& tRCPtr<T>::operator=(const tRCPtr& rhs)
+{
+ if (m_ptr != rhs.m_ptr) {
+ T* old_ptr = m_ptr;
+ m_ptr = rhs.m_ptr;
+ handleNewPointer();
+ if (old_ptr) old_ptr->RemoveReference();
+ }
+
+ return *this;
+}
+
+#endif
More information about the Avida-cvs
mailing list