Terrific, so what does gmThread look like?
Wasn't sure whether you'd want it all pasted! Here it is:
Code:/// \class gmThread /// \brief gmThread.. try to keep this class's memory footprint small.. at the time of this comment, its /// 76 bytes. class gmThread : public gmListDoubleNode<gmThread>, public gmHashNode<int, gmThread> { public: gmThread(gmMachine * a_machine, int a_initialByteSize = GMTHREAD_INITIALBYTESIZE); virtual ~gmThread(); enum State { RUNNING = 0, SLEEPING, BLOCKED, KILLED, EXCEPTION, //!< exception state, for debugging SYS_PENDING, SYS_YIELD, SYS_EXCEPTION, }; inline const int GetKey() const { return m_id; } #if GM_USE_INCGC void GCScanRoots(gmMachine* a_machine, gmGarbageCollector* a_gc); #else //GM_USE_INCGC /// \brief Mark() will call Mark() for all objects in the stack. void Mark(gmuint32 a_mark); #endif //GM_USE_INCGC /// \brief Sys_Execute() will perform execution on this thread. a this, function references, params and stack /// frame must be pushed before a call to execute will succeed. /// \param a_return will be set to the return variable iff Sys_Execute returns gmThread::KILLED. /// \return the new thread state. State Sys_Execute(gmVariable * a_return = NULL); /// \brief Sys_Reset() will reset the thread. void Sys_Reset(int a_id); /// \brief Sys_SetState() will set the thread state. inline void Sys_SetState(State a_state) { m_state = a_state; } /// \brief PushStackFrame will push a stack frame and adjust the instruction and code pointers. /// If the function to be called is a c bound function, the call will occur within PushStackFrame. /// Before PushStackFrame is called, this, fp, and params must be pushed on the stack. /// \param a_numParameters is the number of params pushed after the function ref. /// \param a_ip is the current instruction pointer (pointing to instruction after call.) will be adjusted for new function. /// \param a_cp is the current code pointer. will be adjusted for the new function. a_cp MUST be valid if a_ip is valid. /// \return gmThreadState State PushStackFrame(int a_numParameters, const gmuint8 ** a_ip = NULL, const gmuint8 ** a_cp = NULL); . . . etc.
This, with changes in red, compiles with gcc 3.4.2 with "g++ -Wall -pedantic -ansi -c xx.cpp"
With an embedded compiler, I get a problem because Nullify() for gmListDoubleNode<T> doesn't have a member function Nullify(). Probably declared in the "GM_INCLUDE_ITERATOR(T)" part, which I don't have.
Code:#define NULL 0 template <class T> class gmListDoubleNode; /// \class gmListDouble /// \brief Templated intrusive doubly linked list using a sentinal node template <class T> class gmListDouble { public: /// \class Iterator class Iterator { public: // GM_INCLUDE_ITERATOR_KERNEL(T) inline Iterator() { m_node = NULL; m_list = NULL; } inline Iterator(T * a_node, const gmListDouble * a_list) { m_node = a_node; m_list = a_list; } inline void Inc() { m_node = m_list->GetNext(m_node); } inline void Dec() { m_node = m_list->GetPrev(m_node); } inline bool IsValid() const { return (m_list && m_list->IsValid(m_node)); } private: T * m_node; const gmListDouble * m_list; }; // methods inline gmListDouble(); inline ~gmListDouble(); inline void InsertAfter(T * a_cursor, T * a_elem); inline bool IsValid(const T* a_elem) const { return (a_elem != &m_sentinel); } inline T* GetFirst() const { return (T*) m_sentinel.m_next; } inline T* GetLast() const { return (T*) m_sentinel.m_prev; } inline T* GetNext(const T* a_elem) const { return (T*) a_elem->gmListDoubleNode<T>::m_next; } inline T* GetPrev(const T* a_elem) const { return (T*) a_elem->gmListDoubleNode<T>::m_prev; } inline bool IsEmpty() const { return (m_sentinel.m_next == &m_sentinel); } inline Iterator First(void) const { return Iterator(static_cast<T*>(m_sentinel.m_next), this); } inline Iterator Last(void) const { return Iterator(static_cast<T*>(m_sentinel.m_prev), this); } private: class gmListDoubleNode<T> m_sentinel; }; /// \class gmListDoubleNode /// \brief intrusive node, must inherit this class templated to your class template <class T> class gmListDoubleNode { public: inline gmListDoubleNode() {} /// \brief Remove from list. Allows node to unlink from unknown list. inline void RemoveAndNullify() { m_next->m_prev = m_prev; m_prev->m_next = m_next; this->Nullify(); } private: gmListDoubleNode * m_next; gmListDoubleNode * m_prev; friend class gmListDouble<T>; };
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
What happens if you remove the <T> and change :: to ->?
Code:inline T* GetNext(const T* a_elem) const { return (T*) a_elem->gmListDoubleNode->m_next; }