source: nrEngine/src/IThread.cpp @ 14

Revision 14, 5.2 KB checked in by art, 13 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14//----------------------------------------------------------------------------------
15// Includes
16//----------------------------------------------------------------------------------
17#include "IThread.h"
18#include "EventManager.h"
19#include "Log.h"
20#include <boost/bind.hpp>
21
22namespace nrEngine{
23
24        //--------------------------------------------------------------------
25        IThread::IThread()// : EventActor(std::string("Thread_") + boost::lexical_cast<std::string>(id))
26        {
27                //mThread = NULL;
28                mThreadState = THREAD_STOP;
29        }
30
31        //--------------------------------------------------------------------
32        IThread::~IThread()
33        {
34                // delete the thread object if it is not empty
35                //if (mThread){
36                        //delete mThread;
37                //}
38        }
39
40        //--------------------------------------------------------------------
41        void IThread::threadStart()
42        {
43                // Check if we have already a thread created
44                /*if (mThread)
45                {
46                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "IThread: the appropriate thread is already running!");
47                        return;
48                }*/
49                NR_Log(Log::LOG_KERNEL, "IThread: Create thread and start it");
50
51                // initialise the attribute
52                /*pthread_attr_init(&mThreadAttr);
53
54                // create the joinable attribute for thsi thread
55                pthread_attr_setdetachstate(&mThreadAttr, PTHREAD_CREATE_JOINABLE);
56
57                // setup thread scheduling attribute
58                pthread_attr_setschedpolicy(&mThreadAttr, SCHED_RR);
59               
60                // now create a thread and let it run
61                mThreadState = THREAD_RUNNING;
62                int res = pthread_create(&mThread, &mThreadAttr, IThread::run, (void *)this);
63                if (res){
64                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: creation of a thread failed with error code %d", res);
65                        return;
66                }*/
67   
68        }
69
70        //--------------------------------------------------------------------
71        void IThread::threadStop()
72        {
73                // change state
74                changeState(THREAD_STOP);
75
76                // join the thread to the main process
77                /*pthread_attr_destroy(&mThreadAttr);
78                int res = pthread_join(mThread, NULL);
79                if (res){
80                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: can not join running thread (error code %d)", res);
81                        return;
82                }*/
83        }
84
85        //--------------------------------------------------------------------
86        void IThread::threadSuspend()
87        {
88                changeState(THREAD_NEXT_SUSPEND);
89        }
90
91        //--------------------------------------------------------------------
92        void IThread::threadResume()
93        {
94                changeState(THREAD_NEXT_RESUME);
95        }
96
97        //--------------------------------------------------------------------
98        void IThread::changeState(ThreadState newState)
99        {
100                // first lock the mutex and then change the state
101                /*try{
102                        boost::mutex::scoped_lock lock(mMutex);
103                        mThreadState = newState;
104                }catch (boost::lock_error err) {}
105                */
106
107                // lock the mutex change status and unlock it again
108                //pthread_mutex_lock(&mMutex);
109                mThreadState = newState;
110                //pthread_mutex_unlock(&mMutex);
111               
112        }
113
114        //--------------------------------------------------------------------
115        void IThread::yield(IThread* mythread)
116        {
117                // use pthread to yield the timeslice
118                //pthread_yield();
119        }
120
121        //--------------------------------------------------------------------
122        void* IThread::run(void* _mythread)
123        {
124                // try to cast the given parameter to IThread pointer
125                IThread* mythread = static_cast<IThread*>(_mythread);
126                if (mythread == NULL)
127                {
128                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: not valid parameter was specified for IThread::run(void*) method");
129                        return NULL;
130                }
131               
132                // now loop the thread until some messages occurs
133                bool run = true;
134                while (run){
135
136                        // kernel requested to suspend the thread
137                        if (mythread->mThreadState == THREAD_NEXT_SUSPEND)
138                        {
139                                // notice about suspending and go into sleep mode
140                                mythread->changeState(THREAD_SLEEPING);
141                                mythread->_noticeSuspend();
142
143                        // kernel requested to resume the execution
144                        }else if (mythread->mThreadState == THREAD_NEXT_RESUME)
145                        {
146                                // notice about resuming the work and start it again
147                                mythread->changeState(THREAD_RUNNING);
148                                mythread->_noticeResume();
149
150                        // kernel does not requested anything, so run the task
151                        }else if (mythread->mThreadState == THREAD_RUNNING)
152                        {
153                                mythread->_noticeUpdate();
154                        }
155
156                        // check for the stop message, then stop the thread
157                        // this is a reading mutex, so do not have to lock it
158                        run = mythread->mThreadState != THREAD_STOP;
159
160                        // we now yield the used timeslice for another threads
161                        yield(mythread);
162                }
163               
164                // notice to stop the underlying task
165                mythread->_noticeStop();
166
167                // exit the thread
168                pthread_exit(NULL);
169        }
170
171}; // end namespace
172
Note: See TracBrowser for help on using the repository browser.