source: nrEngine/src/IThread.cpp @ 12

Revision 12, 5.4 KB checked in by art, 13 years ago (diff)
  • Friendly thread execution added (yielding of threads and main thread)
  • Test directory added, where simple test programms will be build
  • Each Makefile now contains the TOPDIR variable
RevLine 
[1]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        {
[11]27                //mThread = NULL;
[1]28                mThreadState = THREAD_STOP;
29        }
30
31        //--------------------------------------------------------------------
32        IThread::~IThread()
33        {
34                // delete the thread object if it is not empty
[11]35                //if (mThread){
36                        //delete mThread;
37                //}
[1]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
[12]51                // initialise the attribute
52                pthread_attr_init(&mThreadAttr);
53
[11]54                // create the joinable attribute for thsi thread
[12]55                pthread_attr_setdetachstate(&mThreadAttr, PTHREAD_CREATE_JOINABLE);
[11]56
[12]57                // setup thread scheduling attribute
58                pthread_attr_setschedpolicy(&mThreadAttr, SCHED_RR);
59                /*if ( pthread_attr_setschedparam(&mThreadAttr, &param1) != 0 ) {
60                        printf("pthread_attr_setschedparam failed");
61                        exit(0);
62                }*/
63               
[1]64                // now create a thread and let it run
65                mThreadState = THREAD_RUNNING;
[12]66                int res = pthread_create(&mThread, &mThreadAttr, IThread::run, (void *)this);
[11]67                if (res){
68                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: creation of a thread failed with error code %d", res);
69                        return;
70                }
71   
[1]72        }
73
74        //--------------------------------------------------------------------
75        void IThread::threadStop()
76        {
[11]77                // change state
[1]78                changeState(THREAD_STOP);
[11]79
80                // join the thread to the main process
81                //mThread->join();
[12]82                pthread_attr_destroy(&mThreadAttr);
[11]83                int res = pthread_join(mThread, NULL);
84                if (res){
85                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: can not join running thread (error code %d)", res);
86                        return;
87                }
[1]88        }
89
90        //--------------------------------------------------------------------
91        void IThread::threadSuspend()
92        {
93                changeState(THREAD_NEXT_SUSPEND);
94        }
95
96        //--------------------------------------------------------------------
97        void IThread::threadResume()
98        {
99                changeState(THREAD_NEXT_RESUME);
100        }
101
102        //--------------------------------------------------------------------
103        void IThread::changeState(ThreadState newState)
104        {
105                // first lock the mutex and then change the state
[11]106                /*try{
[1]107                        boost::mutex::scoped_lock lock(mMutex);
108                        mThreadState = newState;
109                }catch (boost::lock_error err) {}
[11]110                */
111
112                // lock the mutex change status and unlock it again
113                //pthread_mutex_lock(&mMutex);
114                mThreadState = newState;
115                //pthread_mutex_unlock(&mMutex);
116               
[1]117        }
118
119        //--------------------------------------------------------------------
[12]120        void IThread::yield(IThread* mythread)
121        {
122                // use pthread to yield the timeslice
123                pthread_yield();
124        }
125
126        //--------------------------------------------------------------------
[11]127        void* IThread::run(void* _mythread)
[1]128        {
[11]129                // try to cast the given parameter to IThread pointer
130                IThread* mythread = static_cast<IThread*>(_mythread);
131                if (mythread == NULL)
132                {
133                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: not valid parameter was specified for IThread::run(void*) method");
134                        return NULL;
135                }
136               
[1]137                // now loop the thread until some messages occurs
138                bool run = true;
139                while (run){
140
141                        // kernel requested to suspend the thread
142                        if (mythread->mThreadState == THREAD_NEXT_SUSPEND)
143                        {
144                                // notice about suspending and go into sleep mode
145                                mythread->changeState(THREAD_SLEEPING);
146                                mythread->_noticeSuspend();
147
148                        // kernel requested to resume the execution
149                        }else if (mythread->mThreadState == THREAD_NEXT_RESUME)
150                        {
151                                // notice about resuming the work and start it again
152                                mythread->changeState(THREAD_RUNNING);
153                                mythread->_noticeResume();
154
155                        // kernel does not requested anything, so run the task
156                        }else if (mythread->mThreadState == THREAD_RUNNING)
157                        {
158                                mythread->_noticeUpdate();
159                        }
160
161                        // check for the stop message, then stop the thread
162                        // this is a reading mutex, so do not have to lock it
163                        run = mythread->mThreadState != THREAD_STOP;
[12]164
165                        // we now yield the used timeslice for another threads
166                        yield(mythread);
[1]167                }
[11]168               
[1]169                // notice to stop the underlying task
170                mythread->_noticeStop();
[11]171
172                // exit the thread
173                pthread_exit(NULL);
[1]174        }
175
176}; // end namespace
177
Note: See TracBrowser for help on using the repository browser.