source: nrEngine/include/IThread.h @ 14

Revision 14, 7.7 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#ifndef _NR_I_THREAD_H_
15#define _NR_I_THREAD_H_
16
17//----------------------------------------------------------------------------------
18// Includes
19//----------------------------------------------------------------------------------
20#include "Prerequisities.h"
21
22//#include <pthread.h>
23               
24namespace nrEngine{
25
26        //! Abstract class to run a ITask in a thread controlled by Kernel
27        /**
28         * IThread is a base class for each kin dof tasks, allows also parallel
29         * running of a task as a thread. Kernel tasks are derived from thi class
30         * so a task has also a possibility to run in a own thread. Kernel
31         * controls the creation and managing of threads. Threads communicate
32         * through the engine's default communication protocol.
33         *
34         * Writing a task as a thread for your application is not a big issue.
35         * You have to listen on kernel messages coming on the engine's default
36         * channel to be able to react on stop/suspend/resume messages. Kernel
37         * can not simply hold on a task. Because this can corrupt data if a task was
38         * performing any important calculations. Also this is not a good style.
39         * Kernel will provide a function to force a killing of a thread-task, but
40         * prevent using of this function.
41         *
42         * Instead of killing the running threads, kernel will send a message about
43         * stopping the thread. A thread-task should react on this event to
44         * gracefully stop the execution.
45         *
46         * The thread interface does provide neccessary functions to your tasks, so
47         * you do not have to think about managing the kernel messages by yourself.
48         * Instead of this the thread will call taskStop() method to indicate the task,
49         * that kernel want to stop the thread. Suspending the task will cause the kernel
50         * to let the according thread sleeping until the task is resumed. There is
51         * no other way how you can let the task sleep.
52         *
53         * So how the thread interface cooperate with the kernel and the task interface.
54         * You write your task in the way, like if it were a simple task running
55         * sequentially in the kernel. Each ITask itnerface is a derived class from
56         * IThread but a thread portion of the code will only be active if you use the task
57         * as a thread for the kernel. By marking the task as a thread i.e. by adding
58         * the task to the kernel as a thread, you will activate the thread interface automatic.
59         * Kernel will start the thread and will call the taskInit() and taskStart() functions
60         * at the right moment. If the task is a thread, so it will call threadStart() instead
61         * which will call thread_taskStart() method of derived ITask interface. The method
62         * will call your taskStart() method, so you will not notice if there is a difference
63         * between starting a task as a task or as a thread.
64         *
65         * In each cycle the kernel does call taskUpdate() method for sequential tasks. For
66         * parallel tasks (threads) it does not call anything, because thread interface already
67         * running and it will automaticaly call the appropritate taskUpdate() method, so
68         * the task is getting updated. Also the thread base class does check if there is
69         * any messages from the kernel (i.e. sleep or stop). If so it will call appropriate
70         * methods in ITask interface.
71         *
72         * Our threads does yield their time slice to another threads after each execution cycle.
73         * In this manner we get a friendly and intuitive behaviour of threads running in parallel.
74         *
75         * NOTE: The IThread interaface and Kernel does do all the job for you to manage
76         * themself as a threads and to let them run in parallel. The only one thing it
77         * can not manage for you is synchronisation. You have to worry about this by yourself
78         * by using of mutex locking mechanism.
79         *
80         * \ingroup kernel
81        **/
82        class _NRExport IThread{
83                public:
84                        /**
85                         * Virtual destructor so we are able to derive classes
86                         * with overloaded methods.
87                         **/
88                        virtual ~IThread();
89
90                protected:
91
92                        /**
93                         * Protected constructor, so only the ITask-Interface
94                         * and friends are able to create an instance of this class.
95                         * In this way we protect wrong usage of this interface.
96                         **/
97                        IThread();
98
99                        /**
100                         * Call this method if a thread goes into sleep mode. The derived
101                         * task should reimplement this method to call the appropriate suspend
102                         * method
103                         **/
104                        virtual void _noticeSuspend() = 0;
105
106                        /**
107                         * Call this method by waking up a thread. The derived task interface
108                         * should call the appropritate resume method
109                         **/
110                        virtual void _noticeResume() = 0;
111
112                        /**
113                         * Thread does call this method in a main loop. The method
114                         * should call the appropritate update method in ITask interface
115                         **/
116                        virtual void _noticeUpdate() = 0;
117
118                        /**
119                         * Call this method by stopping the execution of a thread. The underlying
120                         * task has to remove all used data, because after calling of this method
121                         * it will be destroyed
122                         **/
123                        virtual void _noticeStop() = 0;
124
125                private:
126
127                        /**
128                         * This is a entry point for a thread. The method is
129                         * static because it do not have to access any data
130                         * of the object itself. The given thread instance as a parameter
131                         * will be updated and managed as a thread.
132                         **/
133                        static void* run(void* mythread);
134
135                        //! Kernel is a friend class
136                        friend class Kernel;
137
138                        /**
139                         * Call the appropriate yield method of the threading library.
140                         * The thread calling this method will yield its remaining timeslice
141                         * to other threads.
142                         *
143                         * @param mythread Pointer to the thread which yields.
144                         *              If NULL specified, so the called thread will be yield.
145                         **/
146                        static void yield(IThread* mythread = NULL);
147                       
148                        /**
149                         * Kernel does call this method if the appropriate task is running
150                         * as a thread in the kernel. This method manage the derived class by calling appropriate
151                         * virtual methods, which has to be reimplemented in the ITask interface.
152                         **/
153                        void threadStart();
154
155                        /**
156                         * Kernel does call this method, if a thread should stop.
157                         **/
158                        void threadStop();
159
160                        /**
161                         * Kernel call this method if a thread is going into sleep mode
162                         **/
163                        void threadSuspend();
164
165                        /**
166                         * Kernel call this method if a thread is goind to resume
167                         **/
168                        void threadResume();
169
170                        //! Define thread states
171                        enum ThreadState{
172                                //! Thread is not running it is stopped
173                                THREAD_STOP,
174
175                                //! Thread does running
176                                THREAD_RUNNING,
177
178                                //! Thread is in sleep state (no action, but ready to wakeup)
179                                THREAD_SLEEPING,
180
181                                //! Wakeup the thread as soon as possible
182                                THREAD_NEXT_RESUME,
183
184                                //! Suspend the thread as soon as possible
185                                THREAD_NEXT_SUSPEND
186                        };
187
188                        //! This is a variable which will manage the thread state
189                        ThreadState     mThreadState;
190
191                        // Mutex to lock the data before use
192                        // pthread_mutex_t mMutex;
193
194                        //! Store here the thread instance
195                        //pthread_t     mThread;
196
197                        //! Thread attributes
198                        //pthread_attr_t mThreadAttr;
199                       
200                        //! Change a thread to new state, use mutex to lock the state
201                        void changeState(ThreadState newState);
202
203        };
204
205}; // end namespace
206#endif  //_NR...
Note: See TracBrowser for help on using the repository browser.