]> git.proxmox.com Git - mirror_frr.git/blob - lib/thread.h
pimd: merge pimd as of 2015-01-19
[mirror_frr.git] / lib / thread.h
1 /* Thread management routine header.
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #ifndef _ZEBRA_THREAD_H
23 #define _ZEBRA_THREAD_H
24
25 #include <zebra.h>
26
27 struct rusage_t
28 {
29 #ifdef HAVE_RUSAGE
30 struct rusage cpu;
31 #endif
32 struct timeval real;
33 };
34 #define RUSAGE_T struct rusage_t
35
36 #define GETRUSAGE(X) thread_getrusage(X)
37
38 /* Linked list of thread. */
39 struct thread_list
40 {
41 struct thread *head;
42 struct thread *tail;
43 int count;
44 };
45
46 struct pqueue;
47
48 /*
49 * Abstract it so we can use different methodologies to
50 * select on data.
51 */
52 typedef fd_set thread_fd_set;
53
54 #if defined(HAVE_POLL)
55 #include <poll.h>
56 struct fd_handler
57 {
58 /* number of pfd stored in pfds */
59 nfds_t pfdcount;
60 /* number of pfd stored in pfds + number of snmp pfd */
61 nfds_t pfdcountsnmp;
62 /* number of pfd that fit in the allocated space of pfds */
63 nfds_t pfdsize;
64 struct pollfd *pfds;
65 };
66 #else
67 struct fd_handler
68 {
69 fd_set readfd;
70 fd_set writefd;
71 fd_set exceptfd;
72 };
73 #endif
74
75 /* Master of the theads. */
76 struct thread_master
77 {
78 struct thread **read;
79 struct thread **write;
80 struct pqueue *timer;
81 struct thread_list event;
82 struct thread_list ready;
83 struct thread_list unuse;
84 struct pqueue *background;
85 int fd_limit;
86 struct fd_handler handler;
87 unsigned long alloc;
88 };
89
90 typedef unsigned char thread_type;
91
92 /* ISO C99 maximum function name length is 63 */
93 #define FUNCNAME_LEN 64
94
95 /* Thread itself. */
96 struct thread
97 {
98 thread_type type; /* thread type */
99 thread_type add_type; /* thread type */
100 struct thread *next; /* next pointer of the thread */
101 struct thread *prev; /* previous pointer of the thread */
102 struct thread_master *master; /* pointer to the struct thread_master. */
103 int (*func) (struct thread *); /* event function */
104 void *arg; /* event argument */
105 union {
106 int val; /* second argument of the event. */
107 int fd; /* file descriptor in case of read/write. */
108 struct timeval sands; /* rest of time sands value. */
109 } u;
110 int index; /* used for timers to store position in queue */
111 struct timeval real;
112 struct cpu_thread_history *hist; /* cache pointer to cpu_history */
113 unsigned long yield; /* yield time in us */
114 char funcname[FUNCNAME_LEN];
115 };
116
117 struct cpu_thread_history
118 {
119 int (*func)(struct thread *);
120 unsigned int total_calls;
121 struct time_stats
122 {
123 unsigned long total, max;
124 } real;
125 #ifdef HAVE_RUSAGE
126 struct time_stats cpu;
127 #endif
128 thread_type types;
129 char funcname[FUNCNAME_LEN];
130 };
131
132 /* Clocks supported by Quagga */
133 enum quagga_clkid {
134 QUAGGA_CLK_REALTIME = 0, /* ala gettimeofday() */
135 QUAGGA_CLK_MONOTONIC, /* monotonic, against an indeterminate base */
136 QUAGGA_CLK_REALTIME_STABILISED, /* like realtime, but non-decrementing */
137 };
138
139 /* Struct timeval's tv_usec one second value. */
140 #define TIMER_SECOND_MICRO 1000000L
141
142 /* Thread types. */
143 #define THREAD_READ 0
144 #define THREAD_WRITE 1
145 #define THREAD_TIMER 2
146 #define THREAD_EVENT 3
147 #define THREAD_READY 4
148 #define THREAD_BACKGROUND 5
149 #define THREAD_UNUSED 6
150 #define THREAD_EXECUTE 7
151
152 /* Thread yield time. */
153 #define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
154
155 /* Macros. */
156 #define THREAD_ARG(X) ((X)->arg)
157 #define THREAD_FD(X) ((X)->u.fd)
158 #define THREAD_VAL(X) ((X)->u.val)
159
160 #define THREAD_READ_ON(master,thread,func,arg,sock) \
161 do { \
162 if (! thread) \
163 thread = thread_add_read (master, func, arg, sock); \
164 } while (0)
165
166 #define THREAD_WRITE_ON(master,thread,func,arg,sock) \
167 do { \
168 if (! thread) \
169 thread = thread_add_write (master, func, arg, sock); \
170 } while (0)
171
172 #define THREAD_TIMER_ON(master,thread,func,arg,time) \
173 do { \
174 if (! thread) \
175 thread = thread_add_timer (master, func, arg, time); \
176 } while (0)
177
178 #define THREAD_TIMER_MSEC_ON(master,thread,func,arg,time) \
179 do { \
180 if (! thread) \
181 thread = thread_add_timer_msec (master, func, arg, time); \
182 } while (0)
183
184 #define THREAD_OFF(thread) \
185 do { \
186 if (thread) \
187 { \
188 thread_cancel (thread); \
189 thread = NULL; \
190 } \
191 } while (0)
192
193 #define THREAD_READ_OFF(thread) THREAD_OFF(thread)
194 #define THREAD_WRITE_OFF(thread) THREAD_OFF(thread)
195 #define THREAD_TIMER_OFF(thread) THREAD_OFF(thread)
196
197 #define thread_add_read(m,f,a,v) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,#f)
198 #define thread_add_write(m,f,a,v) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,#f)
199 #define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f)
200 #define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f)
201 #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f)
202 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f)
203
204 /* The 4th arg to thread_add_background is the # of milliseconds to delay. */
205 #define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f)
206
207 /* Prototypes. */
208 extern struct thread_master *thread_master_create (void);
209 extern void thread_master_free (struct thread_master *);
210 extern void thread_master_free_unused(struct thread_master *);
211
212 extern struct thread *funcname_thread_add_read_write (int dir, struct thread_master *,
213 int (*)(struct thread *),
214 void *, int, const char*);
215 extern struct thread *funcname_thread_add_timer (struct thread_master *,
216 int (*)(struct thread *),
217 void *, long, const char*);
218 extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
219 int (*)(struct thread *),
220 void *, long, const char*);
221 extern struct thread *funcname_thread_add_event (struct thread_master *,
222 int (*)(struct thread *),
223 void *, int, const char*);
224 extern struct thread *funcname_thread_add_background (struct thread_master *,
225 int (*func)(struct thread *),
226 void *arg,
227 long milliseconds_to_delay,
228 const char *funcname);
229 extern struct thread *funcname_thread_execute (struct thread_master *,
230 int (*)(struct thread *),
231 void *, int, const char *);
232 extern void thread_cancel (struct thread *);
233 extern unsigned int thread_cancel_event (struct thread_master *, void *);
234 extern struct thread *thread_fetch (struct thread_master *, struct thread *);
235 extern void thread_call (struct thread *);
236 extern unsigned long thread_timer_remain_second (struct thread *);
237 extern struct timeval thread_timer_remain(struct thread*);
238 extern int thread_should_yield (struct thread *);
239 extern unsigned long timeval_elapsed (struct timeval a, struct timeval b);
240 /* set yield time for thread */
241 extern void thread_set_yield_time (struct thread *, unsigned long);
242
243 /* Internal libzebra exports */
244 extern void thread_getrusage (RUSAGE_T *);
245 extern struct cmd_element show_thread_cpu_cmd;
246 extern struct cmd_element clear_thread_cpu_cmd;
247
248 /* replacements for the system gettimeofday(), clock_gettime() and
249 * time() functions, providing support for non-decrementing clock on
250 * all systems, and fully monotonic on /some/ systems.
251 */
252 extern int quagga_gettime (enum quagga_clkid, struct timeval *);
253 extern time_t quagga_time (time_t *);
254
255 /* Returns elapsed real (wall clock) time. */
256 extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
257 unsigned long *cpu_time_elapsed);
258
259 /* Global variable containing a recent result from gettimeofday. This can
260 be used instead of calling gettimeofday if a recent value is sufficient.
261 This is guaranteed to be refreshed before a thread is called. */
262 extern struct timeval recent_time;
263 /* Similar to recent_time, but a monotonically increasing time value */
264 extern struct timeval recent_relative_time (void);
265 #endif /* _ZEBRA_THREAD_H */