35 #include <gtest/gtest.h>
40 #include <boost/thread.hpp>
52 uint32_t* item =
static_cast<uint32_t*
>(pool.
allocate());
54 EXPECT_EQ(*item, 5UL);
58 item =
static_cast<uint32_t*
>(pool.
allocate());
60 EXPECT_EQ(*item, 6UL);
65 const uint32_t count = 5;
69 std::vector<uint32_t*> items;
72 for (uint32_t i = 0; i < count; ++i)
74 items.push_back(
static_cast<uint32_t*
>(pool.
allocate()));
75 ASSERT_TRUE(items[i]);
76 EXPECT_EQ(*items[i], 5UL);
81 pool.
free(items.back());
83 items.push_back(
static_cast<uint32_t*
>(pool.
allocate()));
84 ASSERT_TRUE(items.back());
87 std::set<uint32_t*> set;
88 set.insert(items.begin(), items.end());
89 EXPECT_EQ(set.size(), count);
93 boost::mutex g_debug_mutex;
94 std::vector<FreeList::Debug> g_debug;
96 std::ostream&
operator<<(std::ostream& o,
const FreeList::Debug::Item& i)
99 o << (i.success ? 1 : 0);
103 o << ((i.op == FreeList::Debug::Alloc) ? std::string(
"alloc") :
std::string(
"free "));
104 o << std::string(
" head: ");
107 o << std::string(
" new_head: ");
109 o <<
" addr:" << (uint32_t*)i.addr;
117 : start(
ros::WallTime::now())
126 void threadFunc(
FreeList& pool, ros::atomic<bool>& done, ros::atomic<bool>& failed, boost::barrier& b)
133 uint64_t alloc_count = 0;
136 for (uint32_t i = 0; i < 10; ++i)
138 vals[i] =
static_cast<uint32_t*
>(pool.
allocate());
147 ROS_ERROR_STREAM(
"Thread " << boost::this_thread::get_id() <<
" failed to allocate");
151 for (uint32_t i = 0; i < 10; ++i)
157 ROS_ERROR_STREAM(
"Thread " << boost::this_thread::get_id() <<
" val " << vals[i] <<
" " << i <<
" = " << *vals[i]);
168 boost::mutex::scoped_lock lock(g_debug_mutex);
169 g_debug.push_back(*pool.getDebug());
180 const uint32_t thread_count = boost::thread::hardware_concurrency() * 2;
181 FreeList pool(4, thread_count * 10);
182 ros::atomic<bool> done(
false);
183 ros::atomic<bool> failed(
false);
184 boost::thread_group tg;
185 boost::barrier bar(thread_count);
186 for (uint32_t i = 0; i < thread_count; ++i)
188 tg.create_thread(boost::bind(
threadFunc, boost::ref(pool), boost::ref(done), boost::ref(failed), boost::ref(bar)));
207 std::vector<std::vector<FreeList::Debug::Item>::iterator> its;
208 its.resize(g_debug.size());
209 for (
size_t i = 0; i < its.size(); ++i)
211 int32_t start = std::max((int32_t)g_debug[i].items.size() - 10000, 0);
213 its[i] = g_debug[i].items.begin() + start;
219 for (
size_t j = 0; j < its.size(); ++j)
221 if (its[j] != g_debug[j].items.end() && its[j]->time < time)
233 ROS_ERROR_STREAM(
"[" << std::setw(20) << g_debug[ind].thread <<
"] " << *its[ind]);
239 ASSERT_TRUE(!failed.load());
244 const uint32_t count = 5;
247 std::vector<uint32_t*> items;
248 items.reserve(count);
252 for (uint32_t i = 0; i < count; ++i)
254 items.push_back(
static_cast<uint32_t*
>(pool.
allocate()));
258 for (uint32_t i = 0; i < count; ++i)
267 int main(
int argc,
char** argv)
269 testing::InitGoogleTest(&argc, argv);
270 return RUN_ALL_TESTS();