STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pplconcrt.h
Go to the documentation of this file.
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 * ==--==
7 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
8 *
9 * pplconcrt.h
10 *
11 * Parallel Patterns Library - PPL ConcRT helpers
12 *
13 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
14 ****/
15 
16 #pragma once
17 
18 #ifndef _PPLCONCRT_H
19 #define _PPLCONCRT_H
20 
21 #include <pplinterface.h>
22 #include <concrt.h>
23 
24 #define _noexcept
25 
26 namespace Concurrency
27 {
28 // The extensibility namespace contains the type definitions that are used by ppltasks implementation
29 namespace extensibility
30 {
31  typedef ::Concurrency::event event_t;
32 
33  typedef ::Concurrency::critical_section critical_section_t;
35 
36  typedef ::Concurrency::reader_writer_lock reader_writer_lock_t;
37  typedef ::Concurrency::reader_writer_lock::scoped_lock scoped_rw_lock_t;
38  typedef ::Concurrency::reader_writer_lock::scoped_lock_read scoped_read_lock_t;
39 
40  typedef ::Concurrency::details::_ReentrantBlockingLock recursive_lock_t;
42 }
43 
45 
46 namespace details
47 {
48  namespace platform
49  {
50  _CRTIMP2 unsigned int __cdecl GetNextAsyncId();
51  _CRTIMP size_t __cdecl CaptureCallstack(void **stackData, size_t skipFrames, size_t captureFrames);
52  _CRTIMP long __cdecl GetCurrentThreadId();
53  }
54 }
55 
56 } // Concurrency
57 
58 #include <pplcancellation_token.h>
59 #include <ppl.h>
60 
61 namespace Concurrency
62 {
63 
64 inline std::shared_ptr< ::Concurrency::scheduler_interface> get_ambient_scheduler()
65 {
66  return nullptr;
67 }
68 
69 inline void set_ambient_scheduler(std::shared_ptr< ::Concurrency::scheduler_interface> _Scheduler)
70 {
71  throw invalid_operation("Scheduler is already initialized");
72 }
73 
74 namespace details
75 {
76 
77 // It has to be a macro because the debugger needs __debugbreak
78 // breaks on the frame with exception pointer.
79 // It can be only used within _ExceptionHolder
80 #ifndef _REPORT_PPLTASK_UNOBSERVED_EXCEPTION
81 #define _REPORT_PPLTASK_UNOBSERVED_EXCEPTION() do { \
82  ReportUnhandledError(); \
83  __debugbreak(); \
84  Concurrency::details::_ReportUnobservedException(); \
85 } while(false)
86 
87 #endif
88 
89  template<typename _T>
90  struct _AutoDeleter
91  {
92  _AutoDeleter(_T *_PPtr) : _Ptr(_PPtr) {}
93  ~_AutoDeleter () { delete _Ptr; }
94  _T *_Ptr;
95  };
96 
98  {
100  {
101  this->m_pFunction = &Concurrency::details::_UnrealizedChore::_InvokeBridge<_TaskProcHandle>;
102  this->_SetRuntimeOwnsLifetime(true);
103  }
104 
105  virtual ~_TaskProcHandle() {}
106  virtual void invoke() const = 0;
107 
108  void operator()() const
109  {
110  this->invoke();
111  }
112 
113  static void __cdecl _RunChoreBridge(void * _Parameter)
114  {
115  auto _PTaskHandle = static_cast<_TaskProcHandle *>(_Parameter);
117  _PTaskHandle->invoke();
118  }
119  };
120 
121  // This is an abstraction that is built on top of the scheduler to provide these additional functionalities
122  // - Ability to wait on a work item
123  // - Ability to cancel a work item
124  // - Ability to inline work on invocation of RunAndWait
125  // The concrt specific implementation provided the following additional features
126  // - Interoperate with concrt task groups and ppl parallel_for algorithms for cancellation
127  // - Stack guard
128  // - Determine if the current task is cancelled
130  {
131  public:
132 
134 
136  : _M_pTaskCollection(nullptr), _M_pScheduler(_PScheduler)
137  {
138  }
139 
141  {
142  if (_M_pTaskCollection != nullptr)
143  {
145  _M_pTaskCollection = nullptr;
146  }
147  }
148 
149  void _ScheduleTask(_TaskProcHandle_t* _Parameter, _TaskInliningMode _InliningMode)
150  {
151  if (!_M_pScheduler)
152  {
153  // Construct the task collection; We use none token to provent it becoming interruption point.
155  }
156 
157  try
158  {
159  if (_M_pTaskCollection != nullptr)
160  {
161  // Do not need to check its returning state, more details please refer to _Wait method.
162  auto _PChore = static_cast< ::Concurrency::details::_UnrealizedChore*>(_Parameter);
163  _M_pTaskCollection->_ScheduleWithAutoInline(_PChore, _InliningMode);
164  }
165  else
166  {
167  // Schedule the work on the user provided scheduler
168  if (_InliningMode == _ForceInline)
169  {
171  }
172  else
173  {
174  _M_pScheduler->schedule(_TaskProcHandle_t::_RunChoreBridge, _Parameter);
175  }
176  }
177  }
178  catch(...)
179  {
180  _SetScheduled();
181  throw;
182  }
183 
184  // Set the event in case anyone is waiting to notify that this task has been scheduled. In the case where we
185  // execute the chore inline, the event should be set after the chore has executed, to prevent a different thread
186  // performing a wait on the task from waiting on the task collection before the chore is actually added to it,
187  // and thereby returning from the wait() before the chore has executed.
188  _SetScheduled();
189  }
190 
191  void _Cancel()
192  {
193  // Ensure that RunAndWait makes progress.
194  _SetScheduled();
195 
196  if (_M_pTaskCollection != nullptr)
197  {
199  }
200  }
201 
202  void _RunAndWait()
203  {
204  _M_Scheduled.wait();
205 
206  if (_M_pTaskCollection != nullptr)
207  {
208  // When it returns cancelled, either work chore or the cancel thread should already have set task's state
209  // properly -- cancelled state or completed state (because there was no interruption point).
210  // For tasks with unwrapped tasks, we should not change the state of current task, since the unwrapped task are still running.
212  }
213  else
214  {
215  _M_Completed.wait();
216  }
217  }
218 
219  void _Wait()
220  {
221  _M_Completed.wait();
222  }
223 
224  void _Complete()
225  {
226  // Ensure that RunAndWait makes progress.
227  _SetScheduled();
228  _M_Completed.set();
229  }
230 
232  {
233  return _M_pScheduler;
234  }
235 
236  // Fire and forget
237  static void _RunTask(TaskProc _Proc, void * _Parameter, _TaskInliningMode _InliningMode)
238  {
240 
241  if (_Guard._ShouldInline(_InliningMode))
242  {
243  _Proc(_Parameter);
244  }
245  else
246  {
247  // Schedule the work on the current scheduler
248  _CurrentScheduler::_ScheduleTask(_Proc, _Parameter);
249  }
250  }
251 
252  static bool __cdecl _Is_cancellation_requested()
253  {
254  // ConcRT scheduler under the hood is using TaskCollection, which is same as task_group
256  }
257 
258  private:
260  {
261  _M_Scheduled.set();
262  }
263 
268  };
269 
270  // For create_async lambdas that return a (non-task) result, we oversubscriber the current task for the duration of the
271  // lambda.
273  {
275  {
277  }
278 
280  {
282  }
283  };
284 
285  typedef ::Concurrency::details::_TaskCollectionImpl _TaskCollection_t;
287  typedef ::Concurrency::details::_Task_generator_oversubscriber _Task_generator_oversubscriber_t;
288 } // details
289 
290 } // Concurrency
291 
292 namespace concurrency = Concurrency;
293 
294 #endif // _PPLCONCRT_H
_T * _Ptr
Definition: pplconcrt.h:94
bool _ShouldInline(_TaskInliningMode _InliningMode) const
Definition: concrt.h:5298
_AsyncTaskCollection * _M_pTaskCollection
Definition: pplconcrt.h:266
::Concurrency::details::_ReentrantBlockingLock recursive_lock_t
Definition: pplconcrt.h:40
This class describes an exception thrown when an invalid operation is performed that is not more accu...
Definition: concrt.h:1705
::Concurrency::details::_TaskInliningMode _TaskInliningMode_t
Definition: pplconcrt.h:286
~_AutoDeleter()
Definition: pplconcrt.h:93
_CRTIMP size_t wait(unsigned int _Timeout=COOPERATIVE_TIMEOUT_INFINITE)
Waits for the event to become signaled.
Async Task collections is a thin wrapper over task collection to cater to the execution of asynchrono...
Definition: concrt.h:5321
static _CRTIMP void __cdecl _ScheduleTask(TaskProc _Proc, void *_Data)
Concurrency::details::_TaskProcHandle _TaskProcHandle_t
Definition: pplconcrt.h:133
#define _CRTIMP
Definition: crtdefs.h:23
TaskProc m_pFunction
Definition: concrt.h:4313
Definition: concrt.h:5277
_TaskCollectionImpl(::Concurrency::scheduler_ptr _PScheduler)
Definition: pplconcrt.h:135
_CRTIMP long __cdecl GetCurrentThreadId()
_TaskCollectionStatus _RunAndWait()
A cancellation friendly wrapper with which to execute _PChore and then waits for all chores running i...
Definition: concrt.h:5399
void(__cdecl * TaskProc)(void *)
Concurrency::details contains definitions of support routines in the public namespaces and one or mor...
Definition: concrt.h:265
RAII wrapper used to maintain and limit ppltask maximum inline schedule depth. This class will keep a...
Definition: concrt.h:5284
::Concurrency::details::_Task_generator_oversubscriber _Task_generator_oversubscriber_t
Definition: pplconcrt.h:287
_TaskCollectionStatus _ScheduleWithAutoInline(_UnrealizedChore *_PChore, _TaskInliningMode _InliningMode)
Schedule a chore with automatic inlining. The chore is pushed onto the associated workstealing queue...
Definition: concrt.h:5353
_TaskProcHandle()
Definition: pplconcrt.h:99
_CRTIMP2 bool __cdecl is_current_task_group_canceling()
Returns an indication of whether the task group which is currently executing inline on the current co...
Definition: pplconcrt.h:97
The Concurrency namespace provides classes and functions that provide access to the Concurrency Runti...
Definition: agents.h:42
::Concurrency::event event_t
Definition: pplconcrt.h:31
::Concurrency::reader_writer_lock reader_writer_lock_t
Definition: pplconcrt.h:36
~_TaskCollectionImpl()
Definition: pplconcrt.h:140
void _SetRuntimeOwnsLifetime(bool fValue)
Definition: concrt.h:4347
recursive_lock_t::_Scoped_lock scoped_recursive_lock_t
Definition: pplconcrt.h:41
_Task_generator_oversubscriber()
Definition: pplconcrt.h:274
~_Task_generator_oversubscriber()
Definition: pplconcrt.h:279
::Concurrency::scheduler_ptr _M_pScheduler
Definition: pplconcrt.h:267
_CRTIMP void set()
Signals the event.
_TaskInliningMode
The enum defines inlining scheduling policy for ppltasks. Scheduling a chore or a functor with _TaskI...
Definition: concrt.h:5270
::Concurrency::reader_writer_lock::scoped_lock_read scoped_read_lock_t
Definition: pplconcrt.h:38
_CRTIMP size_t __cdecl CaptureCallstack(void **stackData, size_t skipFrames, size_t captureFrames)
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:328
static void _RunTask(TaskProc _Proc, void *_Parameter, _TaskInliningMode _InliningMode)
Definition: pplconcrt.h:237
void _RunAndWait()
Definition: pplconcrt.h:202
void set_ambient_scheduler(std::shared_ptr< ::Concurrency::scheduler_interface > _Scheduler)
Definition: pplconcrt.h:69
::Concurrency::critical_section critical_section_t
Definition: pplconcrt.h:33
_CRTIMP2 unsigned int __cdecl GetNextAsyncId()
static bool __cdecl _Is_cancellation_requested()
Definition: pplconcrt.h:252
Represents a pointer to a scheduler. This class exists to allow the the specification of a shared lif...
Definition: pplinterface.h:58
void _Complete()
Definition: pplconcrt.h:224
virtual void invoke() const =0
static _CRTIMP _AsyncTaskCollection *__cdecl _NewCollection(_CancellationTokenState *_PTokenState)
Constructs a new task collection whose cancellation is governed by the specified cancellation token s...
void _ScheduleTask(_TaskProcHandle_t *_Parameter, _TaskInliningMode _InliningMode)
Definition: pplconcrt.h:149
::Concurrency::extensibility::event_t _M_Completed
Definition: pplconcrt.h:265
static _CRTIMP void __cdecl _Oversubscribe(bool _BeginOversubscription)
void _Cancel()
Cancels work on the task collection.
Definition: concrt.h:5381
#define _T(x)
Definition: tchar.h:2498
Definition: pplconcrt.h:90
::Concurrency::extensibility::event_t _M_Scheduled
Definition: pplconcrt.h:264
::Concurrency::reader_writer_lock::scoped_lock scoped_rw_lock_t
Definition: pplconcrt.h:37
#define _CRTIMP2
Definition: crtdefs.h:126
_AutoDeleter(_T *_PPtr)
Definition: pplconcrt.h:92
long _Release()
Definition: concrt.h:4180
::Concurrency::details::_TaskCollectionImpl _TaskCollection_t
Definition: pplconcrt.h:285
A manual reset event which is explicitly aware of the Concurrency Runtime.
Definition: concrt.h:3982
critical_section_t::scoped_lock scoped_critical_section_t
Definition: pplconcrt.h:34
::Concurrency::scheduler_ptr _GetScheduler() const
Definition: pplconcrt.h:231
An exception safe RAII wrapper for a critical_section object.
Definition: concrt.h:3661
virtual ~_TaskProcHandle()
Definition: pplconcrt.h:105
std::shared_ptr< ::Concurrency::scheduler_interface > get_ambient_scheduler()
Definition: pplconcrt.h:64
void _SetScheduled()
Definition: pplconcrt.h:259
void _Cancel()
Definition: pplconcrt.h:191
void _Wait()
Definition: pplconcrt.h:219
void operator()() const
Definition: pplconcrt.h:108
static void __cdecl _RunChoreBridge(void *_Parameter)
Definition: pplconcrt.h:113