1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2015 Vijay Vasudevan <vrv@google.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#define EIGEN_USE_THREADS
11
12#include <stdlib.h>
13#include "main.h"
14#include <Eigen/CXX11/Tensor>
15
16#if EIGEN_OS_WIN || EIGEN_OS_WIN64
17#include <windows.h>
18void sleep(int seconds) {
19  Sleep(seconds*1000);
20}
21#else
22#include <unistd.h>
23#endif
24
25
26namespace {
27
28void WaitAndAdd(Eigen::Notification* n, int* counter) {
29  n->Wait();
30  *counter = *counter + 1;
31}
32
33}  // namespace
34
35static void test_notification_single()
36{
37  ThreadPool thread_pool(1);
38
39  int counter = 0;
40  Eigen::Notification n;
41  std::function<void()> func = std::bind(&WaitAndAdd, &n, &counter);
42  thread_pool.Schedule(func);
43  sleep(1);
44
45  // The thread should be waiting for the notification.
46  VERIFY_IS_EQUAL(counter, 0);
47
48  // Unblock the thread
49  n.Notify();
50
51  sleep(1);
52
53  // Verify the counter has been incremented
54  VERIFY_IS_EQUAL(counter, 1);
55}
56
57// Like test_notification_single() but enqueues multiple threads to
58// validate that all threads get notified by Notify().
59static void test_notification_multiple()
60{
61  ThreadPool thread_pool(1);
62
63  int counter = 0;
64  Eigen::Notification n;
65  std::function<void()> func = std::bind(&WaitAndAdd, &n, &counter);
66  thread_pool.Schedule(func);
67  thread_pool.Schedule(func);
68  thread_pool.Schedule(func);
69  thread_pool.Schedule(func);
70  sleep(1);
71  VERIFY_IS_EQUAL(counter, 0);
72  n.Notify();
73  sleep(1);
74  VERIFY_IS_EQUAL(counter, 4);
75}
76
77void test_cxx11_tensor_notification()
78{
79  CALL_SUBTEST(test_notification_single());
80  CALL_SUBTEST(test_notification_multiple());
81}
82