Since you guys seemed to be basically ok with this I went ahead and
committed it to avoid it rotting in my patch queue. I'll go back and add
a header file with PASS/FAIL printing macros/functions later and
retrofit this test and maybe some others (if it makes sense to) to use
them in a later change or changes.

Gabe

Gabe Black wrote:
> changeset b36af60dcb91 in /z/repo/m5
> details: http://repo.m5sim.org/m5?cmd=changeset;node=b36af60dcb91
> description:
>       RefCount: Add a unit test for reference counting pointers.
>
>       This test exercises each of the functions in the reference counting 
> pointer
>       implementation individually (except get()) and verifies they have some
>       minimially expected behavior. It also checks that reference counted 
> objects
>       are freed when their usage count goes to 0 in some basic situations,
>       specifically a pointer being set to NULL and a pointer being deleted.
>
> diffstat:
>
>  src/unittest/SConscript    |    1 +
>  src/unittest/refcnttest.cc |  187 
> +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 188 insertions(+), 0 deletions(-)
>
> diffs (202 lines):
>
> diff -r dac01f14f20f -r b36af60dcb91 src/unittest/SConscript
> --- a/src/unittest/SConscript Fri Jan 07 21:50:29 2011 -0800
> +++ b/src/unittest/SConscript Mon Jan 10 03:56:42 2011 -0800
> @@ -44,6 +44,7 @@
>  UnitTest('rangetest', 'rangetest.cc')
>  UnitTest('rangemaptest', 'rangemaptest.cc')
>  UnitTest('rangemultimaptest', 'rangemultimaptest.cc')
> +UnitTest('refcnttest', 'refcnttest.cc')
>  UnitTest('stattest', 'stattest.cc')
>  UnitTest('strnumtest', 'strnumtest.cc')
>  UnitTest('symtest', 'symtest.cc')
> diff -r dac01f14f20f -r b36af60dcb91 src/unittest/refcnttest.cc
> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
> +++ b/src/unittest/refcnttest.cc      Mon Jan 10 03:56:42 2011 -0800
> @@ -0,0 +1,187 @@
> +/*
> + * Copyright (c) 2010 The Regents of The University of Michigan
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met: redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer;
> + * redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the distribution;
> + * neither the name of the copyright holders nor the names of its
> + * contributors may be used to endorse or promote products derived from
> + * this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + * Authors: Gabe Black
> + */
> +
> +#include <cassert>
> +#include <iostream>
> +#include <list>
> +
> +#include "base/refcnt.hh"
> +
> +using namespace std;
> +
> +namespace {
> +
> +class TestRC;
> +typedef list<TestRC *> LiveList;
> +LiveList liveList;
> +
> +int
> +live()
> +{
> +    return liveList.size();
> +}
> +
> +int
> +liveChange()
> +{
> +    static int oldLive = 0;
> +    int newLive = live();
> +    int diff =  newLive - oldLive;
> +    oldLive = newLive;
> +    return diff;
> +}
> +
> +class TestRC : public RefCounted
> +{
> +  protected:
> +    const char *_tag;
> +    LiveList::iterator liveIt;
> +
> +  public:
> +    TestRC(const char *newTag) : _tag(newTag)
> +    {
> +        cout << "  Creating object \"" << _tag << "\"\n";
> +        liveList.push_front(this);
> +        liveIt = liveList.begin();
> +    }
> +
> +    ~TestRC()
> +    {
> +        cout << "  Destroying object \"" << _tag << "\"\n";
> +        liveList.erase(liveIt);
> +    }
> +
> +    const char *
> +    tag()
> +    {
> +        return _tag;
> +    }
> +
> +    int testVal;
> +};
> +
> +typedef RefCountingPtr<TestRC> Ptr;
> +
> +}
> +
> +int
> +main()
> +{
> +    assert(live() == 0);
> +    assert(liveChange() == 0);
> +
> +    // Create an empty Ptr and verify it's data pointer is NULL.
> +    cout << "NULL check.\n";
> +    Ptr nullCheck;
> +    assert(nullCheck.get() == NULL);
> +
> +    assert(liveChange() == 0);
> +
> +    // Construct a Ptr from a TestRC pointer.
> +    cout << "Construction from pointer.\n";
> +    Ptr constFromPointer = new TestRC("construction from pointer");
> +
> +    assert(liveChange() == 1);
> +
> +    // Construct a Ptr from an existing Ptr.
> +    cout << "Construction from a Ptr.\n";
> +    Ptr constFromPtr = constFromPointer;
> +
> +    assert(liveChange() == 0);
> +
> +    // Test a Ptr being destroyed.
> +    cout << "Destroying a Ptr.\n";
> +    Ptr *ptrPtr = new Ptr(new TestRC("destroying a ptr"));
> +    assert(liveChange() == 1);
> +    delete ptrPtr;
> +    assert(liveChange() == -1);
> +
> +    // Test assignment from a pointer and from a Ptr.
> +    cout << "Assignment operators.\n";
> +    Ptr assignmentTarget;
> +    TestRC *assignmentSourcePointer = new TestRC("assignment source 1");
> +    assert(liveChange() == 1);
> +    assignmentTarget = assignmentSourcePointer;
> +    assert(liveChange() == 0);
> +    assignmentTarget = NULL;
> +    assert(liveChange() == -1);
> +    Ptr assignmentSourcePtr(new TestRC("assignment source 2"));
> +    assert(liveChange() == 1);
> +    assignmentTarget = assignmentSourcePtr;
> +    assert(liveChange() == 0);
> +    assignmentSourcePtr = NULL;
> +    assert(liveChange() == 0);
> +    assignmentTarget = NULL;
> +    assert(liveChange() == -1);
> +
> +    // Test access to members of the pointed to class and dereferencing.
> +    cout << "Access to members.\n";
> +    TestRC *accessTest = new TestRC("access test");
> +    Ptr accessTestPtr = accessTest;
> +    accessTest->testVal = 1;
> +    assert(accessTestPtr->testVal == 1);
> +    assert((*accessTestPtr).testVal == 1);
> +    accessTest->testVal = 2;
> +    assert(accessTestPtr->testVal == 2);
> +    assert((*accessTestPtr).testVal == 2);
> +    accessTestPtr->testVal = 3;
> +    assert(accessTest->testVal == 3);
> +    (*accessTestPtr).testVal = 4;
> +    assert(accessTest->testVal == 4);
> +    accessTestPtr = NULL;
> +    accessTest = NULL;
> +    assert(liveChange() == 0);
> +
> +    // Test bool and ! operator overloads.
> +    cout << "Conversion to bool and ! overload.\n";
> +    Ptr boolTest = new TestRC("bool test");
> +    assert(boolTest == true);
> +    assert(!boolTest == false);
> +    boolTest = NULL;
> +    assert(boolTest == false);
> +    assert(!boolTest == true);
> +    assert(liveChange() == 0);
> +
> +    // Test the equality operators.
> +    cout << "Equality operators.\n";
> +    TestRC *equalTestA = new TestRC("equal test a");
> +    Ptr equalTestAPtr = equalTestA;
> +    Ptr equalTestAPtr2 = equalTestA;
> +    TestRC *equalTestB = new TestRC("equal test b");
> +    Ptr equalTestBPtr = equalTestB;
> +    assert(equalTestA == equalTestAPtr);
> +    assert(equalTestAPtr == equalTestA);
> +    assert(equalTestAPtr == equalTestAPtr2);
> +    assert(equalTestA != equalTestBPtr);
> +    assert(equalTestAPtr != equalTestB);
> +    assert(equalTestAPtr != equalTestBPtr);
> +
> +    cout << flush;
> +}
> _______________________________________________
> m5-dev mailing list
> [email protected]
> http://m5sim.org/mailman/listinfo/m5-dev
>   

_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to