1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
/********************* */
/*! \file portfolio.cpp
** \verbatim
** Original author: kshitij
** Major contributors: mdeters
** Minor contributors (to current version): none
** This file is part of the CVC4 prototype.
** Copyright (c) 2009-2012 New York University and The University of Iowa
** See the file COPYING in the top-level source directory for licensing
** information.\endverbatim
**
** \brief Provides (somewhat) generic functionality to simulate a
** (potentially cooperative) race
**/
#include <boost/function.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/thread/condition.hpp>
#include <boost/exception_ptr.hpp>
#include "smt/smt_engine.h"
#include "util/result.h"
#include "options/options.h"
namespace CVC4 {
boost::mutex mutex_done;
boost::mutex mutex_main_wait;
boost::condition condition_var_main_wait;
bool global_flag_done;
int global_winner;
template<typename S>
void runThread(int thread_id, boost::function<S()> threadFn, S& returnValue)
{
returnValue = threadFn();
if( mutex_done.try_lock() ) {
if(global_flag_done == false) {
global_flag_done = true;
global_winner = thread_id;
}
mutex_done.unlock();
condition_var_main_wait.notify_all(); // we want main thread to quit
}
}
template<typename T, typename S>
std::pair<int, S> runPortfolio(int numThreads,
boost::function<T()> driverFn,
boost::function<S()> threadFns[],
bool optionWaitToJoin) {
boost::thread thread_driver;
boost::thread threads[numThreads];
S threads_returnValue[numThreads];
global_flag_done = false;
global_winner = -1;
for(int t = 0; t < numThreads; ++t) {
threads[t] =
boost::thread(boost::bind(runThread<S>, t, threadFns[t],
boost::ref(threads_returnValue[t]) ) );
}
if(not driverFn.empty())
thread_driver = boost::thread(driverFn);
while(global_flag_done == false)
condition_var_main_wait.wait(mutex_main_wait);
if(not driverFn.empty()) {
thread_driver.interrupt();
thread_driver.join();
}
for(int t = 0; t < numThreads; ++t) {
if(optionWaitToJoin) {
threads[t].join();
}
}
return std::pair<int, S>(global_winner,threads_returnValue[global_winner]);
}
// instantiation
template
std::pair<int, bool>
runPortfolio<void, bool>(int,
boost::function<void()>,
boost::function<bool()>*,
bool);
}/* CVC4 namespace */
|