source: titan/titan/timerthread.h @ 23185

Last change on this file since 23185 was 23185, checked in by nit, 11 years ago

[titan] increase stacksize for threads

File size: 5.5 KB
Line 
1#ifndef TIMERTHREAD_H
2#define TIMERTHREAD_H
3
4struct stimerthread* gettimerbythread(pthread_t thread)
5{
6        //debug(1000, "in");
7        struct stimerthread *node = NULL;
8
9        m_lock(&status.timerthreadmutex, 6);
10        node = stimerthread;
11        while(node != NULL)
12        {
13                if(node->thread == thread)
14                {
15                        m_unlock(&status.timerthreadmutex, 6);
16                        //debug(1000, "out");
17                        return node;
18                }
19
20                node = node->next;
21        }
22
23        m_unlock(&status.timerthreadmutex, 6);
24        //debug(1000, "out");
25        return NULL;
26}
27
28struct stimerthread* gettimer(struct stimerthread* timernode)
29{
30        //debug(1000, "in");
31        struct stimerthread *node = NULL;
32
33        m_lock(&status.timerthreadmutex, 6);
34        node = stimerthread;
35        while(node != NULL)
36        {
37                if(node == timernode)
38                {
39                        m_unlock(&status.timerthreadmutex, 6);
40                        //debug(1000, "out");
41                        return node;
42                }
43
44                node = node->next;
45        }
46
47        m_unlock(&status.timerthreadmutex, 6);
48        debug(100, "timerthread not found (timer=%p)", timernode);
49        return NULL;
50}
51
52struct stimerthread* addtimer(void* func, int aktion, int delay, int count, void* param1, void* param2, struct stimerthread* last)
53{
54        debug(1000, "in");
55        struct stimerthread *newnode = NULL, *prev = NULL, *node = NULL;
56
57        newnode = (struct stimerthread*)calloc(1, sizeof(struct stimerthread));
58        if(newnode == NULL)
59        {
60                err("no memory");
61                return NULL;
62        }
63
64        newnode->func = func;
65        newnode->aktion = aktion;
66        newnode->delay = delay;
67        newnode->count = count;
68        newnode->param1 = param1;
69        newnode->param2 = param2;
70
71        m_lock(&status.timerthreadmutex, 6);
72        node = stimerthread;
73 
74        if(last == NULL)
75        {
76                while(node != NULL)
77                {
78                        prev = node;
79                        node = node->next;
80                }
81        }
82        else
83        {
84                prev = last;
85                node = last->next;
86        }
87
88        if(prev == NULL)
89                stimerthread = newnode;
90        else
91                prev->next = newnode;
92        newnode->next = node;
93
94        m_unlock(&status.timerthreadmutex, 6);
95        debug(1000, "out");
96        return newnode;
97}
98
99//flag 0: lock
100//flag 1: no lock
101void deltimer(struct stimerthread *tnode, int flag)
102{
103        debug(1000, "in");
104        int i = 0;
105        void* threadstatus;
106
107        if(flag == 0) m_lock(&status.timerthreadmutex, 6);
108        struct stimerthread *node = stimerthread, *prev = stimerthread;
109
110        while(node != NULL)
111        {
112                if(node == tnode)
113                {
114                        //stop timer sub thread
115                        node->aktion = STOP;
116                        while(node->status != DEACTIVE)
117                        {
118                                usleep(100000);
119                                i++; if(i > 50) break;
120                        }
121
122                        if(i > 50)
123                        {
124                                err("detect hanging timer sub thread");
125                        }
126                        else //only free mem if we can stop thread
127                        {
128                                if(node->thread != '\0')
129                                        pthread_join(node->thread, &threadstatus);
130                                pthread_attr_destroy(&node->attr);
131
132                                if(node == stimerthread)
133                                        stimerthread = node->next;
134                                else
135                                        prev->next = node->next;
136
137                                free(node);
138                                node = NULL;
139                        }
140                        break;
141                }
142
143                prev = node;
144                node = node->next;
145        }
146
147        if(flag == 0) m_unlock(&status.timerthreadmutex, 6);
148        debug(1000, "out");
149}
150
151//flag 0 = stop all
152//flag 1 = stop only threads with thread->flag bit 0 = 1
153void freetimer(int flag)
154{
155        debug(1000, "in");
156        struct stimerthread *node = stimerthread, *prev = stimerthread;
157
158        while(node != NULL)
159        {
160                prev = node;
161                node = node->next;
162                if(prev != NULL)
163                {
164                        if(flag == 0)
165                                deltimer(prev, 0);
166                        else if(flag == 1 && checkbit(prev->flag, 0) == 1)
167                                deltimer(prev, 0);
168                }
169        }
170        debug(1000, "out");
171}
172
173void* timerthreadsubfunc(void *param)
174{
175        debug(1000, "in");
176        int count = 0;
177        struct stimerthread* node = (struct stimerthread*)param;
178
179        if(param == NULL)
180        {
181                debug(1000, "out -> NULL detect");
182                pthread_exit(NULL);
183        }
184
185        node->status = ACTIVE;
186        while(node->aktion != STOP)
187        {
188                if(node->aktion != PAUSE)
189                {
190                        node->status = ACTIVE;
191                        node->func(node, node->param1, node->param2);
192                        node->notfirst = 1;
193                        if(node->count > -1 && node->aktion != PAUSE) node->count--;
194                        if(node->count == 0) break;
195                }
196                else
197                        node->status = INPAUSE;
198
199                if(node->delay > 1000)
200                {
201                        count = node->delay;
202                        while(count > 1000)
203                        {
204                                usleep(1000000);
205                                count = count - 1000;
206                                if(node->aktion == STOP || node->aktion == PAUSE) count = 0;
207                        }
208                        usleep(count);
209                }
210                else
211                        usleep(node->delay * 1000);
212        }
213
214        node->aktion = STOP;
215        node->status = DEACTIVE;
216
217        debug(1000, "out");
218        pthread_exit(NULL);
219}
220
221void* timerthreadfunc(void *param)
222{
223        debug(1000, "in");
224        int ret = 0;
225        struct stimerthread* node = NULL;
226        //struct sched_param schedparam;
227
228        //set timer threads scheduler priority
229        //schedparam.sched_priority = 0;
230        //pthread_setschedparam(pthread_self(), SCHED_OTHER, &schedparam);
231
232        status.timerthreadstatus = ACTIVE;
233        while(status.timerthreadaktion != STOP)
234        {
235                if(status.timerthreadaktion != PAUSE)
236                {
237                        status.timerthreadstatus = ACTIVE;
238
239                        m_lock(&status.timerthreadmutex, 6);
240                        node = stimerthread;
241                        while(node != NULL)
242                        {
243                                if(node->status == DEACTIVE && node->aktion == STOP && node->count == 0)
244                                {
245                                        struct stimerthread* prev = node;
246                                        node = node->next;
247                                        deltimer(prev, 1);
248                                        continue;
249                                }
250
251                                if(node->status == DEACTIVE && node->aktion == START && node->count != 0)
252                                {
253                                        pthread_attr_init(&node->attr);
254                                        pthread_attr_setstacksize(&node->attr, 151552);
255                                        pthread_attr_setdetachstate(&node->attr, PTHREAD_CREATE_JOINABLE);
256                                        node->status = ACTIVE;
257                                        debug(10, "start timer sub thread");
258                                        ret = pthread_create(&node->thread, &node->attr, timerthreadsubfunc, (void*)node);
259                                        if(ret)
260                                        {
261                                                node->status = ERROR;
262                                                perr("create timer sub thread");
263                                                pthread_attr_destroy(&node->attr);
264                                        }
265                                }
266                                node = node->next;
267                        }
268                        m_unlock(&status.timerthreadmutex, 6);
269
270                }
271                else
272                        status.timerthreadstatus = INPAUSE;
273
274                usleep(1 * 1000000);
275        }
276        status.timerthreadstatus = DEACTIVE;
277
278        debug(1000, "out");
279        pthread_exit(NULL);
280}
281
282#endif
Note: See TracBrowser for help on using the repository browser.