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