STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pplwin.h
Go to the documentation of this file.
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 * ==--==
7 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
8 *
9 * pplwin.h
10 *
11 * Parallel Patterns Library - PPLTasks helpers
12 *
13 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
14 ****/
15 
16 #pragma once
17 
18 #ifndef _PPLWIN_H
19 #define _PPLWIN_H
20 
21 #include <pplinterface.h>
22 #include <condition_variable>
23 #include <mutex>
24 #include <system_error>
25 #include <memory>
26 #include <ppltaskscheduler.h>
27 
28 #pragma pack(push,_CRT_PACKING)
29 #pragma warning(push,3)
30 #pragma push_macro("new")
31 #undef new
32 
33 namespace Concurrency
34 {
35 namespace details
36 {
37 
38 class _DefaultPPLTaskScheduler : public scheduler_interface
39 {
40 public:
41 
43  {
46  void *_M_param;
47 
48  static void __cdecl _Callback(void *_Args)
49  {
50  auto _Chore = ::std::unique_ptr<_PPLTaskChore>(static_cast<_PPLTaskChore*>(_Args));
51  _Chore->_M_proc(_Chore->_M_param);
52  }
53 
54  public:
56  {
57  _Release_chore(&_M_Chore);
58  }
59 
60  _PPLTaskChore(TaskProc_t _Proc, void *_Param) : _M_Chore{&_Callback, this}, _M_proc(_Proc), _M_param(_Param)
61  {
62  }
63 
64  void _Schedule()
65  {
66  if (_Schedule_chore(&_M_Chore) != 0)
67  {
68  delete this;
69  _THROW_NCEE(::std::runtime_error, "Fail to schedule the chore!");
70  }
71  }
72  };
73 
74  virtual void schedule( TaskProc_t _Proc, void* _Param) override
75  {
76  (new _PPLTaskChore{ _Proc, _Param })->_Schedule();
77  }
78 };
79 
80 inline ::std::shared_ptr<scheduler_interface> & _GetStaticAmbientSchedulerRef()
81 {
82  static ::std::shared_ptr<scheduler_interface> _S_scheduler;
83  return _S_scheduler;
84 }
85 
86 } // namespace details
87 
88 inline const ::std::shared_ptr<scheduler_interface> &get_ambient_scheduler()
89 {
91 }
92 
93 inline void set_ambient_scheduler(const ::std::shared_ptr<scheduler_interface>& _Scheduler)
94 {
96 }
97 
98 namespace details
99 {
100  // Used to report unobserved task exceptions in ppltasks.h
101  _CRTIMP2 void __cdecl _ReportUnobservedException();
102 
103  namespace platform
104  {
105  _CRTIMP2 unsigned int __cdecl GetNextAsyncId();
106  _CRTIMP2 size_t __cdecl CaptureCallstack(void **, size_t, size_t);
107  _CRTIMP2 long __cdecl GetCurrentThreadId();
108  }
109 }
110 
111 } // Concurrency
112 
113 #include <pplcancellation_token.h>
114 
115 namespace Concurrency
116 {
117 
118 namespace details
119 {
120 
121 // It has to be a macro because the debugger needs __debugbreak
122 // breaks on the frame with exception pointer.
123 // It can be only used within _ExceptionHolder
124 #ifndef _REPORT_PPLTASK_UNOBSERVED_EXCEPTION
125 #define _REPORT_PPLTASK_UNOBSERVED_EXCEPTION() do { \
126  ReportUnhandledError(); \
127  __debugbreak(); \
128  ::Concurrency::details::_ReportUnobservedException(); \
129 } while (false)
130 
131 #endif
132 
134  {
136  virtual ~_TaskProcHandle() {}
137  virtual void invoke() const = 0;
138 
139  void operator()() const
140  {
141  this->invoke();
142  }
143 
144  static void __cdecl _RunChoreBridge(void * _Parameter)
145  {
146  ::std::unique_ptr<_TaskProcHandle> {static_cast<_TaskProcHandle *>(_Parameter)}->invoke();
147  }
148  };
149 
151  {
152  protected:
157  };
158 
160  {
161  _ASSERTE(_NewState != _New);
162  std::lock_guard<std::mutex> _Lock(_M_Cs);
163  if (_M_State < _NewState)
164  {
165  _M_State = _NewState;
166  }
167 
168  _M_StateChanged.notify_all();
169  }
170 
172  {
173  std::unique_lock<std::mutex> _Lock(_M_Cs);
174 
175  while(_M_State < _State)
176  {
177  _M_StateChanged.wait(_Lock);
178  }
179  }
180  public:
181 
183 
185  : _M_pScheduler(_PScheduler), _M_State(_New)
186  {
187  }
188 
189  void _ScheduleTask(_TaskProcHandle_t* _Parameter, _TaskInliningMode _InliningMode)
190  {
191  if (_InliningMode == _ForceInline)
192  {
193  _TaskProcHandle_t::_RunChoreBridge(_Parameter);
194  }
195  else
196  {
197  if (_M_pScheduler)
198  {
199  _M_pScheduler->schedule(_TaskProcHandle_t::_RunChoreBridge, _Parameter);
200  }
201  else
202  {
203  _DefaultPPLTaskScheduler().schedule(_TaskProcHandle_t::_RunChoreBridge, _Parameter);
204  }
205  }
206  }
207 
208  void _Cancel()
209  {
210  // No cancellation support
211  }
212 
213  void _RunAndWait()
214  {
215  _Wait();
216  }
217 
218  void _Wait()
219  {
220  WaitUntilStateChangedTo(_Completed);
221  }
222 
223  void _Complete()
224  {
225  // Ensure that RunAndWait makes progress.
226  _SetCollectionState(_Completed);
227  }
228 
230  {
231  return _M_pScheduler;
232  }
233 
234  // Fire and forget
235  static void _RunTask(TaskProc_t _Proc, void * _Parameter, _TaskInliningMode _InliningMode)
236  {
237  if (_InliningMode == _ForceInline)
238  {
239  _Proc(_Parameter);
240  }
241  else
242  {
243  // Schedule the work on the default scheduler if the ambient scheduler is not set
244  auto _Ptr = get_ambient_scheduler();
245  if (_Ptr)
246  {
247  _Ptr->schedule(_Proc, _Parameter);
248  }
249  else
250  {
251  _DefaultPPLTaskScheduler().schedule(_Proc, _Parameter);
252  }
253  }
254  }
255  protected:
256  ::std::condition_variable _M_StateChanged;
257  ::std::mutex _M_Cs;
260  };
261 
263 
264  // Over-subscription is no longer needed for threadpool based ppltasks
266 
269 
270 } // details
271 } // Concurrency
272 
273 namespace concurrency = ::Concurrency;
274 
275 #pragma pop_macro("new")
276 #pragma warning(pop)
277 #pragma pack(pop)
278 #endif // _PPLWIN_H
_TaskCollectionBaseImpl _TaskCollection_t
Definition: pplwin.h:262
static void __cdecl _Callback(void *_Args)
Definition: pplwin.h:48
_TaskCollectionState _M_State
Definition: pplwin.h:259
_CRTIMP2 long __cdecl GetCurrentThreadId()
_TaskInliningMode _TaskInliningMode_t
Definition: pplwin.h:267
_TaskCollectionBaseImpl(::Concurrency::scheduler_ptr _PScheduler)
Definition: pplwin.h:184
_CRTIMP2 void __cdecl _Release_chore(_Threadpool_chore *)
_Threadpool_chore _M_Chore
Definition: pplwin.h:44
Definition: concrt.h:4304
Definition: pplinterface.h:228
const ::std::shared_ptr< scheduler_interface > & get_ambient_scheduler()
Definition: pplwin.h:88
void _RunAndWait()
Definition: pplwin.h:213
void _SetCollectionState(_TaskCollectionState _NewState)
Definition: pplwin.h:159
_CRTIMP2 size_t __cdecl CaptureCallstack(void **, size_t, size_t)
_TaskProcHandle()
Definition: pplwin.h:135
inline::std::shared_ptr< scheduler_interface > & _GetStaticAmbientSchedulerRef()
Definition: pplwin.h:80
The Concurrency namespace provides classes and functions that provide access to the Concurrency Runti...
Definition: agents.h:43
Definition: concrt.h:4172
virtual void schedule(TaskProc_t _Proc, void *_Param) override
Definition: pplwin.h:74
_CRTIMP2 int __cdecl _Schedule_chore(_Threadpool_chore *)
_CRTIMP2 void __cdecl _ReportUnobservedException()
Definition: ppltaskscheduler.h:26
void set_ambient_scheduler(const ::std::shared_ptr< scheduler_interface > &_Scheduler)
Definition: pplwin.h:93
_TaskInliningMode
The enum defines inlining scheduling policy for ppltasks. Scheduling a chore or a functor with _TaskI...
Definition: pplinterface.h:221
_PPLTaskChore(TaskProc_t _Proc, void *_Param)
Definition: pplwin.h:60
#define _THROW_NCEE(x, y)
Definition: xstddef:78
_TaskProcHandle _TaskProcHandle_t
Definition: pplwin.h:182
_CRTIMP2 unsigned int __cdecl GetNextAsyncId()
void _Complete()
Definition: pplwin.h:223
::Concurrency::scheduler_ptr _GetScheduler() const
Definition: pplwin.h:229
Represents a pointer to a scheduler. This class exists to allow the the specification of a shared lif...
Definition: pplinterface.h:47
_Task_generator_oversubscriber _Task_generator_oversubscriber_t
Definition: pplwin.h:268
void(__cdecl * TaskProc_t)(void *)
An elementary abstraction for a task, defined as void (__cdecl * TaskProc_t)(void *)...
Definition: pplinterface.h:32
virtual void invoke() const =0
void _ScheduleTask(_TaskProcHandle_t *_Parameter, _TaskInliningMode _InliningMode)
Definition: pplwin.h:189
::std::mutex _M_Cs
Definition: pplwin.h:257
::std::condition_variable _M_StateChanged
Definition: pplwin.h:256
#define _CRTIMP2
Definition: crtdefs.h:36
void _Cancel()
Definition: pplwin.h:208
void WaitUntilStateChangedTo(_TaskCollectionState _State)
Definition: pplwin.h:171
static void _RunTask(TaskProc_t _Proc, void *_Parameter, _TaskInliningMode _InliningMode)
Definition: pplwin.h:235
virtual ~_TaskProcHandle()
Definition: pplwin.h:136
::Concurrency::scheduler_ptr _M_pScheduler
Definition: pplwin.h:258
void _Wait()
Definition: pplwin.h:218
void operator()() const
Definition: pplwin.h:139
static void __cdecl _RunChoreBridge(void *_Parameter)
Definition: pplwin.h:144