]> git.proxmox.com Git - mirror_frr.git/blob - lib/frr_pthread.h
Merge pull request #1825 from chiragshah6/ospfv3_dev
[mirror_frr.git] / lib / frr_pthread.h
1 /*
2 * Utilities and interfaces for managing POSIX threads within FRR.
3 * Copyright (C) 2017 Cumulus Networks, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef _FRR_PTHREAD_H
21 #define _FRR_PTHREAD_H
22
23 #include <pthread.h>
24 #include "frratomic.h"
25 #include "memory.h"
26 #include "thread.h"
27
28 DECLARE_MTYPE(FRR_PTHREAD);
29 DECLARE_MTYPE(PTHREAD_PRIM);
30
31 struct frr_pthread;
32 struct frr_pthread_attr;
33
34 struct frr_pthread_attr {
35 _Atomic uint32_t id;
36 void *(*start)(void *);
37 int (*stop)(struct frr_pthread *, void **);
38 };
39
40 struct frr_pthread {
41
42 /*
43 * Mutex protecting this structure. Must be taken for reading some
44 * fields, denoted by a 'Requires: mtx'.
45 */
46 pthread_mutex_t mtx;
47
48 /* pthread id */
49 pthread_t thread;
50
51 /* thread master for this pthread's thread.c event loop */
52 struct thread_master *master;
53
54 /* caller-specified data; start & stop funcs, name, id */
55 struct frr_pthread_attr attr;
56
57 /*
58 * Notification mechanism for allowing pthreads to notify their parents
59 * when they are ready to do work. This mechanism has two associated
60 * functions:
61 *
62 * - frr_pthread_wait_running()
63 * This function should be called by the spawning thread after
64 * frr_pthread_run(). It safely waits until the spawned thread
65 * indicates that is ready to do work by posting to the condition
66 * variable.
67 *
68 * - frr_pthread_notify_running()
69 * This function should be called by the spawned thread when it is
70 * ready to do work. It will wake up any threads waiting on the
71 * previously described condition.
72 */
73 pthread_cond_t *running_cond;
74 pthread_mutex_t *running_cond_mtx;
75 _Atomic bool running;
76
77 /*
78 * Fake thread-specific storage. No constraints on usage. Helpful when
79 * creating reentrant pthread implementations. Can be used to pass
80 * argument to pthread entry function.
81 *
82 * Requires: mtx
83 */
84 void *data;
85
86 /*
87 * Human-readable thread name.
88 *
89 * Requires: mtx
90 */
91 char *name;
92 };
93
94 extern struct frr_pthread_attr frr_pthread_attr_default;
95
96 /*
97 * Initializes this module.
98 *
99 * Must be called before using any of the other functions.
100 */
101 void frr_pthread_init(void);
102
103 /*
104 * Uninitializes this module.
105 *
106 * Destroys all registered frr_pthread's and internal data structures.
107 *
108 * It is safe to call frr_pthread_init() after this function to reinitialize
109 * the module.
110 */
111 void frr_pthread_finish(void);
112
113 /*
114 * Creates a new frr_pthread with the given attributes.
115 *
116 * The 'attr' argument should be filled out with the desired attributes,
117 * including ID, start and stop functions and the desired name. Alternatively,
118 * if attr is NULL, the default attributes will be used. The pthread will be
119 * set up to run a basic threadmaster loop and the name will be "Anonymous".
120 * Scheduling tasks onto the threadmaster in the 'master' field of the returned
121 * frr_pthread will cause them to run on that pthread.
122 *
123 * @param attr - the thread attributes
124 * @param name - Human-readable name
125 * @return the created frr_pthread upon success, or NULL upon failure
126 */
127 struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr,
128 const char *name);
129
130 /*
131 * Changes the name of the frr_pthread.
132 *
133 * @param fpt - the frr_pthread to operate on
134 * @param name - Human-readable name
135 */
136 void frr_pthread_set_name(struct frr_pthread *fpt, const char *name);
137
138 /*
139 * Destroys an frr_pthread.
140 *
141 * Assumes that the associated pthread, if any, has already terminated.
142 *
143 * @param fpt - the frr_pthread to destroy
144 */
145 void frr_pthread_destroy(struct frr_pthread *fpt);
146
147 /*
148 * Gets an existing frr_pthread by its id.
149 *
150 * @return frr_thread associated with the provided id, or NULL on error
151 */
152 struct frr_pthread *frr_pthread_get(uint32_t id);
153
154 /*
155 * Creates a new pthread and binds it to a frr_pthread.
156 *
157 * This function is a wrapper for pthread_create. The first parameter is the
158 * frr_pthread to bind the created pthread to. All subsequent arguments are
159 * passed unmodified to pthread_create(). The frr_pthread * provided will be
160 * used as the argument to the pthread entry function. If it is necessary to
161 * pass additional data, the 'data' field in the frr_pthread may be used.
162 *
163 * This function returns the same code as pthread_create(). If the value is
164 * zero, the provided frr_pthread is bound to a running POSIX thread. If the
165 * value is less than zero, the provided frr_pthread is guaranteed to be a
166 * clean instance that may be susbsequently passed to frr_pthread_run().
167 *
168 * @param fpt - frr_pthread * to run
169 * @param attr - see pthread_create(3)
170 *
171 * @return see pthread_create(3)
172 */
173 int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr);
174
175 /*
176 * Waits until the specified pthread has finished setting up and is ready to
177 * begin work.
178 *
179 * If the pthread's code makes use of the startup synchronization mechanism,
180 * this function should be called before attempting to use the functionality
181 * exposed by the pthread. It waits until the 'running' condition is satisfied
182 * (see struct definition of frr_pthread).
183 *
184 * @param fpt - the frr_pthread * to wait on
185 */
186 void frr_pthread_wait_running(struct frr_pthread *fpt);
187
188 /*
189 * Notifies other pthreads that the calling thread has finished setting up and
190 * is ready to begin work.
191 *
192 * This will allow any other pthreads waiting in 'frr_pthread_wait_running' to
193 * proceed.
194 *
195 * @param fpt - the frr_pthread * that has finished setting up
196 */
197 void frr_pthread_notify_running(struct frr_pthread *fpt);
198
199 /*
200 * Stops a frr_pthread with a result.
201 *
202 * @param fpt - frr_pthread * to stop
203 * @param result - where to store the thread's result, if any. May be NULL if a
204 * result is not needed.
205 */
206 int frr_pthread_stop(struct frr_pthread *fpt, void **result);
207
208 /* Stops all frr_pthread's. */
209 void frr_pthread_stop_all(void);
210
211 /* Yields the current thread of execution */
212 void frr_pthread_yield(void);
213
214 /*
215 * Returns a unique identifier for use with frr_pthread_new().
216 *
217 * Internally, this is an integer that increments after each call to this
218 * function. Because the number of pthreads created should never exceed INT_MAX
219 * during the life of the program, there is no overflow protection. If by
220 * chance this function returns an ID which is already in use,
221 * frr_pthread_new() will fail when it is provided.
222 *
223 * @return unique identifier
224 */
225 uint32_t frr_pthread_get_id(void);
226
227 #endif /* _FRR_PTHREAD_H */