예제 #1
0
TEST(Parallel_Test, Future_Test) {
	reset_counters();
	TestCls* values = new TestCls[DEFAULT_PARALLEL_THREAD_COUNT];
	for (unsigned x = 0; x < DEFAULT_PARALLEL_THREAD_COUNT; ++x)
		values[x] = x;

	Future future;
	parallel.process(values, &TestCls::operator*=, DEFAULT_PARALLEL_THREAD_COUNT, 0, &future, 2);

	ASSERT_EQ(DEFAULT_PARALLEL_THREAD_COUNT, future.worker_count);
	future.wait();
	ASSERT_EQ(future.finished_count, future.worker_count);
	delete[] values;
}
예제 #2
0
TEST(Parallel_Test, Process_Object_Test_Large) {
	reset_counters();
	TestCls* values = new TestCls[DEFAULT_PARALLEL_THREAD_COUNT + 1];
	for (unsigned x = 0; x < DEFAULT_PARALLEL_THREAD_COUNT + 1; ++x)
		values[x] = x;

	Future future;
	parallel.process(values, &TestCls::operator*=, DEFAULT_PARALLEL_THREAD_COUNT + 1, 0, &future, 2);
	future.wait();

	for (unsigned x = 0; x < DEFAULT_PARALLEL_THREAD_COUNT + 1; ++x)
		ASSERT_EQ(x * 2, values[x].value());
	delete[] values;
}
예제 #3
0
TEST(Parallel_Test, Batch_Test) {
	reset_counters();
	std::atomic<unsigned> atom = 0;
	Future future;
	for (unsigned x = 0; x < BATCH_TEST_COUNT; ++x) {
		parallel.batch(testFunction, nullptr, &atom);
	}
	parallel.batch(testFunction, &future, &atom);
	future.wait();

	while(!parallel.isQueueEmpty()){}

	ASSERT_EQ(atom.load(), BATCH_TEST_COUNT + 1);
}
예제 #4
0
TEST(Parallel_Test, Process_Object_Test_Equal) {
	reset_counters();
	TestCls* values = new TestCls[DEFAULT_PARALLEL_THREAD_COUNT];
	for (unsigned x = 0; x < DEFAULT_PARALLEL_THREAD_COUNT; ++x)
		values[x] = x;

	Future future;
	parallel.process(values, &TestCls::operator*=, DEFAULT_PARALLEL_THREAD_COUNT, 0, &future, 2);
	future.wait();

	ASSERT_EQ(DEFAULT_PARALLEL_THREAD_COUNT, multiplication_assignment);
	for (unsigned x = 0; x < DEFAULT_PARALLEL_THREAD_COUNT; ++x)
		ASSERT_EQ(x * 2, values[x].value());
	delete[] values;
}
예제 #5
0
TEST(Wait, waitWithDuration) {
 {
  Promise<int> p;
  Future<int> f = p.getFuture();
  f.wait(milliseconds(1));
  EXPECT_FALSE(f.isReady());
  p.setValue(1);
  EXPECT_TRUE(f.isReady());
 }
 {
  Promise<int> p;
  Future<int> f = p.getFuture();
  p.setValue(1);
  f.wait(milliseconds(1));
  EXPECT_TRUE(f.isReady());
 }
 {
  vector<Future<bool>> v_fb;
  v_fb.push_back(makeFuture(true));
  v_fb.push_back(makeFuture(false));
  auto f = collectAll(v_fb);
  f.wait(milliseconds(1));
  EXPECT_TRUE(f.isReady());
  EXPECT_EQ(2, f.value().size());
 }
 {
  vector<Future<bool>> v_fb;
  Promise<bool> p1;
  Promise<bool> p2;
  v_fb.push_back(p1.getFuture());
  v_fb.push_back(p2.getFuture());
  auto f = collectAll(v_fb);
  f.wait(milliseconds(1));
  EXPECT_FALSE(f.isReady());
  p1.setValue(true);
  EXPECT_FALSE(f.isReady());
  p2.setValue(true);
  EXPECT_TRUE(f.isReady());
 }
 {
  auto f = makeFuture().wait(milliseconds(1));
  EXPECT_TRUE(f.isReady());
 }

 {
   Promise<Unit> p;
   auto start = std::chrono::steady_clock::now();
   auto f = p.getFuture().wait(milliseconds(100));
   auto elapsed = std::chrono::steady_clock::now() - start;
   EXPECT_GE(elapsed, milliseconds(100));
   EXPECT_FALSE(f.isReady());
   p.setValue();
   EXPECT_TRUE(f.isReady());
 }

 {
   // Try to trigger the race where the resultant Future is not yet complete
   // even if we didn't hit the timeout, and make sure we deal with it properly
   Promise<Unit> p;
   folly::Baton<> b;
   auto t = std::thread([&]{
     b.post();
     /* sleep override */ std::this_thread::sleep_for(milliseconds(100));
     p.setValue();
   });
   b.wait();
   auto f = p.getFuture().wait(std::chrono::seconds(3600));
   EXPECT_TRUE(f.isReady());
   t.join();
 }
}
예제 #6
0
 static void wait(Future& f, int n) {
   f.wait(n);
 }
예제 #7
0
// The primary thread function, which issues calls through the secondary thread
void rundemos()
{
	// Create an event for which our second thread will wait
	hExternalEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	// Create the secondary thread
	DWORD dwThreadId;
	HANDLE hThread = CreateThread(NULL, 0, demoThread, NULL, 0, &dwThreadId);

	// Obtain a scheduler instance, through which we can make cross thread calls
	CallScheduler<APCPickupPolicy>* scheduler = CallScheduler<APCPickupPolicy>::getInstance();

	// Do a first cross thread call, to a function returning a string
	try
	{
		string dataString = scheduler->syncCall<string, ExceptionTypes<std::exception>>(dwThreadId, boost::bind(demoFunction, 'a'), INFINITE);
		cout << "demoFunction returned: " << dataString << endl;
	}
	catch(CallTimeoutException&)
	{
		cout << "Call timeout." << endl;
	}
	catch(CallSchedulingFailedException&)
	{
		cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
	}
	catch(std::exception& e)
	{
		cout << "The scheduled call threw a std exception: " << e.what() << endl;
	}

	// Do a second cross thread call, to a function returning nothing
	try
	{
		// Expect a std::exception or DemoException
		scheduler->syncCall<void, ExceptionTypes<std::exception, DemoException>>(dwThreadId, boost::bind(demoVoidFunction, 'a'), 500);
	}
	catch(CallTimeoutException&)
	{
		cout << "Call timeout" << endl;
	}
	catch(CallSchedulingFailedException&)
	{
		cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
	}
	catch(std::exception& e)
	{
		cout << "demoVoidFunction threw a std exception: " << e.what() << endl;
	}
	catch(DemoException&)
	{
		cout << "demoVoidFunction threw a DemoException" << endl;
	}

    // Do a third cross thread call, to a function returning an int
    try
    {
        // Expect a std::exception or DemoException
        int demoInt = scheduler->syncCall<int, ExceptionTypes<std::exception, DemoException>>(dwThreadId, boost::bind(demoIntFunction, '!'), 500);
        cout << "demoIntFunction returned: " << demoInt << endl;
    }
    catch(CallTimeoutException&)
    {
        cout << "Call timeout" << endl;
    }
    catch(CallSchedulingFailedException&)
    {
        cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
    }
    catch(std::exception& e)
    {
        cout << "demoIntFunction threw a std exception: " << e.what() << endl;
    }
    catch(DemoException&)
    {
        cout << "demoIntFunction threw a DemoException" << endl;
    }

    // Do a fourth cross thread call, to a function returning an int
    try
    {
        boost::function<int()> f = boost::bind(demoIntFunctionDelayed, '!');
        Future<int> futureDemoInt = scheduler->asyncCall<ExceptionTypes<DemoException, std::exception>>(dwThreadId, f);
        
        //Future<int> futureDemoInt2 = scheduler->asyncCall<ExceptionTypes<DemoException, std::exception>>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<void> futureDemoInt3 = scheduler->asyncCall<void>(dwThreadId, boost::bind(demoIntFunctionDelayed, '?'));
        Future<int> futureDemoInt4 = scheduler->asyncCall<int>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<int> futureDemoInt5 = scheduler->asyncCall<int, ExceptionTypes<DemoException>>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<void> futureDemoInt6 = scheduler->asyncCall<void, ExceptionTypes<DemoException>>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<void> futureDemoInt7 = scheduler->asyncCall<ExceptionTypes<DemoException>, void>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<int> futureDemoInt8 = scheduler->asyncCall<ExceptionTypes<DemoException>, int>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));

        while(futureDemoInt.wait(10) == ASYNCH_CALL_PENDING)
        {
            cout << "Still waiting ..." << endl;
        }
        cout << "demoIntFunctionDelayed returned: " << futureDemoInt.getValue() << endl;
    }
    catch(CallSchedulingFailedException&)
    {
        cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
    }

	// Cleanup
	SetEvent(hExternalEvent);
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	CloseHandle(hExternalEvent);
}