2 * Utilities and interfaces for managing POSIX threads within FRR.
3 * Copyright (C) 2017 Cumulus Networks, Inc.
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.
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.
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
20 #ifndef _FRR_PTHREAD_H
21 #define _FRR_PTHREAD_H
24 #include "frratomic.h"
28 DECLARE_MTYPE(FRR_PTHREAD
);
29 DECLARE_MTYPE(PTHREAD_PRIM
);
31 #define OS_THREAD_NAMELEN 16
34 struct frr_pthread_attr
;
36 struct frr_pthread_attr
{
38 void *(*start
)(void *);
39 int (*stop
)(struct frr_pthread
*, void **);
45 * Mutex protecting this structure. Must be taken for reading some
46 * fields, denoted by a 'Requires: mtx'.
53 /* thread master for this pthread's thread.c event loop */
54 struct thread_master
*master
;
56 /* caller-specified data; start & stop funcs, name, id */
57 struct frr_pthread_attr attr
;
60 * Notification mechanism for allowing pthreads to notify their parents
61 * when they are ready to do work. This mechanism has two associated
64 * - frr_pthread_wait_running()
65 * This function should be called by the spawning thread after
66 * frr_pthread_run(). It safely waits until the spawned thread
67 * indicates that is ready to do work by posting to the condition
70 * - frr_pthread_notify_running()
71 * This function should be called by the spawned thread when it is
72 * ready to do work. It will wake up any threads waiting on the
73 * previously described condition.
75 pthread_cond_t
*running_cond
;
76 pthread_mutex_t
*running_cond_mtx
;
80 * Fake thread-specific storage. No constraints on usage. Helpful when
81 * creating reentrant pthread implementations. Can be used to pass
82 * argument to pthread entry function.
89 * Human-readable thread name.
95 /* Used in pthread_set_name max 16 characters */
96 char os_name
[OS_THREAD_NAMELEN
];
99 extern struct frr_pthread_attr frr_pthread_attr_default
;
102 * Initializes this module.
104 * Must be called before using any of the other functions.
106 void frr_pthread_init(void);
109 * Uninitializes this module.
111 * Destroys all registered frr_pthread's and internal data structures.
113 * It is safe to call frr_pthread_init() after this function to reinitialize
116 void frr_pthread_finish(void);
119 * Creates a new frr_pthread with the given attributes.
121 * The 'attr' argument should be filled out with the desired attributes,
122 * including ID, start and stop functions and the desired name. Alternatively,
123 * if attr is NULL, the default attributes will be used. The pthread will be
124 * set up to run a basic threadmaster loop and the name will be "Anonymous".
125 * Scheduling tasks onto the threadmaster in the 'master' field of the returned
126 * frr_pthread will cause them to run on that pthread.
128 * @param attr - the thread attributes
129 * @param name - Human-readable name
130 * @param os_name - 16 characters (including '\0') thread name to set in os,
131 * @return the created frr_pthread upon success, or NULL upon failure
133 struct frr_pthread
*frr_pthread_new(struct frr_pthread_attr
*attr
,
134 const char *name
, const char *os_name
);
137 * Changes the name of the frr_pthread.
139 * @param fpt - the frr_pthread to operate on
140 * @param name - Human-readable name
141 * @param os_name - 16 characters thread name , including the null
142 * terminator ('\0') to set in os.
143 * @return - on success returns 0 otherwise nonzero error number.
145 int frr_pthread_set_name(struct frr_pthread
*fpt
, const char *name
,
146 const char *os_name
);
149 * Destroys an frr_pthread.
151 * Assumes that the associated pthread, if any, has already terminated.
153 * @param fpt - the frr_pthread to destroy
155 void frr_pthread_destroy(struct frr_pthread
*fpt
);
158 * Gets an existing frr_pthread by its id.
160 * @return frr_thread associated with the provided id, or NULL on error
162 struct frr_pthread
*frr_pthread_get(uint32_t id
);
165 * Creates a new pthread and binds it to a frr_pthread.
167 * This function is a wrapper for pthread_create. The first parameter is the
168 * frr_pthread to bind the created pthread to. All subsequent arguments are
169 * passed unmodified to pthread_create(). The frr_pthread * provided will be
170 * used as the argument to the pthread entry function. If it is necessary to
171 * pass additional data, the 'data' field in the frr_pthread may be used.
173 * This function returns the same code as pthread_create(). If the value is
174 * zero, the provided frr_pthread is bound to a running POSIX thread. If the
175 * value is less than zero, the provided frr_pthread is guaranteed to be a
176 * clean instance that may be susbsequently passed to frr_pthread_run().
178 * @param fpt - frr_pthread * to run
179 * @param attr - see pthread_create(3)
181 * @return see pthread_create(3)
183 int frr_pthread_run(struct frr_pthread
*fpt
, const pthread_attr_t
*attr
);
186 * Waits until the specified pthread has finished setting up and is ready to
189 * If the pthread's code makes use of the startup synchronization mechanism,
190 * this function should be called before attempting to use the functionality
191 * exposed by the pthread. It waits until the 'running' condition is satisfied
192 * (see struct definition of frr_pthread).
194 * @param fpt - the frr_pthread * to wait on
196 void frr_pthread_wait_running(struct frr_pthread
*fpt
);
199 * Notifies other pthreads that the calling thread has finished setting up and
200 * is ready to begin work.
202 * This will allow any other pthreads waiting in 'frr_pthread_wait_running' to
205 * @param fpt - the frr_pthread * that has finished setting up
207 void frr_pthread_notify_running(struct frr_pthread
*fpt
);
210 * Stops a frr_pthread with a result.
212 * @param fpt - frr_pthread * to stop
213 * @param result - where to store the thread's result, if any. May be NULL if a
214 * result is not needed.
216 int frr_pthread_stop(struct frr_pthread
*fpt
, void **result
);
218 /* Stops all frr_pthread's. */
219 void frr_pthread_stop_all(void);
221 /* Yields the current thread of execution */
222 void frr_pthread_yield(void);
225 * Returns a unique identifier for use with frr_pthread_new().
227 * Internally, this is an integer that increments after each call to this
228 * function. Because the number of pthreads created should never exceed INT_MAX
229 * during the life of the program, there is no overflow protection. If by
230 * chance this function returns an ID which is already in use,
231 * frr_pthread_new() will fail when it is provided.
233 * @return unique identifier
235 uint32_t frr_pthread_get_id(void);
237 #ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK
238 #define pthread_condattr_setclock(A, B)
241 #endif /* _FRR_PTHREAD_H */