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