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