Skip to content

Commit

Permalink
Merge pull request #2218 from tklein23/fix_refcounts_in_sgrefobject
Browse files Browse the repository at this point in the history
SGRefObjects not allowed to share RefCount objects (any more)
  • Loading branch information
tklein23 committed May 13, 2014
2 parents 7b466f2 + 330e995 commit a9de0d3
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/shogun/base/Parallel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Parallel::Parallel()
Parallel::Parallel(const Parallel& orig)
{
num_threads=orig.get_num_threads();
m_refcount = new RefCount(orig.m_refcount->ref_count());
m_refcount = new RefCount();
}

Parallel::~Parallel()
Expand Down
5 changes: 3 additions & 2 deletions src/shogun/base/SGRefObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ SGRefObject::SGRefObject()
SGRefObject::SGRefObject(const SGRefObject& orig)
{
init();
m_refcount = orig.m_refcount;
SG_REF(this);
m_refcount = new RefCount(0);

SG_SGCDEBUG("SGRefObject copied (%p)\n", this)
}

SGRefObject::~SGRefObject()
Expand Down
2 changes: 1 addition & 1 deletion src/shogun/io/SGIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ SGIO::SGIO(const SGIO& orig)
syntax_highlight(orig.get_syntax_highlight()),
loglevel(orig.get_loglevel())
{
m_refcount = new RefCount(orig.m_refcount->ref_count());
m_refcount = new RefCount();
}

void SGIO::message(EMessageType prio, const char* function, const char* file,
Expand Down
54 changes: 54 additions & 0 deletions tests/unit/base/RefCount_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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; either version 3 of the License, or
* (at your option) any later version.
*
* Written (W) 2014 Thoralf Klein
*/

#include <shogun/lib/RefCount.h>
#include <pthread.h>
#include <gtest/gtest.h>

using namespace shogun;

void * stress_test_helper(void * args)
{
RefCount * rc = (RefCount *) args;

for (index_t i = 0; i < 1000000; i++)
{
rc->ref();
rc->ref();
rc->unref();
rc->unref();
}

pthread_exit(0);
}

TEST(RefCount, stress_test)
{
RefCount * rc = new RefCount(0);
EXPECT_EQ(rc->ref_count(), 0);
rc->ref();
EXPECT_EQ(rc->ref_count(), 1);

pthread_t * threads = new pthread_t[10];

for (index_t i = 0; i < 10; i++)
{
pthread_create(&threads[i], NULL, stress_test_helper, static_cast<void *>(rc));
}

for (index_t i = 0; i < 10; i++)
{
pthread_join(threads[i], NULL);
}

EXPECT_EQ(rc->ref_count(), 1);
rc->unref();
EXPECT_EQ(rc->ref_count(), 0);
delete [] threads;
}
38 changes: 15 additions & 23 deletions tests/unit/base/SGObject_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* (at your option) any later version.
*
* Written (W) 2013 Heiko Strathmann
* Written (W) 2014 Thoralf Klein
*/

#include <shogun/labels/BinaryLabels.h>
Expand Down Expand Up @@ -50,42 +51,33 @@ TEST(SGObject,equals_NULL_parameter)
}
#endif //HAVE_EIGEN3

void* stress_test(void* args)
#ifdef USE_REFERENCE_COUNTING
TEST(SGObject,DISABLED_ref_copy_constructor)
{
CBinaryLabels* labs = (CBinaryLabels* ) args;
CBinaryLabels* labs = new CBinaryLabels(10);
EXPECT_EQ(labs->ref_count(), 0);

SG_REF(labs);
EXPECT_EQ(labs->ref_count(), 1);

// TODO: This causes memory corruptions; disabled test until fixed
CBinaryLabels* labs_2 = new CBinaryLabels(*labs);
for (index_t i=0; i<1000000; i++)
{
SG_REF(labs);
SG_REF(labs_2);
SG_UNREF(labs_2);
SG_UNREF(labs);
}
SG_UNREF(labs_2);
pthread_exit(0);

SG_UNREF(labs);
EXPECT_TRUE(labs == NULL);
}

#ifdef USE_REFERENCE_COUNTING
TEST(SGObject,ref_unref)
TEST(SGObject,ref_unref_simple)
{
CBinaryLabels* labs = new CBinaryLabels(10);
EXPECT_EQ(labs->ref_count(), 0);

SG_REF(labs);
EXPECT_EQ(labs->ref_count(), 1);

pthread_t* threads = new pthread_t[10];
for (index_t i=0; i<10; i++)
{
pthread_create(&threads[i], NULL, stress_test, static_cast<void* >(labs));
}
for (index_t i=0; i<10; i++)
{
pthread_join(threads[i], NULL);
//SG_UNREF(labs);
}
SG_UNREF(labs);
EXPECT_TRUE(labs == NULL);
delete [] threads;
}
#endif

Expand Down

0 comments on commit a9de0d3

Please sign in to comment.