]> git.proxmox.com Git - mirror_frr.git/blame - lib/event.h
*: Convert thread_cancelXXX to event_cancelXXX
[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
db9c0df9 38#define GETRUSAGE(X) thread_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;
65 uint32_t thread_type;
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
94/* Thread itself. */
e6685141 95struct event {
fbcac826
QY
96 uint8_t type; /* thread type */
97 uint8_t add_type; /* thread type */
c284542b 98 struct thread_list_item threaditem;
27d29ced 99 struct thread_timer_list_item timeritem;
e6685141 100 struct event **ref; /* external reference (if given) */
d62a17ae 101 struct thread_master *master; /* pointer to the struct thread_master */
e6685141 102 void (*func)(struct event *); /* event function */
d62a17ae 103 void *arg; /* event argument */
104 union {
105 int val; /* second argument of the event. */
106 int fd; /* file descriptor in case of r/w */
107 struct timeval sands; /* rest of time sands value. */
108 } u;
d62a17ae 109 struct timeval real;
110 struct cpu_thread_history *hist; /* cache pointer to cpu_history */
111 unsigned long yield; /* yield time in microseconds */
60a3efec 112 const struct xref_threadsched *xref; /* origin location */
d62a17ae 113 pthread_mutex_t mtx; /* mutex for thread.c functions */
e8b3a2f7 114 bool ignore_timer_late;
e04ab74d 115};
116
f59e6882 117#ifdef _FRR_ATTRIBUTE_PRINTFRR
e6685141 118#pragma FRR printfrr_ext "%pTH"(struct event *)
f59e6882
DL
119#endif
120
d62a17ae 121struct cpu_thread_history {
e6685141 122 void (*func)(struct event *);
9b8e01ca
DS
123 atomic_size_t total_cpu_warn;
124 atomic_size_t total_wall_warn;
1dd08c22 125 atomic_size_t total_starv_warn;
72327cf3
MS
126 atomic_size_t total_calls;
127 atomic_size_t total_active;
d62a17ae 128 struct time_stats {
c8a65463 129 atomic_size_t total, max;
d62a17ae 130 } real;
131 struct time_stats cpu;
c8a65463 132 atomic_uint_fast32_t types;
d62a17ae 133 const char *funcname;
718e3744 134};
135
ca1f4309
DS
136/* Struct timeval's tv_usec one second value. */
137#define TIMER_SECOND_MICRO 1000000L
138
718e3744 139/* Thread types. */
140#define THREAD_READ 0
141#define THREAD_WRITE 1
142#define THREAD_TIMER 2
143#define THREAD_EVENT 3
144#define THREAD_READY 4
a587d00b
QY
145#define THREAD_UNUSED 5
146#define THREAD_EXECUTE 6
718e3744 147
148/* Thread yield time. */
17fc128d 149#define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
718e3744 150
0447957e
AK
151#define THREAD_TIMER_STRLEN 12
152
718e3744 153/* Macros. */
154#define THREAD_ARG(X) ((X)->arg)
155#define THREAD_FD(X) ((X)->u.fd)
156#define THREAD_VAL(X) ((X)->u.val)
157
50478845
MS
158/*
159 * Please consider this macro deprecated, and do not use it in new code.
160 */
332beb64
DS
161#define THREAD_OFF(thread) \
162 do { \
163 if ((thread)) \
164 event_cancel(&(thread)); \
50478845 165 } while (0)
718e3744 166
60a3efec
DL
167/*
168 * Macro wrappers to generate xrefs for all thread add calls. Includes
169 * file/line/function info for debugging/tracing.
170 */
171#include "lib/xref.h"
172
173#define _xref_t_a(addfn, type, m, f, a, v, t) \
174 ({ \
907a2395
DS
175 static const struct xref_threadsched _xref __attribute__( \
176 (used)) = { \
60a3efec
DL
177 .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
178 .funcname = #f, \
179 .dest = #t, \
907a2395 180 .thread_type = THREAD_##type, \
60a3efec
DL
181 }; \
182 XREF_LINK(_xref.xref); \
907a2395
DS
183 _event_add_##addfn(&_xref, m, f, a, v, t); \
184 }) /* end */
60a3efec 185
907a2395
DS
186#define event_add_read(m, f, a, v, t) _xref_t_a(read_write, READ, m, f, a, v, t)
187#define event_add_write(m, f, a, v, t) \
188 _xref_t_a(read_write, WRITE, m, f, a, v, t)
189#define event_add_timer(m, f, a, v, t) _xref_t_a(timer, TIMER, m, f, a, v, t)
190#define event_add_timer_msec(m, f, a, v, t) \
191 _xref_t_a(timer_msec, TIMER, m, f, a, v, t)
192#define event_add_timer_tv(m, f, a, v, t) \
193 _xref_t_a(timer_tv, TIMER, m, f, a, v, t)
194#define event_add_event(m, f, a, v, t) _xref_t_a(event, EVENT, m, f, a, v, t)
60a3efec
DL
195
196#define thread_execute(m,f,a,v) \
197 ({ \
198 static const struct xref_threadsched _xref \
199 __attribute__((used)) = { \
200 .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
201 .funcname = #f, \
202 .dest = NULL, \
203 .thread_type = THREAD_EXECUTE, \
204 }; \
205 XREF_LINK(_xref.xref); \
206 _thread_execute(&_xref, m, f, a, v); \
207 }) /* end */
fb9e46bb 208
718e3744 209/* Prototypes. */
d62a17ae 210extern struct thread_master *thread_master_create(const char *);
d8a8a8de 211void thread_master_set_name(struct thread_master *master, const char *name);
d62a17ae 212extern void thread_master_free(struct thread_master *);
495f0b13 213extern void thread_master_free_unused(struct thread_master *);
8cc4198f 214
907a2395
DS
215extern void _event_add_read_write(const struct xref_threadsched *xref,
216 struct thread_master *master,
217 void (*fn)(struct event *), void *arg, int fd,
218 struct event **tref);
219
220extern void _event_add_timer(const struct xref_threadsched *xref,
221 struct thread_master *master,
222 void (*fn)(struct event *), void *arg, long t,
223 struct event **tref);
224
225extern void _event_add_timer_msec(const struct xref_threadsched *xref,
226 struct thread_master *master,
227 void (*fn)(struct event *), void *arg, long t,
228 struct event **tref);
229
230extern void _event_add_timer_tv(const struct xref_threadsched *xref,
231 struct thread_master *master,
232 void (*fn)(struct event *), void *arg,
233 struct timeval *tv, struct event **tref);
234
235extern void _event_add_event(const struct xref_threadsched *xref,
236 struct thread_master *master,
237 void (*fn)(struct event *), void *arg, int val,
238 struct event **tref);
60a3efec
DL
239
240extern void _thread_execute(const struct xref_threadsched *xref,
241 struct thread_master *master,
e6685141 242 void (*fn)(struct event *), void *arg, int val);
9c7753e4 243
332beb64
DS
244extern void event_cancel(struct event **event);
245extern void event_cancel_async(struct thread_master *, struct event **, void *);
a9318a32 246/* Cancel ready tasks with an arg matching 'arg' */
332beb64 247extern void event_cancel_event_ready(struct thread_master *m, void *arg);
a9318a32 248/* Cancel all tasks with an arg matching 'arg', including timers and io */
332beb64 249extern void event_cancel_event(struct thread_master *m, void *arg);
e6685141
DS
250extern struct event *thread_fetch(struct thread_master *, struct event *event);
251extern void thread_call(struct event *event);
252extern unsigned long thread_timer_remain_second(struct event *event);
253extern struct timeval thread_timer_remain(struct event *event);
254extern unsigned long thread_timer_remain_msec(struct event *event);
255extern int thread_should_yield(struct event *event);
50596be0 256/* set yield time for thread */
e6685141 257extern void thread_set_yield_time(struct event *event, unsigned long);
718e3744 258
55c72803 259/* Internal libfrr exports */
d62a17ae 260extern void thread_getrusage(RUSAGE_T *);
261extern void thread_cmd_init(void);
e04ab74d 262
8b70d0b0 263/* Returns elapsed real (wall clock) time. */
264extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
265 unsigned long *cpu_time_elapsed);
266
d1265948 267/* only for use in logging functions! */
e0bebc7c 268extern pthread_key_t thread_current;
0447957e 269extern char *thread_timer_to_hhmmss(char *buf, int buf_size,
e6685141 270 struct event *t_timer);
d1265948 271
e6685141 272static inline bool thread_is_scheduled(struct event *thread)
cfb9e0ee
DS
273{
274 if (thread)
275 return true;
276
277 return false;
278}
279
1543c387
MS
280/* Debug signal mask */
281void debug_signals(const sigset_t *sigs);
282
e6685141 283static inline void thread_ignore_late_timer(struct event *event)
e8b3a2f7 284{
e6685141 285 event->ignore_timer_late = true;
e8b3a2f7
DS
286}
287
5e244469
RW
288#ifdef __cplusplus
289}
290#endif
291
718e3744 292#endif /* _ZEBRA_THREAD_H */