]> git.proxmox.com Git - mirror_frr.git/blob - lib/thread.h
Merge pull request #5163 from ton31337/fix/do_not_reconnect_if_prefix_overflow_7.1
[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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef _ZEBRA_THREAD_H
22 #define _ZEBRA_THREAD_H
23
24 #include <zebra.h>
25 #include <pthread.h>
26 #include <poll.h>
27 #include "monotime.h"
28 #include "frratomic.h"
29 #include "typesafe.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 struct rusage_t {
36 struct rusage cpu;
37 struct timeval real;
38 };
39 #define RUSAGE_T struct rusage_t
40
41 #define GETRUSAGE(X) thread_getrusage(X)
42
43 PREDECL_LIST(thread_list)
44
45 struct pqueue;
46
47 struct fd_handler {
48 /* number of pfd that fit in the allocated space of pfds. This is a
49 * constant
50 * and is the same for both pfds and copy. */
51 nfds_t pfdsize;
52
53 /* file descriptors to monitor for i/o */
54 struct pollfd *pfds;
55 /* number of pollfds stored in pfds */
56 nfds_t pfdcount;
57
58 /* chunk used for temp copy of pollfds */
59 struct pollfd *copy;
60 /* number of pollfds stored in copy */
61 nfds_t copycount;
62 };
63
64 struct cancel_req {
65 struct thread *thread;
66 void *eventobj;
67 struct thread **threadref;
68 };
69
70 /* Master of the theads. */
71 struct thread_master {
72 char *name;
73
74 struct thread **read;
75 struct thread **write;
76 struct pqueue *timer;
77 struct thread_list_head event, ready, unuse;
78 struct list *cancel_req;
79 bool canceled;
80 pthread_cond_t cancel_cond;
81 struct hash *cpu_record;
82 int io_pipe[2];
83 int fd_limit;
84 struct fd_handler handler;
85 unsigned long alloc;
86 long selectpoll_timeout;
87 bool spin;
88 bool handle_signals;
89 pthread_mutex_t mtx;
90 pthread_t owner;
91 };
92
93 /* Thread itself. */
94 struct thread {
95 uint8_t type; /* thread type */
96 uint8_t add_type; /* thread type */
97 struct thread_list_item threaditem;
98 struct thread **ref; /* external reference (if given) */
99 struct thread_master *master; /* pointer to the struct thread_master */
100 int (*func)(struct thread *); /* event function */
101 void *arg; /* event argument */
102 union {
103 int val; /* second argument of the event. */
104 int fd; /* file descriptor in case of r/w */
105 struct timeval sands; /* rest of time sands value. */
106 } u;
107 int index; /* queue position for timers */
108 struct timeval real;
109 struct cpu_thread_history *hist; /* cache pointer to cpu_history */
110 unsigned long yield; /* yield time in microseconds */
111 const char *funcname; /* name of thread function */
112 const char *schedfrom; /* source file thread was scheduled from */
113 int schedfrom_line; /* line number of source file */
114 pthread_mutex_t mtx; /* mutex for thread.c functions */
115 };
116
117 struct cpu_thread_history {
118 int (*func)(struct thread *);
119 atomic_uint_fast32_t total_calls;
120 atomic_uint_fast32_t total_active;
121 struct time_stats {
122 atomic_size_t total, max;
123 } real;
124 struct time_stats cpu;
125 atomic_uint_fast32_t types;
126 const char *funcname;
127 };
128
129 /* Struct timeval's tv_usec one second value. */
130 #define TIMER_SECOND_MICRO 1000000L
131
132 /* Thread types. */
133 #define THREAD_READ 0
134 #define THREAD_WRITE 1
135 #define THREAD_TIMER 2
136 #define THREAD_EVENT 3
137 #define THREAD_READY 4
138 #define THREAD_UNUSED 5
139 #define THREAD_EXECUTE 6
140
141 /* Thread yield time. */
142 #define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
143
144 /* Macros. */
145 #define THREAD_ARG(X) ((X)->arg)
146 #define THREAD_FD(X) ((X)->u.fd)
147 #define THREAD_VAL(X) ((X)->u.val)
148
149 #define THREAD_OFF(thread) \
150 do { \
151 if (thread) { \
152 thread_cancel(thread); \
153 thread = NULL; \
154 } \
155 } while (0)
156
157 #define THREAD_READ_OFF(thread) THREAD_OFF(thread)
158 #define THREAD_WRITE_OFF(thread) THREAD_OFF(thread)
159 #define THREAD_TIMER_OFF(thread) THREAD_OFF(thread)
160
161 #define debugargdef const char *funcname, const char *schedfrom, int fromln
162
163 #define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__)
164 #define thread_add_write(m,f,a,v,t) funcname_thread_add_read_write(THREAD_WRITE,m,f,a,v,t,#f,__FILE__,__LINE__)
165 #define thread_add_timer(m,f,a,v,t) funcname_thread_add_timer(m,f,a,v,t,#f,__FILE__,__LINE__)
166 #define thread_add_timer_msec(m,f,a,v,t) funcname_thread_add_timer_msec(m,f,a,v,t,#f,__FILE__,__LINE__)
167 #define thread_add_timer_tv(m,f,a,v,t) funcname_thread_add_timer_tv(m,f,a,v,t,#f,__FILE__,__LINE__)
168 #define thread_add_event(m,f,a,v,t) funcname_thread_add_event(m,f,a,v,t,#f,__FILE__,__LINE__)
169 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f,__FILE__,__LINE__)
170 #define thread_execute_name(m, f, a, v, n) \
171 funcname_thread_execute(m, f, a, v, n, __FILE__, __LINE__)
172
173 /* Prototypes. */
174 extern struct thread_master *thread_master_create(const char *);
175 void thread_master_set_name(struct thread_master *master, const char *name);
176 extern void thread_master_free(struct thread_master *);
177 extern void thread_master_free_unused(struct thread_master *);
178
179 extern struct thread *
180 funcname_thread_add_read_write(int dir, struct thread_master *,
181 int (*)(struct thread *), void *, int,
182 struct thread **, debugargdef);
183
184 extern struct thread *funcname_thread_add_timer(struct thread_master *,
185 int (*)(struct thread *),
186 void *, long, struct thread **,
187 debugargdef);
188
189 extern struct thread *
190 funcname_thread_add_timer_msec(struct thread_master *, int (*)(struct thread *),
191 void *, long, struct thread **, debugargdef);
192
193 extern struct thread *funcname_thread_add_timer_tv(struct thread_master *,
194 int (*)(struct thread *),
195 void *, struct timeval *,
196 struct thread **,
197 debugargdef);
198
199 extern struct thread *funcname_thread_add_event(struct thread_master *,
200 int (*)(struct thread *),
201 void *, int, struct thread **,
202 debugargdef);
203
204 extern void funcname_thread_execute(struct thread_master *,
205 int (*)(struct thread *), void *, int,
206 debugargdef);
207 #undef debugargdef
208
209 extern void thread_cancel(struct thread *);
210 extern void thread_cancel_async(struct thread_master *, struct thread **,
211 void *);
212 extern void thread_cancel_event(struct thread_master *, void *);
213 extern struct thread *thread_fetch(struct thread_master *, struct thread *);
214 extern void thread_call(struct thread *);
215 extern unsigned long thread_timer_remain_second(struct thread *);
216 extern struct timeval thread_timer_remain(struct thread *);
217 extern unsigned long thread_timer_remain_msec(struct thread *);
218 extern int thread_should_yield(struct thread *);
219 /* set yield time for thread */
220 extern void thread_set_yield_time(struct thread *, unsigned long);
221
222 /* Internal libfrr exports */
223 extern void thread_getrusage(RUSAGE_T *);
224 extern void thread_cmd_init(void);
225
226 /* Returns elapsed real (wall clock) time. */
227 extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
228 unsigned long *cpu_time_elapsed);
229
230 /* only for use in logging functions! */
231 extern pthread_key_t thread_current;
232
233 #ifdef __cplusplus
234 }
235 #endif
236
237 #endif /* _ZEBRA_THREAD_H */