blob: e1c25590eb278728995c963e7b686d00c6b6abf6 [file] [log] [blame]
#include <gtest/gtest.h>
#include <pthreadpool.h>
const size_t itemsCount1D = 1024;
TEST(SetupAndShutdown, Basic) {
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
pthreadpool_destroy(threadpool);
}
static void computeNothing1D(void*, size_t) {
}
TEST(Compute1D, Basic) {
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
pthreadpool_compute_1d(threadpool, computeNothing1D, NULL, itemsCount1D);
pthreadpool_destroy(threadpool);
}
static void checkRange1D(void*, size_t itemId) {
EXPECT_LT(itemId, itemsCount1D);
}
TEST(Compute1D, ValidRange) {
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
pthreadpool_compute_1d(threadpool, checkRange1D, NULL, itemsCount1D);
pthreadpool_destroy(threadpool);
}
static void setTrue1D(bool indicators[], size_t itemId) {
indicators[itemId] = true;
}
TEST(Compute1D, AllItemsProcessed) {
bool processed[itemsCount1D];
memset(processed, 0, sizeof(processed));
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
pthreadpool_compute_1d(threadpool, reinterpret_cast<pthreadpool_function_1d_t>(setTrue1D), processed, itemsCount1D);
for (size_t itemId = 0; itemId < itemsCount1D; itemId++) {
EXPECT_TRUE(processed[itemId]) << "Item " << itemId << " not processed";
}
pthreadpool_destroy(threadpool);
}
static void increment1D(int counters[], size_t itemId) {
counters[itemId] += 1;
}
TEST(Compute1D, EachItemProcessedOnce) {
int processedCount[itemsCount1D];
memset(processedCount, 0, sizeof(processedCount));
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
pthreadpool_compute_1d(threadpool, reinterpret_cast<pthreadpool_function_1d_t>(increment1D), processedCount, itemsCount1D);
for (size_t itemId = 0; itemId < itemsCount1D; itemId++) {
EXPECT_EQ(1, processedCount[itemId]) << "Item " << itemId << " processed " << processedCount[itemId] << " times";
}
pthreadpool_destroy(threadpool);
}
TEST(Compute1D, EachItemProcessedMultipleTimes) {
int processedCount[itemsCount1D];
memset(processedCount, 0, sizeof(processedCount));
const size_t iterations = 100;
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
for (size_t iteration = 0; iteration < iterations; iteration++) {
pthreadpool_compute_1d(threadpool, reinterpret_cast<pthreadpool_function_1d_t>(increment1D), processedCount, itemsCount1D);
}
for (size_t itemId = 0; itemId < itemsCount1D; itemId++) {
EXPECT_EQ(iterations, processedCount[itemId]) << "Item " << itemId << " processed " << processedCount[itemId] << " times";
}
pthreadpool_destroy(threadpool);
}
static void workImbalance1D(volatile size_t* computedItems, size_t itemId) {
__sync_fetch_and_add(computedItems, 1);
if (itemId == 0) {
/* Wait until all items are computed */
while (*computedItems != itemsCount1D) {
__sync_synchronize();
}
}
}
TEST(Compute1D, WorkStealing) {
volatile size_t computedItems = 0;
pthreadpool* threadpool = pthreadpool_create(0);
EXPECT_TRUE(threadpool != nullptr);
pthreadpool_compute_1d(threadpool, reinterpret_cast<pthreadpool_function_1d_t>(workImbalance1D), reinterpret_cast<void*>(const_cast<size_t*>(&computedItems)), itemsCount1D);
EXPECT_EQ(computedItems, itemsCount1D);
pthreadpool_destroy(threadpool);
}
int main(int argc, char* argv[]) {
setenv("TERM", "xterm-256color", 0);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}