@@ -28,11 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828=============================================================================
2929*/
3030
31- #include " ../Math/Bit.h "
31+ #include < algorithm >
3232
33- #include " ThreadMemory .h"
33+ #include " ../Math/Bit .h"
3434
3535#include " TaskList.h"
36+ #include " ThreadMemory.h"
3637
3738#include " Task.h"
3839
@@ -45,6 +46,18 @@ Task::Task( const Task& other ) {
4546 *this = other;
4647}
4748
49+ const Task& Task::operator *() {
50+ return *this ;
51+ }
52+
53+ const Task* Task::operator ->() const {
54+ return this ;
55+ }
56+
57+ constexpr Task& Task::GetTask () {
58+ return *this ;
59+ }
60+
4861Task& Task::Delay ( const uint64 delay ) {
4962 if ( IsShutdownTask () ) {
5063 Log::Warn ( " Shutdown tasks may not be delayed! (task: %s, delay: %u)" , Execute, delay );
@@ -84,45 +97,131 @@ void Task::Wait() {
8497 }
8598}
8699
100+ void Task::ExecuteDestructors () {
101+ uint8 destructors = argsMap & 255 ;
102+ uint32 offset = 0 ;
103+
104+ while ( destructors ) {
105+ DestructorFunction destructor = *( DestructorFunction* ) ( taskList.GetTaskData ( GetDataOffset () ) + offset );
106+
107+ uint32 arg = FindLSB ( destructors );
108+ destructor ( GetArgMemory ( arg ) );
109+
110+ offset += sizeof ( DestructorFunction );
111+ UnSetBit ( &destructors, arg );
112+ }
113+ }
114+
87115bool Task::IsValid () {
88- return BitSet ( flags, validOffset );
116+ return BitSet ( flags, validOffset );
117+ }
118+
119+ bool Task::IsActive () {
120+ return BitSet ( flags, activeOffset );
89121}
90122
91123bool Task::IsShutdownTask () {
92- return BitSet ( flags, shutdownOffset );
124+ return BitSet ( flags, shutdownOffset );
125+ }
126+
127+ uint8 Task::GetArgCount () {
128+ return GetBits ( flags, argCountOffset, 3 );
129+ }
130+
131+ void Task::SetValid ( const bool valid ) {
132+ valid ? SetBit ( &flags, validOffset ) : UnSetBit ( &flags, validOffset );
133+ }
134+
135+ void Task::SetActive ( const bool active ) {
136+ active ? SetBit ( &flags, activeOffset ) : UnSetBit ( &flags, activeOffset );
137+ }
138+
139+ uint32 Task::RemapArg ( const uint32 arg ) {
140+ return GetBits ( argsMap, arg * argMapArgSize + argMapArgOffset, argMapArgSize );
141+ }
142+
143+ uint64 Task::GetDataOffset () {
144+ return SetBits ( ( uint64 ) dataOffset, ( uint64 ) dataOffset2, 32 , 8 );
145+ }
146+
147+ uint32 Task::SetArgsMap ( Arg* start, Arg* end ) {
148+ uint32 size = 0 ;
149+
150+ for ( Arg* arg = start; arg < end; arg++ ) {
151+ if ( arg > start ) {
152+ dataOffsets[arg - start] = size;
153+ }
154+
155+ size = PAD ( size, arg->size > 8 ? 8 : arg->size ) + arg->size ;
156+ SetBits ( &argsMap, arg - start, arg->id * argMapArgSize + argMapArgOffset, argMapArgSize );
157+
158+ if ( arg->hasDestructor ) {
159+ SetBit ( &argsMap, arg->id );
160+ };
161+ }
162+
163+ SetBits ( &flags, end - start, argCountOffset, 3 );
164+
165+ return CountBits ( argsMap & argMapMask ) * sizeof ( DestructorFunction ) + PAD ( size, 8 );
166+ }
167+
168+ byte* Task::InitMemory ( Arg* start, Arg* end ) {
169+ SetValid ( true );
170+
171+ std::sort ( start, end,
172+ []( const Arg& lhs, const Arg& rhs ) {
173+ return lhs.size > rhs.size ;
174+ }
175+ );
176+
177+ uint32 dataSize = SetArgsMap ( start, end );
178+
179+ uint64 offset;
180+ byte* data = AllocTaskData ( dataSize, &offset );
181+
182+ dataOffset = GetBits ( offset, 0 , 32 );
183+ dataOffset2 = GetBits ( offset, 32 , 8 );
184+
185+ return data;
93186}
94187
95- void Task::SetValid ( const bool valid ) {
96- valid ? SetBit ( &flags, validOffset ) : UnSetBit ( &flags, validOffset ) ;
188+ byte* Task::GetArgMemory ( const uint32 arg ) {
189+ return taskList. GetTaskData ( GetDataOffset () ) + dataOffsets[ RemapArg ( arg )] ;
97190}
98191
99192void Task::operator =( const Task& other ) {
100193 Execute = other.Execute ;
101- data = other.data ;
102-
103194 complete = other.complete ;
104195
105- flags = other.flags ;
196+ dataOffset = other.dataOffset ;
197+ dataOffset2 = other.dataOffset2 ;
106198
107- active = other.active ;
199+ flags = other.flags ;
200+ id = other.id ;
108201
109- eventMask = other.eventMask ;
202+ bufferID = other.bufferID ;
110203
111204 gen = other.gen ;
205+
112206 time = other.time ;
207+ threadMask = other.threadMask ;
113208
114209 dependencyCounter = other.dependencyCounter .load ( std::memory_order_relaxed );
115210 forwardTaskCounter = other.forwardTaskCounter .load ( std::memory_order_relaxed );
116-
117- id = other.id ;
118-
119- bufferID = other.bufferID ;
120- threadMask = other.threadMask ;
121211 threadCount = other.threadCount .load ( std::memory_order_relaxed );
122212
123213 forwardTaskLock = other.forwardTaskLock ;
124214
125- memcpy ( forwardTasks, other.forwardTasks , MAX_FORWARD_TASKS * sizeof ( uint16 ) );
215+ memcpy ( dataOffsets, other.dataOffsets , maxArgCount * sizeof ( uint16 ) );
216+ memcpy ( forwardTasks, other.forwardTasks , maxForwardTasks * sizeof ( uint16 ) );
217+
218+ argsMap = other.argsMap ;
219+ }
220+
221+ TaskProxy::TaskProxy ( Task& newTask ) :
222+ task( newTask ) {
223+ }
126224
127- dataSize = other.dataSize ;
225+ Task* TaskProxy::operator ->() const {
226+ return &task;
128227}
0 commit comments