watch.h
Go to the documentation of this file.
1 //
2 // Created by Eduard Valeyev on 2019-04-05.
3 //
4 
5 #ifndef TTG_WATCH_H
6 #define TTG_WATCH_H
7 
8 #include "ttg/impl_selector.h"
9 #include "ttg/util/bug.h"
10 
11 namespace ttg_madness {
12  // clang-format off
13 /*
14  * This allows programmatic control of watchpoints. Requires MADWorld using legacy ThreadPool and macOS. Example:
15  * @code
16  * double x = 0.0;
17  * ::ttg_madness::initialize_watchpoints();
18  * ::ttg_madness::watchpoint_set(&x, ttg::detail::MemoryWatchpoint_x86_64::kWord,
19  * ttg::detail::MemoryWatchpoint_x86_64::kWhenWritten);
20  * x = 1.0; // this will generate SIGTRAP ...
21  * ::ttg_madness::ttg_default_execution_context().taskq.add([&x](){ x = 1.0; }); // and so will this ...
22  * ::ttg_madness::watchpoint_set(&x, ttg::detail::MemoryWatchpoint_x86_64::kWord,
23  * ttg::detail::MemoryWatchpoint_x86_64::kWhenWrittenOrRead);
24  * ::ttg_madness::ttg_default_execution_context().taskq.add([&x](){
25  * std::cout << x << std::endl; }); // and even this!
26  *
27  * @endcode
28  */
29  // clang-format on
30 
31  namespace detail {
32  inline const std::vector<const pthread_t *> &watchpoints_threads() {
33  static std::vector<const pthread_t *> threads;
34  // can set watchpoints only with the legacy MADNESS threadpool
35  // TODO improve this when shortsighted MADNESS macro names are strengthened, i.e. HAVE_INTEL_TBB ->
36  // MADNESS_HAS_INTEL_TBB
37  // TODO also exclude the case of a PARSEC-based backend
38 #ifndef HAVE_INTEL_TBB
39  if (threads.empty()) {
40  static pthread_t main_thread_id = pthread_self();
41  threads.push_back(&main_thread_id);
42  for (auto t = 0ul; t != ::madness::ThreadPool::size(); ++t) {
43  threads.push_back(&(::madness::ThreadPool::get_threads()[t].get_id()));
44  }
45  }
46 #endif
47  return threads;
48  }
49  } // namespace detail
50 
52  inline void initialize_watchpoints() {
53 #if defined(HAVE_INTEL_TBB)
55  "WARNING: watchpoints are only supported with MADWorld using the legacy threadpool");
56 #endif
57 #if !defined(__APPLE__)
58  ttg::print_error(ttg::default_execution_context().rank(), "WARNING: watchpoints are only supported on macOS");
59 #endif
61  }
62 
64  template <typename T>
67  const auto &threads = detail::watchpoints_threads();
68  for (auto t : threads) ttg::detail::MemoryWatchpoint_x86_64::Pool::instance()->set(addr, size, cond, t);
69  }
70 
72  template <typename T>
73  inline void watchpoint_clear(T *addr) {
74  const auto &threads = detail::watchpoints_threads();
75  for (auto t : threads) ttg::detail::MemoryWatchpoint_x86_64::Pool::instance()->clear(addr, t);
76  }
77 
78 } // namespace ttg_madness
79 #endif // TTG_WATCH_H
static void initialize_instance(const std::vector< const pthread_t * > &threads)
Definition: bug.h:89
static std::shared_ptr< Pool > instance()
accesses the unique pool; asserts that the default instance has been initialized by calling initializ...
Definition: bug.h:94
const std::vector< const pthread_t * > & watchpoints_threads()
Definition: watch.h:32
this contains MADNESS-based TTG functionality
Definition: fwd.h:16
void initialize_watchpoints()
must be called from main thread before setting watchpoints
Definition: watch.h:52
void watchpoint_clear(T *addr)
clears the hardware watchpoint for window [addr,addr+size) previously created with watchpoint_set<T>
Definition: watch.h:73
void watchpoint_set(T *addr, ttg::detail::MemoryWatchpoint_x86_64::Size size, ttg::detail::MemoryWatchpoint_x86_64::Condition cond)
sets a hardware watchpoint for window [addr,addr+size) and condition cond
Definition: watch.h:65
int size(World world=default_execution_context())
Definition: run.h:89
World default_execution_context()
Accesses the default backend's default execution context.
Definition: run.h:68
void print_error(const T &t, const Ts &... ts)
atomically prints to std::cerr a sequence of items (separated by ttg::print_separator) followed by st...
Definition: print.h:138
int rank(World world=default_execution_context())
Definition: run.h:85