]> git.proxmox.com Git - mirror_frr.git/blame - lib/thread.h
Merge pull request #10583 from donaldsharp/pim_upstream_timers
[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 *
896014f4
DL
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
718e3744 19 */
20
21#ifndef _ZEBRA_THREAD_H
22#define _ZEBRA_THREAD_H
23
5734509c 24#include <zebra.h>
1189d95f 25#include <pthread.h>
75bcb355
QY
26#include <poll.h>
27#include "monotime.h"
fbcac826 28#include "frratomic.h"
c284542b 29#include "typesafe.h"
60a3efec 30#include "xref.h"
5734509c 31
5e244469
RW
32#ifdef __cplusplus
33extern "C" {
34#endif
35
45f01188
DL
36extern bool cputime_enabled;
37extern unsigned long cputime_threshold;
38/* capturing wallclock time is always enabled since it is fast (reading
39 * hardware TSC w/o syscalls)
40 */
41extern unsigned long walltime_threshold;
42
d62a17ae 43struct rusage_t {
6418e2d3
DL
44#ifdef HAVE_CLOCK_THREAD_CPUTIME_ID
45 struct timespec cpu;
46#else
d62a17ae 47 struct rusage cpu;
6418e2d3 48#endif
d62a17ae 49 struct timeval real;
8b70d0b0 50};
51#define RUSAGE_T struct rusage_t
52
db9c0df9 53#define GETRUSAGE(X) thread_getrusage(X)
718e3744 54
960b9a53
DL
55PREDECL_LIST(thread_list);
56PREDECL_HEAP(thread_timer_list);
4becea72 57
d62a17ae 58struct fd_handler {
59 /* number of pfd that fit in the allocated space of pfds. This is a
a9318a32
MS
60 * constant and is the same for both pfds and copy.
61 */
d62a17ae 62 nfds_t pfdsize;
63
64 /* file descriptors to monitor for i/o */
65 struct pollfd *pfds;
66 /* number of pollfds stored in pfds */
67 nfds_t pfdcount;
68
69 /* chunk used for temp copy of pollfds */
70 struct pollfd *copy;
71 /* number of pollfds stored in copy */
72 nfds_t copycount;
0a95a0d0 73};
0a95a0d0 74
60a3efec
DL
75struct xref_threadsched {
76 struct xref xref;
77
78 const char *funcname;
79 const char *dest;
80 uint32_t thread_type;
81};
82
718e3744 83/* Master of the theads. */
d62a17ae 84struct thread_master {
85 char *name;
86
87 struct thread **read;
88 struct thread **write;
27d29ced 89 struct thread_timer_list_head timer;
c284542b 90 struct thread_list_head event, ready, unuse;
d62a17ae 91 struct list *cancel_req;
92 bool canceled;
93 pthread_cond_t cancel_cond;
94 struct hash *cpu_record;
95 int io_pipe[2];
96 int fd_limit;
97 struct fd_handler handler;
98 unsigned long alloc;
99 long selectpoll_timeout;
100 bool spin;
101 bool handle_signals;
102 pthread_mutex_t mtx;
103 pthread_t owner;
5e822957
DS
104
105 bool ready_run_loop;
106 RUSAGE_T last_getrusage;
718e3744 107};
108
109/* Thread itself. */
d62a17ae 110struct thread {
fbcac826
QY
111 uint8_t type; /* thread type */
112 uint8_t add_type; /* thread type */
c284542b 113 struct thread_list_item threaditem;
27d29ced 114 struct thread_timer_list_item timeritem;
d62a17ae 115 struct thread **ref; /* external reference (if given) */
116 struct thread_master *master; /* pointer to the struct thread_master */
cc9f21da 117 void (*func)(struct thread *); /* event function */
d62a17ae 118 void *arg; /* event argument */
119 union {
120 int val; /* second argument of the event. */
121 int fd; /* file descriptor in case of r/w */
122 struct timeval sands; /* rest of time sands value. */
123 } u;
d62a17ae 124 struct timeval real;
125 struct cpu_thread_history *hist; /* cache pointer to cpu_history */
126 unsigned long yield; /* yield time in microseconds */
60a3efec 127 const struct xref_threadsched *xref; /* origin location */
d62a17ae 128 pthread_mutex_t mtx; /* mutex for thread.c functions */
e8b3a2f7 129 bool ignore_timer_late;
e04ab74d 130};
131
f59e6882
DL
132#ifdef _FRR_ATTRIBUTE_PRINTFRR
133#pragma FRR printfrr_ext "%pTH" (struct thread *)
134#endif
135
d62a17ae 136struct cpu_thread_history {
cc9f21da 137 void (*func)(struct thread *);
9b8e01ca
DS
138 atomic_size_t total_cpu_warn;
139 atomic_size_t total_wall_warn;
1dd08c22 140 atomic_size_t total_starv_warn;
72327cf3
MS
141 atomic_size_t total_calls;
142 atomic_size_t total_active;
d62a17ae 143 struct time_stats {
c8a65463 144 atomic_size_t total, max;
d62a17ae 145 } real;
146 struct time_stats cpu;
c8a65463 147 atomic_uint_fast32_t types;
d62a17ae 148 const char *funcname;
718e3744 149};
150
ca1f4309
DS
151/* Struct timeval's tv_usec one second value. */
152#define TIMER_SECOND_MICRO 1000000L
153
718e3744 154/* Thread types. */
155#define THREAD_READ 0
156#define THREAD_WRITE 1
157#define THREAD_TIMER 2
158#define THREAD_EVENT 3
159#define THREAD_READY 4
a587d00b
QY
160#define THREAD_UNUSED 5
161#define THREAD_EXECUTE 6
718e3744 162
163/* Thread yield time. */
17fc128d 164#define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
718e3744 165
0447957e
AK
166#define THREAD_TIMER_STRLEN 12
167
718e3744 168/* Macros. */
169#define THREAD_ARG(X) ((X)->arg)
170#define THREAD_FD(X) ((X)->u.fd)
171#define THREAD_VAL(X) ((X)->u.val)
172
50478845
MS
173/*
174 * Please consider this macro deprecated, and do not use it in new code.
175 */
176#define THREAD_OFF(thread) \
177 do { \
178 if ((thread)) \
179 thread_cancel(&(thread)); \
180 } while (0)
718e3744 181
60a3efec
DL
182/*
183 * Macro wrappers to generate xrefs for all thread add calls. Includes
184 * file/line/function info for debugging/tracing.
185 */
186#include "lib/xref.h"
187
188#define _xref_t_a(addfn, type, m, f, a, v, t) \
189 ({ \
190 static const struct xref_threadsched _xref \
191 __attribute__((used)) = { \
192 .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
193 .funcname = #f, \
194 .dest = #t, \
195 .thread_type = THREAD_ ## type, \
196 }; \
197 XREF_LINK(_xref.xref); \
198 _thread_add_ ## addfn(&_xref, m, f, a, v, t); \
199 }) \
200 /* end */
201
202#define thread_add_read(m,f,a,v,t) _xref_t_a(read_write, READ, m,f,a,v,t)
203#define thread_add_write(m,f,a,v,t) _xref_t_a(read_write, WRITE, m,f,a,v,t)
204#define thread_add_timer(m,f,a,v,t) _xref_t_a(timer, TIMER, m,f,a,v,t)
205#define thread_add_timer_msec(m,f,a,v,t) _xref_t_a(timer_msec, TIMER, m,f,a,v,t)
206#define thread_add_timer_tv(m,f,a,v,t) _xref_t_a(timer_tv, TIMER, m,f,a,v,t)
44a5e507 207#define thread_add_event(m,f,a,v,t) _xref_t_a(event, EVENT, m,f,a,v,t)
60a3efec
DL
208
209#define thread_execute(m,f,a,v) \
210 ({ \
211 static const struct xref_threadsched _xref \
212 __attribute__((used)) = { \
213 .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
214 .funcname = #f, \
215 .dest = NULL, \
216 .thread_type = THREAD_EXECUTE, \
217 }; \
218 XREF_LINK(_xref.xref); \
219 _thread_execute(&_xref, m, f, a, v); \
220 }) /* end */
fb9e46bb 221
718e3744 222/* Prototypes. */
d62a17ae 223extern struct thread_master *thread_master_create(const char *);
d8a8a8de 224void thread_master_set_name(struct thread_master *master, const char *name);
d62a17ae 225extern void thread_master_free(struct thread_master *);
495f0b13 226extern void thread_master_free_unused(struct thread_master *);
8cc4198f 227
ee1455dd
IR
228extern void _thread_add_read_write(const struct xref_threadsched *xref,
229 struct thread_master *master,
cc9f21da 230 void (*fn)(struct thread *), void *arg,
ee1455dd
IR
231 int fd, struct thread **tref);
232
233extern void _thread_add_timer(const struct xref_threadsched *xref,
234 struct thread_master *master,
cc9f21da 235 void (*fn)(struct thread *), void *arg, long t,
ee1455dd
IR
236 struct thread **tref);
237
238extern void _thread_add_timer_msec(const struct xref_threadsched *xref,
239 struct thread_master *master,
cc9f21da 240 void (*fn)(struct thread *), void *arg,
ee1455dd
IR
241 long t, struct thread **tref);
242
243extern void _thread_add_timer_tv(const struct xref_threadsched *xref,
244 struct thread_master *master,
cc9f21da 245 void (*fn)(struct thread *), void *arg,
ee1455dd
IR
246 struct timeval *tv, struct thread **tref);
247
248extern void _thread_add_event(const struct xref_threadsched *xref,
249 struct thread_master *master,
cc9f21da 250 void (*fn)(struct thread *), void *arg, int val,
ee1455dd 251 struct thread **tref);
60a3efec
DL
252
253extern void _thread_execute(const struct xref_threadsched *xref,
254 struct thread_master *master,
cc9f21da 255 void (*fn)(struct thread *), void *arg, int val);
9c7753e4 256
b3d6bc6e 257extern void thread_cancel(struct thread **event);
d62a17ae 258extern void thread_cancel_async(struct thread_master *, struct thread **,
259 void *);
a9318a32
MS
260/* Cancel ready tasks with an arg matching 'arg' */
261extern void thread_cancel_event_ready(struct thread_master *m, void *arg);
262/* Cancel all tasks with an arg matching 'arg', including timers and io */
263extern void thread_cancel_event(struct thread_master *m, void *arg);
d62a17ae 264extern struct thread *thread_fetch(struct thread_master *, struct thread *);
265extern void thread_call(struct thread *);
266extern unsigned long thread_timer_remain_second(struct thread *);
267extern struct timeval thread_timer_remain(struct thread *);
78ca0342 268extern unsigned long thread_timer_remain_msec(struct thread *);
d62a17ae 269extern int thread_should_yield(struct thread *);
50596be0 270/* set yield time for thread */
d62a17ae 271extern void thread_set_yield_time(struct thread *, unsigned long);
718e3744 272
55c72803 273/* Internal libfrr exports */
d62a17ae 274extern void thread_getrusage(RUSAGE_T *);
275extern void thread_cmd_init(void);
e04ab74d 276
8b70d0b0 277/* Returns elapsed real (wall clock) time. */
278extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
279 unsigned long *cpu_time_elapsed);
280
d1265948 281/* only for use in logging functions! */
e0bebc7c 282extern pthread_key_t thread_current;
0447957e
AK
283extern char *thread_timer_to_hhmmss(char *buf, int buf_size,
284 struct thread *t_timer);
d1265948 285
a505383d 286extern bool thread_is_scheduled(struct thread *thread);
1543c387
MS
287/* Debug signal mask */
288void debug_signals(const sigset_t *sigs);
289
e8b3a2f7
DS
290static inline void thread_ignore_late_timer(struct thread *thread)
291{
292 thread->ignore_timer_late = true;
293}
294
5e244469
RW
295#ifdef __cplusplus
296}
297#endif
298
718e3744 299#endif /* _ZEBRA_THREAD_H */