Import Upstream version 1.2.2
[quagga-debian.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 /* Master of the theads. */
55 struct thread_master
56 {
57   struct thread **read;
58   struct thread **write;
59   struct pqueue *timer;
60   struct thread_list event;
61   struct thread_list ready;
62   struct thread_list unuse;
63   struct pqueue *background;
64   int fd_limit;
65   thread_fd_set readfd;
66   thread_fd_set writefd;
67   thread_fd_set exceptfd;
68   unsigned long alloc;
69 };
70
71 typedef unsigned char thread_type;
72
73 /* Thread itself. */
74 struct thread
75 {
76   thread_type type;             /* thread type */
77   thread_type add_type;         /* thread type */
78   struct thread *next;          /* next pointer of the thread */   
79   struct thread *prev;          /* previous pointer of the thread */
80   struct thread_master *master; /* pointer to the struct thread_master. */
81   int (*func) (struct thread *); /* event function */
82   void *arg;                    /* event argument */
83   union {
84     int val;                    /* second argument of the event. */
85     int fd;                     /* file descriptor in case of read/write. */
86     struct timeval sands;       /* rest of time sands value. */
87   } u;
88   int index;                    /* used for timers to store position in queue */
89   struct timeval real;
90   struct cpu_thread_history *hist; /* cache pointer to cpu_history */
91   const char *funcname;
92   const char *schedfrom;
93   int schedfrom_line;
94 };
95
96 struct cpu_thread_history 
97 {
98   int (*func)(struct thread *);
99   unsigned int total_calls;
100   struct time_stats
101   {
102     unsigned long total, max;
103   } real;
104 #ifdef HAVE_RUSAGE
105   struct time_stats cpu;
106 #endif
107   thread_type types;
108   const char *funcname;
109 };
110
111 /* Clocks supported by Quagga */
112 enum quagga_clkid {
113   QUAGGA_CLK_REALTIME = 0,      /* ala gettimeofday() */
114   QUAGGA_CLK_MONOTONIC,         /* monotonic, against an indeterminate base */
115   QUAGGA_CLK_REALTIME_STABILISED, /* like realtime, but non-decrementing */
116 };
117
118 /* Thread types. */
119 #define THREAD_READ           0
120 #define THREAD_WRITE          1
121 #define THREAD_TIMER          2
122 #define THREAD_EVENT          3
123 #define THREAD_READY          4
124 #define THREAD_BACKGROUND     5
125 #define THREAD_UNUSED         6
126 #define THREAD_EXECUTE        7
127
128 /* Thread yield time.  */
129 #define THREAD_YIELD_TIME_SLOT     10 * 1000L /* 10ms */
130
131 /* Macros. */
132 #define THREAD_ARG(X) ((X)->arg)
133 #define THREAD_FD(X)  ((X)->u.fd)
134 #define THREAD_VAL(X) ((X)->u.val)
135
136 #define THREAD_READ_ON(master,thread,func,arg,sock) \
137   do { \
138     if (! thread) \
139       thread = thread_add_read (master, func, arg, sock); \
140   } while (0)
141
142 #define THREAD_WRITE_ON(master,thread,func,arg,sock) \
143   do { \
144     if (! thread) \
145       thread = thread_add_write (master, func, arg, sock); \
146   } while (0)
147
148 #define THREAD_TIMER_ON(master,thread,func,arg,time) \
149   do { \
150     if (! thread) \
151       thread = thread_add_timer (master, func, arg, time); \
152   } while (0)
153
154 #define THREAD_TIMER_MSEC_ON(master,thread,func,arg,time) \
155   do { \
156     if (! thread) \
157       thread = thread_add_timer_msec (master, func, arg, time); \
158   } while (0)
159
160 #define THREAD_OFF(thread) \
161   do { \
162     if (thread) \
163       { \
164         thread_cancel (thread); \
165         thread = NULL; \
166       } \
167   } while (0)
168
169 #define THREAD_READ_OFF(thread)  THREAD_OFF(thread)
170 #define THREAD_WRITE_OFF(thread)  THREAD_OFF(thread)
171 #define THREAD_TIMER_OFF(thread)  THREAD_OFF(thread)
172
173 #define debugargdef  const char *funcname, const char *schedfrom, int fromln
174
175 #define thread_add_read(m,f,a,v) funcname_thread_add_read(m,f,a,v,#f,__FILE__,__LINE__)
176 #define thread_add_write(m,f,a,v) funcname_thread_add_write(m,f,a,v,#f,__FILE__,__LINE__)
177 #define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f,__FILE__,__LINE__)
178 #define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f,__FILE__,__LINE__)
179 #define thread_add_timer_tv(m,f,a,v) funcname_thread_add_timer_tv(m,f,a,v,#f,__FILE__,__LINE__)
180 #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f,__FILE__,__LINE__)
181 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
182
183 /* The 4th arg to thread_add_background is the # of milliseconds to delay. */
184 #define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f,__FILE__,__LINE__)
185
186 /* Prototypes. */
187 extern struct thread_master *thread_master_create (void);
188 extern void thread_master_free (struct thread_master *);
189
190 extern struct thread *funcname_thread_add_read (struct thread_master *, 
191                                                 int (*)(struct thread *),
192                                                 void *, int, debugargdef);
193 extern struct thread *funcname_thread_add_write (struct thread_master *,
194                                                  int (*)(struct thread *),
195                                                  void *, int, debugargdef);
196 extern struct thread *funcname_thread_add_timer (struct thread_master *,
197                                                  int (*)(struct thread *),
198                                                  void *, long, debugargdef);
199 extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
200                                                       int (*)(struct thread *),
201                                                       void *, long, debugargdef);
202 extern struct thread *funcname_thread_add_timer_tv (struct thread_master *,
203                                                     int (*)(struct thread *),
204                                                     void *, struct timeval *,
205                                                     debugargdef);
206 extern struct thread *funcname_thread_add_event (struct thread_master *,
207                                                  int (*)(struct thread *),
208                                                  void *, int, debugargdef);
209 extern struct thread *funcname_thread_add_background (struct thread_master *,
210                                                int (*func)(struct thread *),
211                                                void *arg,
212                                                long milliseconds_to_delay,
213                                                debugargdef);
214 extern struct thread *funcname_thread_execute (struct thread_master *,
215                                                int (*)(struct thread *),
216                                                void *, int, debugargdef);
217 #undef debugargdef
218
219 extern void thread_cancel (struct thread *);
220 extern unsigned int thread_cancel_event (struct thread_master *, void *);
221 extern struct thread *thread_fetch (struct thread_master *, struct thread *);
222 extern void thread_call (struct thread *);
223 extern unsigned long thread_timer_remain_second (struct thread *);
224 extern struct timeval thread_timer_remain(struct thread*);
225 extern int thread_should_yield (struct thread *);
226 extern unsigned long timeval_elapsed (struct timeval a, struct timeval b);
227
228 /* Internal libzebra exports */
229 extern void thread_getrusage (RUSAGE_T *);
230 extern struct cmd_element show_thread_cpu_cmd;
231 extern struct cmd_element clear_thread_cpu_cmd;
232
233 /* replacements for the system gettimeofday(), clock_gettime() and
234  * time() functions, providing support for non-decrementing clock on
235  * all systems, and fully monotonic on /some/ systems.
236  */
237 extern int quagga_gettime (enum quagga_clkid, struct timeval *);
238 extern time_t quagga_time (time_t *);
239
240 /* Returns elapsed real (wall clock) time. */
241 extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
242                                           unsigned long *cpu_time_elapsed);
243
244 /* Global variable containing a recent result from gettimeofday.  This can
245    be used instead of calling gettimeofday if a recent value is sufficient.
246    This is guaranteed to be refreshed before a thread is called. */
247 extern struct timeval recent_time;
248 /* Similar to recent_time, but a monotonically increasing time value */
249 extern struct timeval recent_relative_time (void);
250
251 /* only for use in logging functions! */
252 extern struct thread *thread_current;
253
254 #endif /* _ZEBRA_THREAD_H */