source: titan/titan/timerthread.h @ 37145

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

[titan] cleanup

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