]> git.proxmox.com Git - mirror_frr.git/blame - lib/thread.h
libs: make the task cancellation struct private
[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
d62a17ae 36struct rusage_t {
37 struct rusage cpu;
38 struct timeval real;
8b70d0b0 39};
40#define RUSAGE_T struct rusage_t
41
db9c0df9 42#define GETRUSAGE(X) thread_getrusage(X)
718e3744 43
c284542b 44PREDECL_LIST(thread_list)
27d29ced 45PREDECL_HEAP(thread_timer_list)
4becea72 46
d62a17ae 47struct 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;
0a95a0d0 62};
0a95a0d0 63
60a3efec
DL
64struct xref_threadsched {
65 struct xref xref;
66
67 const char *funcname;
68 const char *dest;
69 uint32_t thread_type;
70};
71
718e3744 72/* Master of the theads. */
d62a17ae 73struct thread_master {
74 char *name;
75
76 struct thread **read;
77 struct thread **write;
27d29ced 78 struct thread_timer_list_head timer;
c284542b 79 struct thread_list_head event, ready, unuse;
d62a17ae 80 struct list *cancel_req;
81 bool canceled;
82 pthread_cond_t cancel_cond;
83 struct hash *cpu_record;
84 int io_pipe[2];
85 int fd_limit;
86 struct fd_handler handler;
87 unsigned long alloc;
88 long selectpoll_timeout;
89 bool spin;
90 bool handle_signals;
91 pthread_mutex_t mtx;
92 pthread_t owner;
718e3744 93};
94
95/* Thread itself. */
d62a17ae 96struct thread {
fbcac826
QY
97 uint8_t type; /* thread type */
98 uint8_t add_type; /* thread type */
c284542b 99 struct thread_list_item threaditem;
27d29ced 100 struct thread_timer_list_item timeritem;
d62a17ae 101 struct thread **ref; /* external reference (if given) */
102 struct thread_master *master; /* pointer to the struct thread_master */
103 int (*func)(struct thread *); /* event function */
104 void *arg; /* event argument */
105 union {
106 int val; /* second argument of the event. */
107 int fd; /* file descriptor in case of r/w */
108 struct timeval sands; /* rest of time sands value. */
109 } u;
d62a17ae 110 struct timeval real;
111 struct cpu_thread_history *hist; /* cache pointer to cpu_history */
112 unsigned long yield; /* yield time in microseconds */
60a3efec 113 const struct xref_threadsched *xref; /* origin location */
d62a17ae 114 pthread_mutex_t mtx; /* mutex for thread.c functions */
e04ab74d 115};
116
d62a17ae 117struct cpu_thread_history {
118 int (*func)(struct thread *);
72327cf3
MS
119 atomic_size_t total_calls;
120 atomic_size_t total_active;
d62a17ae 121 struct time_stats {
c8a65463 122 atomic_size_t total, max;
d62a17ae 123 } real;
124 struct time_stats cpu;
c8a65463 125 atomic_uint_fast32_t types;
d62a17ae 126 const char *funcname;
718e3744 127};
128
ca1f4309
DS
129/* Struct timeval's tv_usec one second value. */
130#define TIMER_SECOND_MICRO 1000000L
131
718e3744 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
a587d00b
QY
138#define THREAD_UNUSED 5
139#define THREAD_EXECUTE 6
718e3744 140
141/* Thread yield time. */
17fc128d 142#define THREAD_YIELD_TIME_SLOT 10 * 1000L /* 10ms */
718e3744 143
0447957e
AK
144#define THREAD_TIMER_STRLEN 12
145
718e3744 146/* Macros. */
147#define THREAD_ARG(X) ((X)->arg)
148#define THREAD_FD(X) ((X)->u.fd)
149#define THREAD_VAL(X) ((X)->u.val)
150
50478845
MS
151/*
152 * Please consider this macro deprecated, and do not use it in new code.
153 */
154#define THREAD_OFF(thread) \
155 do { \
156 if ((thread)) \
157 thread_cancel(&(thread)); \
158 } while (0)
718e3744 159
60a3efec
DL
160/*
161 * Macro wrappers to generate xrefs for all thread add calls. Includes
162 * file/line/function info for debugging/tracing.
163 */
164#include "lib/xref.h"
165
166#define _xref_t_a(addfn, type, m, f, a, v, t) \
167 ({ \
168 static const struct xref_threadsched _xref \
169 __attribute__((used)) = { \
170 .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
171 .funcname = #f, \
172 .dest = #t, \
173 .thread_type = THREAD_ ## type, \
174 }; \
175 XREF_LINK(_xref.xref); \
176 _thread_add_ ## addfn(&_xref, m, f, a, v, t); \
177 }) \
178 /* end */
179
180#define thread_add_read(m,f,a,v,t) _xref_t_a(read_write, READ, m,f,a,v,t)
181#define thread_add_write(m,f,a,v,t) _xref_t_a(read_write, WRITE, m,f,a,v,t)
182#define thread_add_timer(m,f,a,v,t) _xref_t_a(timer, TIMER, m,f,a,v,t)
183#define thread_add_timer_msec(m,f,a,v,t) _xref_t_a(timer_msec, TIMER, m,f,a,v,t)
184#define thread_add_timer_tv(m,f,a,v,t) _xref_t_a(timer_tv, TIMER, m,f,a,v,t)
185#define thread_add_event(m,f,a,v,t) _xref_t_a(event, TIMER, m,f,a,v,t)
186
187#define thread_execute(m,f,a,v) \
188 ({ \
189 static const struct xref_threadsched _xref \
190 __attribute__((used)) = { \
191 .xref = XREF_INIT(XREFT_THREADSCHED, NULL, __func__), \
192 .funcname = #f, \
193 .dest = NULL, \
194 .thread_type = THREAD_EXECUTE, \
195 }; \
196 XREF_LINK(_xref.xref); \
197 _thread_execute(&_xref, m, f, a, v); \
198 }) /* end */
fb9e46bb 199
718e3744 200/* Prototypes. */
d62a17ae 201extern struct thread_master *thread_master_create(const char *);
d8a8a8de 202void thread_master_set_name(struct thread_master *master, const char *name);
d62a17ae 203extern void thread_master_free(struct thread_master *);
495f0b13 204extern void thread_master_free_unused(struct thread_master *);
8cc4198f 205
60a3efec
DL
206extern struct thread *_thread_add_read_write(
207 const struct xref_threadsched *xref, struct thread_master *master,
208 int (*fn)(struct thread *), void *arg, int fd, struct thread **tref);
209
210extern struct thread *_thread_add_timer(
211 const struct xref_threadsched *xref, struct thread_master *master,
212 int (*fn)(struct thread *), void *arg, long t, struct thread **tref);
213
214extern struct thread *_thread_add_timer_msec(
215 const struct xref_threadsched *xref, struct thread_master *master,
216 int (*fn)(struct thread *), void *arg, long t, struct thread **tref);
217
218extern struct thread *_thread_add_timer_tv(
219 const struct xref_threadsched *xref, struct thread_master *master,
220 int (*fn)(struct thread *), void *arg, struct timeval *tv,
221 struct thread **tref);
222
223extern struct thread *_thread_add_event(
224 const struct xref_threadsched *xref, struct thread_master *master,
225 int (*fn)(struct thread *), void *arg, int val, struct thread **tref);
226
227extern void _thread_execute(const struct xref_threadsched *xref,
228 struct thread_master *master,
229 int (*fn)(struct thread *), void *arg, int val);
9c7753e4 230
b3d6bc6e 231extern void thread_cancel(struct thread **event);
d62a17ae 232extern void thread_cancel_async(struct thread_master *, struct thread **,
233 void *);
234extern void thread_cancel_event(struct thread_master *, void *);
235extern struct thread *thread_fetch(struct thread_master *, struct thread *);
236extern void thread_call(struct thread *);
237extern unsigned long thread_timer_remain_second(struct thread *);
238extern struct timeval thread_timer_remain(struct thread *);
78ca0342 239extern unsigned long thread_timer_remain_msec(struct thread *);
d62a17ae 240extern int thread_should_yield(struct thread *);
50596be0 241/* set yield time for thread */
d62a17ae 242extern void thread_set_yield_time(struct thread *, unsigned long);
718e3744 243
55c72803 244/* Internal libfrr exports */
d62a17ae 245extern void thread_getrusage(RUSAGE_T *);
246extern void thread_cmd_init(void);
e04ab74d 247
8b70d0b0 248/* Returns elapsed real (wall clock) time. */
249extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before,
250 unsigned long *cpu_time_elapsed);
251
d1265948 252/* only for use in logging functions! */
e0bebc7c 253extern pthread_key_t thread_current;
0447957e
AK
254extern char *thread_timer_to_hhmmss(char *buf, int buf_size,
255 struct thread *t_timer);
d1265948 256
1543c387
MS
257/* Debug signal mask */
258void debug_signals(const sigset_t *sigs);
259
5e244469
RW
260#ifdef __cplusplus
261}
262#endif
263
718e3744 264#endif /* _ZEBRA_THREAD_H */