]> git.proxmox.com Git - mirror_frr.git/blame - lib/frr_pthread.h
lib, pimd: Remove PIM_NODE as it is not needed
[mirror_frr.git] / lib / frr_pthread.h
CommitLineData
98f14af8 1/*
a45dc974 2 * Utilities and interfaces for managing POSIX threads within FRR.
896014f4
DL
3 * Copyright (C) 2017 Cumulus Networks
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
98f14af8
QY
18 */
19
20#ifndef _FRR_PTHREAD_H
21#define _FRR_PTHREAD_H
22
23#include <pthread.h>
a45dc974 24#include "frratomic.h"
0bbb9e72 25#include "memory.h"
98f14af8
QY
26#include "thread.h"
27
a45dc974 28DECLARE_MTYPE(FRR_PTHREAD);
0bbb9e72
QY
29DECLARE_MTYPE(PTHREAD_PRIM);
30
a45dc974
QY
31struct frr_pthread;
32struct frr_pthread_attr;
33
34struct frr_pthread_attr {
35 int id;
36 void *(*start)(void *);
37 int (*stop)(struct frr_pthread *, void **);
38 const char *name;
39};
40
98f14af8
QY
41struct frr_pthread {
42
d62a17ae 43 /* pthread id */
44 pthread_t thread;
98f14af8 45
d62a17ae 46 /* thread master for this pthread's thread.c event loop */
47 struct thread_master *master;
98f14af8 48
a45dc974
QY
49 /* caller-specified data; start & stop funcs, name, id */
50 struct frr_pthread_attr attr;
51
52 /*
53 * Notification mechanism for allowing pthreads to notify their parents
54 * when they are ready to do work. This mechanism has two associated
55 * functions:
56 *
57 * - frr_pthread_wait_running()
58 * This function should be called by the spawning thread after
59 * frr_pthread_run(). It safely waits until the spawned thread
60 * indicates that is ready to do work by posting to the condition
61 * variable.
62 *
63 * - frr_pthread_notify_running()
64 * This function should be called by the spawned thread when it is
65 * ready to do work. It will wake up any threads waiting on the
66 * previously described condition.
67 */
68 pthread_cond_t *running_cond;
69 pthread_mutex_t *running_cond_mtx;
70 _Atomic bool running;
71
72 /*
73 * Fake thread-specific storage. No constraints on usage. Helpful when
74 * creating reentrant pthread implementations. Can be used to pass
75 * argument to pthread entry function.
76 */
77 void *data;
98f14af8
QY
78};
79
a45dc974
QY
80extern struct frr_pthread_attr frr_pthread_attr_default;
81
82/*
83 * Initializes this module.
98f14af8
QY
84 *
85 * Must be called before using any of the other functions.
86 */
87void frr_pthread_init(void);
88
a45dc974
QY
89/*
90 * Uninitializes this module.
98f14af8
QY
91 *
92 * Destroys all registered frr_pthread's and internal data structures.
93 *
94 * It is safe to call frr_pthread_init() after this function to reinitialize
95 * the module.
96 */
97void frr_pthread_finish(void);
98
a45dc974
QY
99/*
100 * Creates a new frr_pthread with the given attributes.
98f14af8 101 *
a45dc974
QY
102 * The 'attr' argument should be filled out with the desired attributes,
103 * including ID, start and stop functions and the desired name. Alternatively,
104 * if attr is NULL, the default attributes will be used. The pthread will be
105 * set up to run a basic threadmaster loop and the name will be "Anonymous".
106 * Scheduling tasks onto the threadmaster in the 'master' field of the returned
107 * frr_pthread will cause them to run on that pthread.
98f14af8 108 *
a45dc974 109 * @param attr - the thread attributes
98f14af8
QY
110 * @return the created frr_pthread upon success, or NULL upon failure
111 */
a45dc974 112struct frr_pthread *frr_pthread_new(struct frr_pthread_attr *attr);
98f14af8 113
a45dc974
QY
114/*
115 * Destroys an frr_pthread.
98f14af8
QY
116 *
117 * Assumes that the associated pthread, if any, has already terminated.
118 *
119 * @param fpt - the frr_pthread to destroy
120 */
121void frr_pthread_destroy(struct frr_pthread *fpt);
122
a45dc974
QY
123/*
124 * Gets an existing frr_pthread by its id.
98f14af8
QY
125 *
126 * @return frr_thread associated with the provided id, or NULL on error
127 */
128struct frr_pthread *frr_pthread_get(unsigned int id);
129
a45dc974
QY
130/*
131 * Creates a new pthread and binds it to a frr_pthread.
98f14af8
QY
132 *
133 * This function is a wrapper for pthread_create. The first parameter is the
134 * frr_pthread to bind the created pthread to. All subsequent arguments are
a45dc974
QY
135 * passed unmodified to pthread_create(). The frr_pthread * provided will be
136 * used as the argument to the pthread entry function. If it is necessary to
137 * pass additional data, the 'data' field in the frr_pthread may be used.
98f14af8
QY
138 *
139 * This function returns the same code as pthread_create(). If the value is
140 * zero, the provided frr_pthread is bound to a running POSIX thread. If the
141 * value is less than zero, the provided frr_pthread is guaranteed to be a
142 * clean instance that may be susbsequently passed to frr_pthread_run().
143 *
a45dc974 144 * @param fpt - frr_pthread * to run
98f14af8 145 * @param attr - see pthread_create(3)
98f14af8
QY
146 *
147 * @return see pthread_create(3)
148 */
a45dc974
QY
149int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr);
150
151/*
152 * Waits until the specified pthread has finished setting up and is ready to
153 * begin work.
154 *
155 * If the pthread's code makes use of the startup synchronization mechanism,
156 * this function should be called before attempting to use the functionality
157 * exposed by the pthread. It waits until the 'running' condition is satisfied
158 * (see struct definition of frr_pthread).
159 *
160 * @param fpt - the frr_pthread * to wait on
161 */
162void frr_pthread_wait_running(struct frr_pthread *fpt);
98f14af8 163
a45dc974
QY
164/*
165 * Notifies other pthreads that the calling thread has finished setting up and
166 * is ready to begin work.
167 *
168 * This will allow any other pthreads waiting in 'frr_pthread_wait_running' to
169 * proceed.
98f14af8 170 *
a45dc974
QY
171 * @param fpt - the frr_pthread * that has finished setting up
172 */
173void frr_pthread_notify_running(struct frr_pthread *fpt);
174
175/*
176 * Stops a frr_pthread with a result.
177 *
178 * @param fpt - frr_pthread * to stop
98f14af8
QY
179 * @param result - where to store the thread's result, if any. May be NULL if a
180 * result is not needed.
181 */
a45dc974 182int frr_pthread_stop(struct frr_pthread *fpt, void **result);
98f14af8
QY
183
184/* Stops all frr_pthread's. */
185void frr_pthread_stop_all(void);
186
b2140cb7
DS
187/* Yields the current thread of execution */
188void frr_pthread_yield(void);
189
a45dc974
QY
190/*
191 * Returns a unique identifier for use with frr_pthread_new().
98f14af8
QY
192 *
193 * Internally, this is an integer that increments after each call to this
194 * function. Because the number of pthreads created should never exceed INT_MAX
195 * during the life of the program, there is no overflow protection. If by
196 * chance this function returns an ID which is already in use,
197 * frr_pthread_new() will fail when it is provided.
198 *
199 * @return unique identifier
200 */
201unsigned int frr_pthread_get_id(void);
202
203#endif /* _FRR_PTHREAD_H */