]> git.proxmox.com Git - mirror_frr.git/blame - lib/thread.h
Add user `frr` into group `frrvty`
[mirror_frr.git] / lib / thread.h
CommitLineData
718e3744 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
5734509c
PJ
25#include <zebra.h>
26
8b70d0b0 27struct rusage_t
28{
8b70d0b0 29 struct rusage cpu;
8b70d0b0 30 struct timeval real;
31};
32#define RUSAGE_T struct rusage_t
33
db9c0df9 34#define GETRUSAGE(X) thread_getrusage(X)
718e3744 35
36/* Linked list of thread. */
37struct thread_list
38{
39 struct thread *head;
40 struct thread *tail;
41 int count;
42};
43
4becea72
CF
44struct pqueue;
45
209a72a6
DS
46/*
47 * Abstract it so we can use different methodologies to
48 * select on data.
49 */
50typedef fd_set thread_fd_set;
51
0a95a0d0
DS
52#if defined(HAVE_POLL)
53#include <poll.h>
54struct fd_handler
55{
56 /* number of pfd stored in pfds */
57 nfds_t pfdcount;
58 /* number of pfd stored in pfds + number of snmp pfd */
59 nfds_t pfdcountsnmp;
60 /* number of pfd that fit in the allocated space of pfds */
61 nfds_t pfdsize;
62 struct pollfd *pfds;
63};
64#else
65struct fd_handler
66{
67 fd_set readfd;
68 fd_set writefd;
69 fd_set exceptfd;
70};
71#endif
72
718e3744 73/* Master of the theads. */
74struct thread_master
75{
308d14ae
DV
76 struct thread **read;
77 struct thread **write;
4becea72 78 struct pqueue *timer;
718e3744 79 struct thread_list event;
80 struct thread_list ready;
81 struct thread_list unuse;
4becea72 82 struct pqueue *background;
308d14ae 83 int fd_limit;
0a95a0d0 84 struct fd_handler handler;
718e3744 85 unsigned long alloc;
86};
87
41b2373c
PJ
88typedef unsigned char thread_type;
89
718e3744 90/* Thread itself. */
91struct thread
92{
41b2373c
PJ
93 thread_type type; /* thread type */
94 thread_type add_type; /* thread type */
a48b4e6d 95 struct thread *next; /* next pointer of the thread */
718e3744 96 struct thread *prev; /* previous pointer of the thread */
97 struct thread_master *master; /* pointer to the struct thread_master. */
98 int (*func) (struct thread *); /* event function */
99 void *arg; /* event argument */
100 union {
101 int val; /* second argument of the event. */
102 int fd; /* file descriptor in case of read/write. */
103 struct timeval sands; /* rest of time sands value. */
104 } u;
4becea72 105 int index; /* used for timers to store position in queue */
41af338e 106 struct timeval real;
cc8b13a0 107 struct cpu_thread_history *hist; /* cache pointer to cpu_history */
50596be0 108 unsigned long yield; /* yield time in us */
9c7753e4
DL
109 const char *funcname;
110 const char *schedfrom;
111 int schedfrom_line;
e04ab74d 112};
113
8b70d0b0 114struct cpu_thread_history
115{
e04ab74d 116 int (*func)(struct thread *);
e04ab74d 117 unsigned int total_calls;
8b70d0b0 118 struct time_stats
119 {
120 unsigned long total, max;
121 } real;
8b70d0b0 122 struct time_stats cpu;
41b2373c 123 thread_type types;
9c7753e4 124 const char *funcname;
718e3744 125};
126
db9c0df9
PJ
127/* Clocks supported by Quagga */
128enum quagga_clkid {
16f5949d 129 QUAGGA_CLK_MONOTONIC = 1, /* monotonic, against an indeterminate base */
db9c0df9
PJ
130};
131
ca1f4309
DS
132/* Struct timeval's tv_usec one second value. */
133#define TIMER_SECOND_MICRO 1000000L
134
718e3744 135/* Thread types. */
136#define THREAD_READ 0
137#define THREAD_WRITE 1
138#define THREAD_TIMER 2
139#define THREAD_EVENT 3
140#define THREAD_READY 4
a48b4e6d 141#define THREAD_BACKGROUND 5
142#define THREAD_UNUSED 6
143#define THREAD_EXECUTE 7
718e3744 144
145/* Thread yield time. */
17fc128d 146#define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
718e3744 147
148/* Macros. */
149#define THREAD_ARG(X) ((X)->arg)
150#define THREAD_FD(X) ((X)->u.fd)
151#define THREAD_VAL(X) ((X)->u.val)
152
153#define THREAD_READ_ON(master,thread,func,arg,sock) \
154 do { \
155 if (! thread) \
156 thread = thread_add_read (master, func, arg, sock); \
157 } while (0)
158
159#define THREAD_WRITE_ON(master,thread,func,arg,sock) \
160 do { \
161 if (! thread) \
162 thread = thread_add_write (master, func, arg, sock); \
163 } while (0)
164
165#define THREAD_TIMER_ON(master,thread,func,arg,time) \
166 do { \
167 if (! thread) \
168 thread = thread_add_timer (master, func, arg, time); \
169 } while (0)
170
e8540959
EM
171#define THREAD_TIMER_MSEC_ON(master,thread,func,arg,time) \
172 do { \
173 if (! thread) \
174 thread = thread_add_timer_msec (master, func, arg, time); \
175 } while (0)
176
718e3744 177#define THREAD_OFF(thread) \
178 do { \
179 if (thread) \
180 { \
181 thread_cancel (thread); \
182 thread = NULL; \
183 } \
184 } while (0)
185
186#define THREAD_READ_OFF(thread) THREAD_OFF(thread)
187#define THREAD_WRITE_OFF(thread) THREAD_OFF(thread)
188#define THREAD_TIMER_OFF(thread) THREAD_OFF(thread)
189
9c7753e4
DL
190#define debugargdef const char *funcname, const char *schedfrom, int fromln
191
192#define thread_add_read(m,f,a,v) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,#f,__FILE__,__LINE__)
193#define thread_add_write(m,f,a,v) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,#f,__FILE__,__LINE__)
194#define thread_add_timer(m,f,a,v) funcname_thread_add_timer(m,f,a,v,#f,__FILE__,__LINE__)
195#define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f,__FILE__,__LINE__)
d03c4cbd 196#define thread_add_timer_tv(m,f,a,v) funcname_thread_add_timer_tv(m,f,a,v,#f,__FILE__,__LINE__)
9c7753e4
DL
197#define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f,__FILE__,__LINE__)
198#define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
fb9e46bb 199
200/* The 4th arg to thread_add_background is the # of milliseconds to delay. */
9c7753e4 201#define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f,__FILE__,__LINE__)
e04ab74d 202
718e3744 203/* Prototypes. */
8cc4198f 204extern struct thread_master *thread_master_create (void);
205extern void thread_master_free (struct thread_master *);
495f0b13 206extern void thread_master_free_unused(struct thread_master *);
8cc4198f 207
8dadcae7 208extern struct thread *funcname_thread_add_read_write (int dir, struct thread_master *,
8cc4198f 209 int (*)(struct thread *),
9c7753e4 210 void *, int, debugargdef);
8cc4198f 211extern struct thread *funcname_thread_add_timer (struct thread_master *,
212 int (*)(struct thread *),
9c7753e4 213 void *, long, debugargdef);
8cc4198f 214extern struct thread *funcname_thread_add_timer_msec (struct thread_master *,
215 int (*)(struct thread *),
9c7753e4 216 void *, long, debugargdef);
d03c4cbd
DL
217extern struct thread *funcname_thread_add_timer_tv (struct thread_master *,
218 int (*)(struct thread *),
219 void *, struct timeval *,
220 debugargdef);
8cc4198f 221extern struct thread *funcname_thread_add_event (struct thread_master *,
222 int (*)(struct thread *),
9c7753e4 223 void *, int, debugargdef);
8cc4198f 224extern struct thread *funcname_thread_add_background (struct thread_master *,
225 int (*func)(struct thread *),
fb9e46bb 226 void *arg,
227 long milliseconds_to_delay,
9c7753e4 228 debugargdef);
8cc4198f 229extern struct thread *funcname_thread_execute (struct thread_master *,
230 int (*)(struct thread *),
9c7753e4
DL
231 void *, int, debugargdef);
232#undef debugargdef
233
8cc4198f 234extern void thread_cancel (struct thread *);
dc81807a 235extern unsigned int thread_cancel_event (struct thread_master *, void *);
8cc4198f 236extern struct thread *thread_fetch (struct thread_master *, struct thread *);
237extern void thread_call (struct thread *);
238extern unsigned long thread_timer_remain_second (struct thread *);
6ac44687 239extern struct timeval thread_timer_remain(struct thread*);
8cc4198f 240extern int thread_should_yield (struct thread *);
cf744958 241extern unsigned long timeval_elapsed (struct timeval a, struct timeval b);
50596be0
DS
242/* set yield time for thread */
243extern void thread_set_yield_time (struct thread *, unsigned long);
718e3744 244
55c72803 245/* Internal libfrr exports */
db9c0df9 246extern void thread_getrusage (RUSAGE_T *);
e04ab74d 247extern struct cmd_element show_thread_cpu_cmd;
e276eb82 248extern struct cmd_element clear_thread_cpu_cmd;
e04ab74d 249
db9c0df9
PJ
250/* replacements for the system gettimeofday(), clock_gettime() and
251 * time() functions, providing support for non-decrementing clock on
252 * all systems, and fully monotonic on /some/ systems.
253 */
254extern int quagga_gettime (enum quagga_clkid, struct timeval *);
a05d8b7a 255extern time_t quagga_monotime (void);
db9c0df9 256
8b70d0b0 257/* Returns elapsed real (wall clock) time. */
258extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
259 unsigned long *cpu_time_elapsed);
260
261/* Global variable containing a recent result from gettimeofday. This can
262 be used instead of calling gettimeofday if a recent value is sufficient.
263 This is guaranteed to be refreshed before a thread is called. */
264extern struct timeval recent_time;
db9c0df9
PJ
265/* Similar to recent_time, but a monotonically increasing time value */
266extern struct timeval recent_relative_time (void);
d1265948
DL
267
268/* only for use in logging functions! */
269extern struct thread *thread_current;
270
718e3744 271#endif /* _ZEBRA_THREAD_H */