[Scummvm-git-logs] scummvm master -> 542742e2aa7d088330d3e970a1910ce29b9f080f
elasota
noreply at scummvm.org
Sat Aug 24 19:13:48 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
542742e2aa MTROPOLIS: Refactor VThread to use statically-located stacks
Commit: 542742e2aa7d088330d3e970a1910ce29b9f080f
https://github.com/scummvm/scummvm/commit/542742e2aa7d088330d3e970a1910ce29b9f080f
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-08-24T15:11:48-04:00
Commit Message:
MTROPOLIS: Refactor VThread to use statically-located stacks
Changed paths:
engines/mtropolis/vthread.cpp
engines/mtropolis/vthread.h
diff --git a/engines/mtropolis/vthread.cpp b/engines/mtropolis/vthread.cpp
index 14cf5ba18c7..aa477d0cdf3 100644
--- a/engines/mtropolis/vthread.cpp
+++ b/engines/mtropolis/vthread.cpp
@@ -29,6 +29,26 @@ VThreadTaskData::VThreadTaskData() {
VThreadTaskData::~VThreadTaskData() {
}
+VThreadStackChunk::VThreadStackChunk(size_t capacity)
+ : _memory(nullptr), _size(capacity), _topFrame(nullptr) {
+
+ _memory = static_cast<byte *>(malloc(capacity));
+ if (!_memory)
+ error("Out of memory");
+}
+
+VThreadStackChunk::VThreadStackChunk(VThreadStackChunk &&other)
+ : _memory(other._memory), _size(other._size), _topFrame(other._topFrame) {
+ other._memory = nullptr;
+ other._size = 0;
+ other._topFrame = nullptr;
+}
+
+VThreadStackChunk::~VThreadStackChunk() {
+ if (_memory)
+ free(_memory);
+}
+
#ifdef MTROPOLIS_DEBUG_ENABLE
void VThreadTaskData::debugInit(const char *name) {
_debugName = name;
@@ -39,176 +59,145 @@ void VThreadTaskData::debugInspect(IDebugInspectionReport *report) const {
#endif
VThread::VThread()
- : _faultID(nullptr), _stackUnalignedBase(nullptr), _stackAlignedBase(nullptr), /* _size(0), */_alignment(1), _used(0)
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- , _topFrame(nullptr)
-#endif
+ : _numActiveStackChunks(0)
{
}
VThread::~VThread() {
- void *dataPtr;
- void *framePtr;
- while (popFrame(dataPtr, framePtr)) {
- static_cast<VThreadStackFrame *>(framePtr)->~VThreadStackFrame();
- static_cast<VThreadTaskData *>(dataPtr)->~VThreadTaskData();
+ while (popFrame()) {
}
-
- if (_stackUnalignedBase)
- free(_stackUnalignedBase);
}
VThreadState VThread::step() {
- void *dataPtr;
- void *framePtr;
- while (popFrame(dataPtr, framePtr)) {
- VThreadTaskData *data = static_cast<VThreadTaskData *>(dataPtr);
-
- VThreadStackFrame *stackFrame = static_cast<VThreadStackFrame *>(framePtr);
-
- const bool isHandling = (data->handlesFault(_faultID));
- stackFrame->~VThreadStackFrame();
- if (isHandling) {
- _faultID = nullptr;
- VThreadState state = data->destructAndRunTask();
- if (state != kVThreadReturn)
- return state;
- } else {
- static_cast<VThreadTaskData *>(dataPtr)->~VThreadTaskData();
- }
+ while (hasTasks()) {
+ VThreadStackFrame *frame = _stackChunks[_numActiveStackChunks - 1]._topFrame;
+
+ VThreadState state = frame->data->execute(this);
+ if (state != kVThreadReturn)
+ return state;
}
return kVThreadReturn;
}
bool VThread::hasTasks() const {
- return _used > 0;
+ return _numActiveStackChunks > 0;
}
-void VThread::reserveFrame(size_t size, size_t alignment, void *&outFramePtr, void *&outUnadjustedDataPtr, size_t &outPrevFrameOffset) {
- const size_t frameAlignment = alignof(VThreadStackFrame);
- const size_t frameAlignmentMask = frameAlignment - 1;
+bool VThread::reserveFrameInChunk(VThreadStackChunk *chunk, size_t frameAlignment, size_t frameSize, VThreadStackFrame *&outFramePtr, size_t dataAlignment, size_t dataSize, void *&outDataPtr) {
+ VThreadStackFrame *framePtr = nullptr;
+ void *dataPtr = nullptr;
- size_t dataAlignmentMask = alignment - 1;
+ uintptr address = 0;
+ size_t bytesAvailable = 0;
- bool needToReallocate = false;
- if (alignment > _alignment || frameAlignment > _alignment) {
- if ((reinterpret_cast<uintptr>(_stackAlignedBase) & dataAlignmentMask) != 0) {
- needToReallocate = true;
- }
+ if (chunk->_topFrame) {
+ address = reinterpret_cast<uintptr>(chunk->_topFrame);
+ bytesAvailable = static_cast<size_t>(reinterpret_cast<const byte *>(chunk->_topFrame) - chunk->_memory);
+ } else {
+ address = reinterpret_cast<uintptr>(chunk->_memory + chunk->_size);
+ bytesAvailable = chunk->_size;
}
- size_t dataAlignmentPaddingNeeded = (alignment - (_used & dataAlignmentMask));
- if (dataAlignmentPaddingNeeded == alignment)
- dataAlignmentPaddingNeeded = 0;
+ if (bytesAvailable < dataSize)
+ return false;
- size_t offsetOfData = dataAlignmentPaddingNeeded + _used;
- size_t offsetOfEndOfData = offsetOfData + size;
- size_t frameAlignmentPaddingNeeded = (frameAlignment - (offsetOfData & frameAlignmentMask));
- if (frameAlignmentPaddingNeeded == frameAlignment)
- frameAlignmentPaddingNeeded = 0;
+ bytesAvailable -= dataSize;
+ address -= dataSize;
- size_t offsetOfFrame = offsetOfEndOfData + frameAlignmentPaddingNeeded;
- size_t offsetOfEndOfFrame = offsetOfFrame + sizeof(VThreadStackFrame);
+ size_t dataAlignPadding = static_cast<size_t>(dataAlignment % dataAlignment);
- size_t offsetOfPrevFrame = 0;
- if (_used > 0)
- offsetOfPrevFrame = _used - sizeof(VThreadStackFrame);
+ if (bytesAvailable < dataAlignPadding)
+ return false;
- if (offsetOfEndOfFrame > _used)
- needToReallocate = true;
+ bytesAvailable -= dataAlignPadding;
+ address -= dataAlignPadding;
- if (needToReallocate) {
- size_t maxAlignment = alignment;
- if (maxAlignment < frameAlignment)
- maxAlignment = frameAlignment;
+ dataPtr = reinterpret_cast<void *>(address);
- void *unalignedBase = malloc(offsetOfEndOfFrame + maxAlignment - 1);
- size_t alignPadding = maxAlignment - (reinterpret_cast<uintptr>(unalignedBase) % maxAlignment);
- if (alignPadding == maxAlignment)
- alignPadding = 0;
+ if (bytesAvailable < frameSize)
+ return false;
- void *alignedBase = static_cast<char *>(unalignedBase) + alignPadding;
+ bytesAvailable -= frameSize;
+ address -= frameSize;
- // Copy the previous frames
- size_t framePos = 0;
- if (_used > 0) {
- framePos = _used - sizeof(VThreadStackFrame);
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- VThreadStackFrame *nextFrame = nullptr;
-#endif
+ size_t frameAlignPadding = static_cast<size_t>(address % frameAlignment);
- while (framePos != 0) {
- VThreadStackFrame *oldFrame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(_stackAlignedBase) + framePos);
- size_t dataPos = oldFrame->taskDataOffset;
- VThreadTaskData *oldData = reinterpret_cast<VThreadTaskData *>(static_cast<char *>(_stackAlignedBase) + dataPos);
- size_t nextPos = oldFrame->prevFrameOffset;
+ if (bytesAvailable < frameAlignPadding)
+ return false;
- VThreadStackFrame *newFrame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(alignedBase) + framePos);
- VThreadTaskData *newData = reinterpret_cast<VThreadTaskData *>(static_cast<char *>(alignedBase) + dataPos);
+ bytesAvailable -= frameAlignPadding;
+ address -= frameAlignPadding;
- // Relocate the frame
- new (newFrame) VThreadStackFrame(*oldFrame);
- oldFrame->~VThreadStackFrame();
+ framePtr = reinterpret_cast<VThreadStackFrame *>(address);
- // Relocate the data
- oldData->relocateTo(newData);
- oldData->~VThreadTaskData();
+ chunk->_topFrame = framePtr;
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- newFrame->data = newData;
- newFrame->prevFrame = nullptr;
- if (nextFrame)
- nextFrame->prevFrame = newFrame;
+ outDataPtr = dataPtr;
+ outFramePtr = framePtr;
- nextFrame = newFrame;
-#endif
+ return true;
+}
+
+void VThread::reserveFrame(size_t frameAlignment, size_t frameSize, VThreadStackFrame *&outFramePtr, size_t dataAlignment, size_t dataSize, void *&outDataPtr, bool &outIsNewChunk) {
+ // See if this fits in the last active chunk
+ if (_numActiveStackChunks > 0) {
+ VThreadStackChunk &lastChunk = _stackChunks[_numActiveStackChunks - 1];
- framePos = nextPos;
- }
+ if (reserveFrameInChunk(&lastChunk, frameAlignment, frameSize, outFramePtr, dataAlignment, dataSize, outDataPtr)) {
+ outIsNewChunk = false;
+ return;
}
+ }
- if (_stackUnalignedBase)
- free(_stackUnalignedBase);
+ // Didn't fit, this is the first one in the chunk
+ size_t requiredSize = (frameAlignment - 1) + (dataAlignment - 1) + frameSize + dataSize;
- _stackUnalignedBase = unalignedBase;
- _stackAlignedBase = alignedBase;
+ if (_numActiveStackChunks >= _stackChunks.size() || _stackChunks[_numActiveStackChunks]._size < requiredSize) {
+ // Doesn't fit in the next chunk, deallocate the chunk and all subsequent chunks and reallocate
+
+ const size_t kChunkMinSize = 1024 * 1024; // 1MB chunks
+ size_t chunkSize = requiredSize;
+ if (chunkSize < kChunkMinSize)
+ chunkSize = kChunkMinSize;
+
+ while (_stackChunks.size() > _numActiveStackChunks)
+ _stackChunks.pop_back();
+
+ _stackChunks.push_back(VThreadStackChunk(chunkSize));
}
- VThreadStackFrame *newFrame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(_stackAlignedBase) + offsetOfFrame);
- void *newData = static_cast<char *>(_stackAlignedBase) + offsetOfData;
- _used = offsetOfEndOfFrame;
+ VThreadStackChunk &lastChunk = _stackChunks[_numActiveStackChunks++];
- outFramePtr = newFrame;
- outUnadjustedDataPtr = newData;
- outPrevFrameOffset = offsetOfPrevFrame;
+ bool reservedOK = reserveFrameInChunk(&lastChunk, frameAlignment, frameSize, outFramePtr, dataAlignment, dataSize, outDataPtr);
+ assert(reservedOK);
+ (void)reservedOK;
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- _topFrame = newFrame;
-#endif
+ outIsNewChunk = true;
}
-bool VThread::popFrame(void *&dataPtr, void *&outFramePtr) {
- if (_used == 0)
+bool VThread::popFrame() {
+ if (_numActiveStackChunks == 0)
return false;
- VThreadStackFrame *frame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(_stackAlignedBase) + _used - sizeof(VThreadStackFrame));
- VThreadTaskData *data = reinterpret_cast<VThreadTaskData *>(static_cast<char *>(_stackAlignedBase) + frame->taskDataOffset);
+ VThreadStackChunk &lastChunk = _stackChunks[_numActiveStackChunks - 1];
+ VThreadStackFrame *topFrame = lastChunk._topFrame;
- dataPtr = data;
- outFramePtr = frame;
+ VThreadStackFrame *secondFrame = topFrame->prevFrame;
+ bool isLastFrameInChunk = topFrame->isLastInChunk;
- if (frame->prevFrameOffset == 0)
- _used = 0;
- else
- _used = frame->prevFrameOffset + sizeof(VThreadStackFrame);
+ if (isLastFrameInChunk) {
+ lastChunk._topFrame = nullptr;
+ _numActiveStackChunks--;
+ } else {
+ assert(reinterpret_cast<byte *>(secondFrame) >= lastChunk._memory);
+ assert(reinterpret_cast<byte *>(secondFrame) < lastChunk._memory + lastChunk._size);
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- if (_used == 0)
- _topFrame = nullptr;
- else
- _topFrame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(_stackAlignedBase) + frame->prevFrameOffset);
-#endif
+ lastChunk._topFrame = secondFrame;
+ }
+
+ topFrame->data->~VThreadTaskData();
+ topFrame->~VThreadStackFrame();
return true;
}
diff --git a/engines/mtropolis/vthread.h b/engines/mtropolis/vthread.h
index 96518fb3eea..96e99154b27 100644
--- a/engines/mtropolis/vthread.h
+++ b/engines/mtropolis/vthread.h
@@ -26,6 +26,8 @@
namespace MTropolis {
+class VThread;
+
// Virtual thread, really a task stack
enum VThreadState {
kVThreadReturn,
@@ -49,9 +51,7 @@ public:
VThreadTaskData();
virtual ~VThreadTaskData();
- virtual VThreadState destructAndRunTask() = 0;
- virtual void relocateTo(void *newPosition) = 0;
- virtual bool handlesFault(const VThreadFaultIdentifier *faultID) const = 0;
+ virtual VThreadState execute(VThread *thread) = 0;
#ifdef MTROPOLIS_DEBUG_ENABLE
public:
@@ -67,14 +67,27 @@ protected:
#endif
};
-struct VThreadStackFrame {
- size_t taskDataOffset; // Offset to VThreadTaskData
- size_t prevFrameOffset;
+struct VThreadStackFrame;
+
+class VThreadStackChunk {
+public:
+ explicit VThreadStackChunk(size_t capacity);
+ VThreadStackChunk(VThreadStackChunk &&other);
+ ~VThreadStackChunk();
+
+ VThreadStackFrame *_topFrame;
+ byte *_memory;
+ size_t _size;
+
+private:
+ VThreadStackChunk() = delete;
+ VThreadStackChunk(const VThreadStackChunk &) = delete;
+};
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
+struct VThreadStackFrame {
VThreadTaskData *data;
VThreadStackFrame *prevFrame;
-#endif
+ bool isLastInChunk;
};
template<typename TClass, typename TData>
@@ -84,9 +97,7 @@ public:
VThreadMethodData(const VThreadMethodData &other);
VThreadMethodData(VThreadMethodData &&other);
- VThreadState destructAndRunTask() override;
- void relocateTo(void *newPosition) override;
- bool handlesFault(const VThreadFaultIdentifier *faultID) const override;
+ VThreadState execute(VThread *thread) override;
TData &getData();
@@ -106,9 +117,7 @@ public:
VThreadFunctionData(VThreadFunctionData &&other);
- VThreadState destructAndRunTask() override;
- void relocateTo(void *newPosition) override;
- bool handlesFault(const VThreadFaultIdentifier *faultID) const override;
+ VThreadState execute(VThread *thread) override;
TData &getData();
@@ -119,7 +128,6 @@ private:
};
class VThread {
-
public:
VThread();
~VThread();
@@ -130,36 +138,24 @@ public:
template<typename TData>
TData *pushTask(const char *name, VThreadState (*func)(const TData &data));
- template<typename TFaultType, typename TClass, typename TData>
- TData *pushFaultHandler(const char *name, TClass *obj, VThreadState (TClass::*method)(const TData &data));
-
- template<typename TFaultType, typename TData>
- TData *pushFaultHandler(const char *name, VThreadState (*func)(const TData &data));
-
VThreadState step();
bool hasTasks() const;
+ bool popFrame();
+
private:
+ void reserveFrame(size_t frameAlignment, size_t frameSize, VThreadStackFrame *&outFramePtr, size_t dataAlignment, size_t dataSize, void *&outDataPtr, bool &outIsNewChunk);
+ static bool reserveFrameInChunk(VThreadStackChunk *chunk, size_t frameAlignment, size_t frameSize, VThreadStackFrame *&outFramePtr, size_t dataAlignment, size_t dataSize, void *&outDataPtr);
+
template<typename TClass, typename TData>
TData *pushTaskWithFaultHandler(const VThreadFaultIdentifier *faultID, const char *name, TClass *obj, VThreadState (TClass::*method)(const TData &data));
template<typename TData>
TData *pushTaskWithFaultHandler(const VThreadFaultIdentifier *faultID, const char *name, VThreadState (*func)(const TData &data));
- void reserveFrame(size_t size, size_t alignment, void *&outFramePtr, void *&outUnadjustedDataPtr, size_t &outPrevFrameOffset);
- bool popFrame(void *&dataPtr, void *&outFramePtr);
-
- void *_stackUnalignedBase;
- void *_stackAlignedBase;
- //size_t _size;
- size_t _alignment;
- size_t _used;
- VThreadFaultIdentifier *_faultID;
-
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- const VThreadStackFrame *_topFrame;
-#endif
+ Common::Array<VThreadStackChunk> _stackChunks;
+ uint _numActiveStackChunks;
};
template<typename TClass, typename TData>
@@ -178,29 +174,17 @@ VThreadMethodData<TClass, TData>::VThreadMethodData(VThreadMethodData &&other)
}
template<typename TClass, typename TData>
-VThreadState VThreadMethodData<TClass, TData>::destructAndRunTask() {
+VThreadState VThreadMethodData<TClass, TData>::execute(VThread *thread) {
TData data(static_cast<TData &&>(_data));
TClass *target = _target;
VThreadState (TClass::*method)(const TData &) = _method;
- this->~VThreadMethodData<TClass, TData>();
+ thread->popFrame();
return (target->*method)(data);
}
-template<typename TClass, typename TData>
-void VThreadMethodData<TClass, TData>::relocateTo(void *newPosition) {
- void *adjustedPtr = static_cast<VThreadMethodData<TClass, TData> *>(static_cast<VThreadTaskData *>(newPosition));
-
- new (adjustedPtr) VThreadMethodData<TClass, TData>(static_cast<VThreadMethodData<TClass, TData> &&>(*this));
-}
-
-template<typename TClass, typename TData>
-bool VThreadMethodData<TClass, TData>::handlesFault(const VThreadFaultIdentifier* faultID) const {
- return _faultID == faultID;
-}
-
template<typename TClass, typename TData>
TData &VThreadMethodData<TClass, TData>::getData() {
return _data;
@@ -222,28 +206,16 @@ VThreadFunctionData<TData>::VThreadFunctionData(VThreadFunctionData &&other)
}
template<typename TData>
-VThreadState VThreadFunctionData<TData>::destructAndRunTask() {
+VThreadState VThreadFunctionData<TData>::execute(VThread *thread) {
TData data(static_cast<TData &&>(_data));
VThreadState (*func)(const TData &) = _func;
- this->~VThreadFunctionData<TData>();
+ thread->popFrame();
return func(data);
}
-template<typename TData>
-void VThreadFunctionData<TData>::relocateTo(void *newPosition) {
- void *adjustedPtr = static_cast<VThreadFunctionData<TData> *>(static_cast<VThreadTaskData *>(newPosition));
-
- new (adjustedPtr) VThreadFunctionData<TData>(static_cast<VThreadFunctionData<TData> &&>(*this));
-}
-
-template<typename TData>
-bool VThreadFunctionData<TData>::handlesFault(const VThreadFaultIdentifier *faultID) const {
- return _faultID == faultID;
-}
-
template<typename TData>
TData &VThreadFunctionData<TData>::getData() {
return _data;
@@ -259,44 +231,29 @@ TData *VThread::pushTask(const char *name, VThreadState (*func)(const TData &dat
return this->pushTaskWithFaultHandler(nullptr, name, func);
}
-template<typename TFaultType, typename TClass, typename TData>
-TData *VThread::pushFaultHandler(const char *name, TClass *obj, VThreadState (TClass::*method)(const TData &data)) {
- return this->pushTaskWithFaultHandler(&VThreadFaultIdentifierSingleton<TFaultType>::_identifier, name, obj, method);
-}
-
-template<typename TFaultType, typename TData>
-TData *VThread::pushFaultHandler(const char *name, VThreadState (*func)(const TData &data)) {
- return this->pushTaskWithFaultHandler(&VThreadFaultIdentifierSingleton<TFaultType>::_identifier, name, func);
-}
-
-
template<typename TClass, typename TData>
TData *VThread::pushTaskWithFaultHandler(const VThreadFaultIdentifier *faultID, const char *name, TClass *obj, VThreadState (TClass::*method)(const TData &data)) {
typedef VThreadMethodData<TClass, TData> FrameData_t;
const size_t frameAlignment = alignof(VThreadStackFrame);
const size_t dataAlignment = alignof(FrameData_t);
- const size_t maxAlignment = (frameAlignment < dataAlignment) ? dataAlignment : frameAlignment;
- void *framePtr;
- void *dataPtr;
- size_t prevFrameOffset;
- reserveFrame(sizeof(FrameData_t), maxAlignment, framePtr, dataPtr, prevFrameOffset);
+ VThreadStackFrame *prevFrame = nullptr;
+ if (_numActiveStackChunks > 0)
+ prevFrame = _stackChunks[_numActiveStackChunks - 1]._topFrame;
- VThreadStackFrame *frame = new (framePtr) VThreadStackFrame();
- frame->prevFrameOffset = prevFrameOffset;
+ VThreadStackFrame *framePtr = nullptr;
+ void *dataPtr = nullptr;
+ bool isNewChunk = false;
+ reserveFrame(frameAlignment, sizeof(VThreadStackFrame), framePtr, dataAlignment, sizeof(FrameData_t), dataPtr, isNewChunk);
+ VThreadStackFrame *frame = new (framePtr) VThreadStackFrame();
FrameData_t *frameData = new (dataPtr) FrameData_t(faultID, obj, method);
- frame->taskDataOffset = reinterpret_cast<char *>(static_cast<VThreadTaskData *>(frameData)) - static_cast<char *>(_stackAlignedBase);
-
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- if (frame->prevFrameOffset == 0)
- frame->prevFrame = nullptr;
- else
- frame->prevFrame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(_stackAlignedBase) + prevFrameOffset);
frame->data = frameData;
-#endif
+ frame->prevFrame = prevFrame;
+ frame->isLastInChunk = isNewChunk;
+
#ifdef MTROPOLIS_DEBUG_ENABLE
frameData->debugInit(name);
#endif
@@ -310,27 +267,23 @@ TData *VThread::pushTaskWithFaultHandler(const VThreadFaultIdentifier *faultID,
const size_t frameAlignment = alignof(VThreadStackFrame);
const size_t dataAlignment = alignof(FrameData_t);
- const size_t maxAlignment = (frameAlignment < dataAlignment) ? dataAlignment : frameAlignment;
- void *framePtr;
- void *dataPtr;
- size_t prevFrameOffset;
- reserveFrame(sizeof(FrameData_t), maxAlignment, framePtr, dataPtr, prevFrameOffset);
+ VThreadStackFrame *prevFrame = nullptr;
+ if (_numActiveStackChunks > 0)
+ prevFrame = _stackChunks[_numActiveStackChunks - 1]._topFrame;
- VThreadStackFrame *frame = new (framePtr) VThreadStackFrame();
- frame->prevFrameOffset = prevFrameOffset;
+ VThreadStackFrame *framePtr = nullptr;
+ void *dataPtr = nullptr;
+ bool isNewChunk = false;
+ reserveFrame(frameAlignment, sizeof(VThreadStackFrame), framePtr, dataAlignment, sizeof(FrameData_t), dataPtr, isNewChunk);
+ VThreadStackFrame *frame = new (framePtr) VThreadStackFrame();
FrameData_t *frameData = new (dataPtr) FrameData_t(faultID, func);
- frame->taskDataOffset = reinterpret_cast<char *>(static_cast<VThreadTaskData *>(frameData)) - static_cast<char *>(_stackAlignedBase);
-
-#ifdef MTROPOLIS_DEBUG_VTHREAD_STACKS
- if (frame->prevFrameOffset == 0)
- frame->prevFrame = nullptr;
- else
- frame->prevFrame = reinterpret_cast<VThreadStackFrame *>(static_cast<char *>(_stackAlignedBase) + prevFrameOffset);
frame->data = frameData;
-#endif
+ frame->prevFrame = prevFrame;
+ frame->isLastInChunk = isNewChunk;
+
#ifdef MTROPOLIS_DEBUG_ENABLE
frameData->debugInit(name);
#endif
More information about the Scummvm-git-logs
mailing list