BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
parallel.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 The BitShares Blockchain, and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #pragma once
26 
27 #include <fc/thread/task.hpp>
28 #include <fc/thread/thread.hpp>
29 #include <fc/asio.hpp>
30 
31 #include <boost/atomic/atomic.hpp>
32 
33 namespace fc {
34 
35  namespace detail {
36  class pool_impl;
37 
38  class worker_pool {
39  public:
40  worker_pool();
41  ~worker_pool();
42  void post( task_base* task );
43  private:
44  pool_impl* my;
45  };
46 
48  }
49 
50  class serial_valve {
51  private:
52  class ticket_guard {
53  public:
54  explicit ticket_guard( boost::atomic<future<void>*>& latch );
55  ~ticket_guard();
56  void wait_for_my_turn();
57  private:
58  promise<void>::ptr my_promise;
59  future<void>* ticket;
60  };
61 
62  friend class ticket_guard;
63  boost::atomic<future<void>*> latch;
64 
65  public:
66  serial_valve();
67  ~serial_valve();
68 
80  template<typename Functor1,typename Functor2>
81  auto do_serial( const Functor1& f1, const Functor2& f2 ) -> decltype(f2())
82  {
83  ticket_guard guard( latch );
84  f1();
85  guard.wait_for_my_turn();
86  return f2();
87  }
88  };
89 
96  template<typename Functor>
97  auto do_parallel( Functor&& f, const char* desc FC_TASK_NAME_DEFAULT_ARG ) -> fc::future<decltype(f())> {
98  typedef decltype(f()) Result;
99  typedef typename std::remove_const_t< std::remove_reference_t<Functor> > FunctorType;
101  task<Result,sizeof(FunctorType)>::create( std::forward<Functor>(f), desc );
102  tsk->retain(); // HERE BE DRAGONS
103  fc::future<Result> r( std::dynamic_pointer_cast< promise<Result> >(tsk) );
104  detail::get_worker_pool().post( tsk.get() );
105  return r;
106  }
107 }
void retain()
Definition: task.cpp:105
a placeholder for the result of an asynchronous operation.
Definition: future.hpp:211
auto do_serial(const Functor1 &f1, const Functor2 &f2) -> decltype(f2())
Definition: parallel.hpp:81
auto do_parallel(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG) -> fc::future< decltype(f())>
Definition: parallel.hpp:97
std::shared_ptr< task< R, FunctorSize > > ptr
Definition: task.hpp:118
#define FC_TASK_NAME_DEFAULT_ARG
Definition: future.hpp:14
Definition: api.hpp:15
std::shared_ptr< promise< T > > ptr
Definition: future.hpp:111
worker_pool & get_worker_pool()
Definition: parallel.cpp:152
void post(task_base *task)
Definition: parallel.cpp:145