RavEngine
Loading...
Searching...
No Matches
CmTask.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef CM_TASK_H
30#define CM_TASK_H
31
32#include "task/PxTask.h"
33#include "foundation/PxUserAllocated.h"
34#include "foundation/PxAtomic.h"
35#include "foundation/PxMutex.h"
36#include "foundation/PxInlineArray.h"
37#include "foundation/PxFPU.h"
38
39namespace physx
40{
41namespace Cm
42{
43 // wrapper around the public PxLightCpuTask
44 // internal SDK tasks should be inherited from
45 // this and override the runInternal() method
46 // to ensure that the correct floating point
47 // state is set / reset during execution
49 {
50 public:
51 Task(PxU64 contextId)
52 {
53 mContextID = contextId;
54 }
55
56 virtual void run()
57 {
58#if PX_SWITCH // special case because default rounding mode is not nearest
59 PX_FPU_GUARD;
60#else
61 PX_SIMD_GUARD;
62#endif
63 runInternal();
64 }
65
66 virtual void runInternal()=0;
67 };
68
69 // same as Cm::Task but inheriting from physx::PxBaseTask
70 // instead of PxLightCpuTask
72 {
73 public:
74
75 virtual void run()
76 {
77#if PX_SWITCH // special case because default rounding mode is not nearest
78 PX_FPU_GUARD;
79#else
80 PX_SIMD_GUARD;
81#endif
82 runInternal();
83 }
84
85 virtual void runInternal()=0;
86 };
87
88 template <class T, void (T::*Fn)(physx::PxBaseTask*) >
89 class DelegateTask : public Cm::Task, public PxUserAllocated
90 {
91 public:
92
93 DelegateTask(PxU64 contextID, T* obj, const char* name) : Cm::Task(contextID), mObj(obj), mName(name) {}
94
95 virtual void run()
96 {
97#if PX_SWITCH // special case because default rounding mode is not nearest
98 PX_FPU_GUARD;
99#else
100 PX_SIMD_GUARD;
101#endif
102 (mObj->*Fn)(mCont);
103 }
104
105 virtual void runInternal()
106 {
107 (mObj->*Fn)(mCont);
108 }
109
110 virtual const char* getName() const
111 {
112 return mName;
113 }
114
115 void setObject(T* obj) { mObj = obj; }
116
117 private:
118 T* mObj;
119 const char* mName;
120 };
121
122
132 {
133 PX_NOCOPY(FanoutTask)
134 public:
135 FanoutTask(PxU64 contextID, const char* name) : Cm::BaseTask(), mRefCount(0), mName(name), mNotifySubmission(false) { mContextID = contextID; }
136
137 virtual void runInternal() {}
138
139 virtual const char* getName() const { return mName; }
140
144 virtual void removeReference()
145 {
146 PxMutex::ScopedLock lock(mMutex);
147 if (!physx::PxAtomicDecrement(&mRefCount))
148 {
149 // prevents access to mReferencesToRemove until release
150 physx::PxAtomicIncrement(&mRefCount);
151 mNotifySubmission = false;
152 PX_ASSERT(mReferencesToRemove.empty());
153 for (PxU32 i = 0; i < mDependents.size(); i++)
154 mReferencesToRemove.pushBack(mDependents[i]);
155 mDependents.clear();
157 }
158 }
159
163 virtual void addReference()
164 {
165 PxMutex::ScopedLock lock(mMutex);
166 physx::PxAtomicIncrement(&mRefCount);
167 mNotifySubmission = true;
168 }
169
174 {
175 return mRefCount;
176 }
177
182 {
183 mTm = &tm;
184 }
185
191 {
192 PxMutex::ScopedLock lock(mMutex);
193 physx::PxAtomicIncrement(&mRefCount);
194 mTm = dependent.getTaskManager();
195 mDependents.pushBack(&dependent);
196 dependent.addReference();
197 mNotifySubmission = true;
198 }
199
204 virtual void release()
205 {
206 PxInlineArray<physx::PxBaseTask*, 10> referencesToRemove;
207
208 {
209 PxMutex::ScopedLock lock(mMutex);
210
211 const PxU32 contCount = mReferencesToRemove.size();
212 referencesToRemove.reserve(contCount);
213 for (PxU32 i=0; i < contCount; ++i)
214 referencesToRemove.pushBack(mReferencesToRemove[i]);
215
216 mReferencesToRemove.clear();
217 // allow access to mReferencesToRemove again
218 if (mNotifySubmission)
219 {
221 }
222 else
223 {
224 physx::PxAtomicDecrement(&mRefCount);
225 }
226
227 // the scoped lock needs to get freed before the continuation tasks get (potentially) submitted because
228 // those continuation tasks might trigger events that delete this task and corrupt the memory of the
229 // mutex (for example, assume this task is a member of the scene then the submitted tasks cause the simulation
230 // to finish and then the scene gets released which in turn will delete this task. When this task then finally
231 // continues the heap memory will be corrupted.
232 }
233
234 for (PxU32 i=0; i < referencesToRemove.size(); ++i)
235 referencesToRemove[i]->removeReference();
236 }
237
238 protected:
239 volatile PxI32 mRefCount;
240 const char* mName;
242 PxInlineArray<physx::PxBaseTask*, 4> mReferencesToRemove;
243 bool mNotifySubmission;
244 PxMutex mMutex; // guarding mDependents and mNotifySubmission
245 };
246
247
251 template <class T, void (T::*Fn)(physx::PxBaseTask*) >
253 {
254 public:
255 DelegateFanoutTask(PxU64 contextID, T* obj, const char* name) :
256 FanoutTask(contextID, name), mObj(obj) { }
257
258 virtual void runInternal()
259 {
260 physx::PxBaseTask* continuation = mReferencesToRemove.empty() ? NULL : mReferencesToRemove[0];
261 (mObj->*Fn)(continuation);
262 }
263
264 void setObject(T* obj) { mObj = obj; }
265
266 private:
267 T* mObj;
268 };
269
270} // namespace Cm
271
272}
273
274#endif
Definition CmTask.h:72
virtual void run()
The user-implemented run method where the task's work should be performed.
Definition CmTask.h:75
Specialization of FanoutTask class in order to provide the delegation mechanism.
Definition CmTask.h:253
Definition CmTask.h:90
virtual const char * getName() const
Return a user-provided task name for profiling purposes.
Definition CmTask.h:110
virtual void run()
The user-implemented run method where the task's work should be performed.
Definition CmTask.h:95
A task that maintains a list of dependent tasks.
Definition CmTask.h:132
virtual void addReference()
Increases reference count.
Definition CmTask.h:163
PX_INLINE void setTaskManager(physx::PxTaskManager &tm)
Definition CmTask.h:181
virtual void release()
Definition CmTask.h:204
virtual void removeReference()
Definition CmTask.h:144
virtual const char * getName() const
Return a user-provided task name for profiling purposes.
Definition CmTask.h:139
PX_INLINE PxI32 getReference() const
Return the ref-count for this task.
Definition CmTask.h:173
PX_INLINE void addDependent(physx::PxBaseTask &dependent)
Definition CmTask.h:190
Definition CmTask.h:49
virtual void run()
The user-implemented run method where the task's work should be performed.
Definition CmTask.h:56
PX_FORCE_INLINE uint32_t size() const
Definition PxArray.h:242
PX_INLINE void clear()
Definition PxArray.h:250
PX_FORCE_INLINE bool empty() const
Definition PxArray.h:261
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
PX_INLINE void reserve(const uint32_t capacity)
Definition PxArray.h:486
Base class of all task types.
Definition PxTask.h:45
virtual void addReference()=0
Implemented by derived implementation classes.
PxU64 mContextID
Context ID for profiler interface.
Definition PxTask.h:97
PX_FORCE_INLINE PxTaskManager * getTaskManager() const
Return PxTaskManager to which this task was submitted.
Definition PxTask.h:88
PxTaskManager * mTm
Owning PxTaskManager instance.
Definition PxTask.h:98
virtual void submitTask(PxBaseTask &task)=0
Called by the TaskManager when a task is to be queued for execution.
Definition PxInlineArray.h:43
A PxBaseTask implementation with immediate execution and simple dependencies.
Definition PxTask.h:209
PxBaseTask * mCont
Continuation task, can be NULL.
Definition PxTask.h:306
Definition PxMutex.h:93
Definition PxMutex.h:89
The PxTaskManager interface.
Definition PxTaskManager.h:81
virtual PxCpuDispatcher * getCpuDispatcher() const =0
Get the user-provided dispatcher object for CPU tasks.
Definition PxUserAllocated.h:43
#define PX_INLINE
Definition PxPreprocessor.h:320
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39