BRL-CAD
parallel.h
Go to the documentation of this file.
1 /* P A R A L L E L . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library 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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 /** @defgroup parallel Parallel Processing */
22 /** @defgroup thread Multithreading */
23 
24 /** @file include/bu/parallel.h
25  *
26  */
27 #ifndef BU_PARALLEL_H
28 #define BU_PARALLEL_H
29 
30 #include "common.h"
31 
32 #include <setjmp.h> /* for bu_setjmp */
33 
34 #include "bu/defines.h"
35 
37 
38 /** @addtogroup thread */
39 /** @{ */
40 
41 /**
42  * MAX_PSW - The maximum number of processors that can be expected on
43  * this hardware. Used to allocate application-specific per-processor
44  * tables at compile-time and represent a hard limit on the number of
45  * processors/threads that may be spawned. The actual number of
46  * available processors is found at runtime by calling bu_avail_cpus()
47  */
48 #define MAX_PSW 1024
49 
50 /** @file libbu/parallel.c
51  *
52  * subroutine to determine if we are multi-threaded
53  *
54  * This subroutine is separated off from parallel.c so that bu_bomb()
55  * and others can call it, without causing either parallel.c or
56  * semaphore.c to get referenced and thus causing the loader to drag
57  * in all the parallel processing stuff from the vendor library.
58  *
59  */
60 
61 /**
62  * This routine is DEPRECATED, do not use it. If you need a means to
63  * determine when an application is running bu_parallel(), please
64  * report this to our developers.
65  *
66  * Previously, this was a library-stateful way for bu_bomb() to tell
67  * if a parallel application is running. This routine now simply
68  * returns zero all the time, which permits BU_SETJUMP() error
69  * handling during bu_bomb().
70  */
71 DEPRECATED BU_EXPORT extern int bu_is_parallel(void);
72 
73 /**
74  * returns the CPU number of the current bu_parallel() invoked thread.
75  */
76 BU_EXPORT extern int bu_parallel_id(void);
77 
78 /** @file libbu/kill.c
79  *
80  * terminate a given process.
81  *
82  */
83 
84 /**
85  * terminate a given process.
86  *
87  * returns truthfully whether the process could be killed.
88  */
89 BU_EXPORT extern int bu_terminate(int process);
90 
91 /** @file libbu/process.c
92  *
93  * process management routines
94  *
95  */
96 
97 /**
98  * returns the process ID of the calling process
99  */
100 BU_EXPORT extern int bu_process_id(void);
101 
102 /** @file libbu/parallel.c
103  *
104  * routines for parallel processing
105  *
106  * Machine-specific routines for portable parallel processing.
107  *
108  */
109 
110 /**
111  * Without knowing what the current UNIX "nice" value is, change to a
112  * new absolute "nice" value. (The system routine makes a relative
113  * change).
114  */
115 BU_EXPORT extern void bu_nice_set(int newnice);
116 
117 /**
118  * Return the maximum number of physical CPUs that are considered to
119  * be available to this process now.
120  */
121 BU_EXPORT extern size_t bu_avail_cpus(void);
122 
123 
124 /**
125  * Create parallel threads of execution.
126  *
127  * This function creates (at most) 'ncpu' copies of function 'func'
128  * all running in parallel, passing 'data' to each invocation.
129  * Specifying ncpu=0 will specify automatic parallelization, invoking
130  * parallel threads as cores become available. This is particularly
131  * useful during recursive invocations where the ncpu core count is
132  * limited by the parent context.
133  *
134  * Locking and work dispatching are handled by 'func' using a
135  * "self-dispatching" paradigm. This means you must manually protect
136  * shared data structures, e.g., via BU_SEMAPHORE_ACQUIRE().
137  * Lock-free execution is often possible by creating data containers
138  * with MAX_PSW elements as bu_parallel will never execute more than
139  * that many threads of execution.
140  *
141  * All invocations of the specified 'func' callback function are
142  * passed two parameters: 1) it's assigned thread number and 2) a
143  * shared 'data' pointer for application use. Threads are assigned
144  * increasing numbers, starting with zero. Processes may also call
145  * bu_parallel_id() to obtain their thread number.
146  *
147  * Threads created with bu_parallel() may specify utilization of
148  * affinity locking to keep threads on a given physical CPU core.
149  * This behavior can be enabled at runtime by setting the environment
150  * variable LIBBU_AFFINITY=1. Note that this option may increase or
151  * even decrease performance, particularly on platforms with advanced
152  * scheduling, so testing is recommended.
153  *
154  * This function will not return control until all invocations of the
155  * subroutine are finished.
156  */
157 BU_EXPORT extern void bu_parallel(void (*func)(int func_ncpu, void *func_data), int ncpu, void *data);
158 
159 
160 /** @file libbu/semaphore.c
161  *
162  * semaphore implementation
163  *
164  * Machine-specific routines for parallel processing. Primarily for
165  * handling semaphores to protect critical sections of code.
166  *
167  * The new paradigm: semaphores are referred to, not by a pointer, but
168  * by a small integer. This module is now responsible for obtaining
169  * whatever storage is needed to implement each semaphore.
170  *
171  * Note that these routines can't use bu_log() for error logging,
172  * because bu_log() acquires semaphore #0 (BU_SEM_SYSCALL).
173  */
174 
175 /*
176  * Section for manifest constants for bu_semaphore_acquire()
177  */
178 #define BU_SEM_SYSCALL 0
179 #define BU_SEM_LISTS 1
180 #define BU_SEM_BN_NOISE 2
181 #define BU_SEM_MAPPEDFILE 3
182 #define BU_SEM_THREAD 4
183 #define BU_SEM_MALLOC 5
184 #define BU_SEM_DATETIME 6
185 #define BU_SEM_LAST (BU_SEM_DATETIME+1) /* allocate this many for LIBBU+LIBBN */
186 /*
187  * Automatic restart capability in bu_bomb(). The return from
188  * BU_SETJUMP is the return from the setjmp(). It is 0 on the first
189  * pass through, and non-zero when re-entered via a longjmp() from
190  * bu_bomb(). This is only safe to use in non-parallel applications.
191  */
192 #define BU_SETJUMP setjmp((bu_setjmp_valid[bu_parallel_id()]=1, bu_jmpbuf[bu_parallel_id()]))
193 #define BU_UNSETJUMP (bu_setjmp_valid[bu_parallel_id()]=0)
194 
195 /* These are global because BU_SETJUMP must be macro. Please don't touch. */
196 BU_EXPORT extern int bu_setjmp_valid[MAX_PSW]; /* !0 = bu_jmpbuf is valid */
197 BU_EXPORT extern jmp_buf bu_jmpbuf[MAX_PSW]; /* for BU_SETJUMP() */
198 
199 
200 /**
201  * Prepare 'nsemaphores' independent critical section semaphores. Die
202  * on error.
203  *
204  * Takes the place of 'n' separate calls to old RES_INIT(). Start by
205  * allocating array of "struct bu_semaphores", which has been arranged
206  * to contain whatever this system needs.
207  *
208  */
209 BU_EXPORT extern void bu_semaphore_init(unsigned int nsemaphores);
210 
211 /**
212  * Release all initialized semaphores and any associated memory.
213  */
214 BU_EXPORT extern void bu_semaphore_free(void);
215 
216 BU_EXPORT extern void bu_semaphore_acquire(unsigned int i);
217 
218 BU_EXPORT extern void bu_semaphore_release(unsigned int i);
219 
220 /** @} */
221 
223 
224 #endif /* BU_PARALLEL_H */
225 
226 /*
227  * Local Variables:
228  * mode: C
229  * tab-width: 8
230  * indent-tabs-mode: t
231  * c-file-style: "stroustrup"
232  * End:
233  * ex: shiftwidth=4 tabstop=8
234  */
void bu_semaphore_init(unsigned int nsemaphores)
Definition: semaphore.c:82
void bu_semaphore_acquire(unsigned int i)
Definition: semaphore.c:180
int bu_process_id(void)
Definition: process.c:31
Header file for the BRL-CAD common definitions.
int bu_setjmp_valid[MAX_PSW]
Definition: globals.c:74
DEPRECATED int bu_is_parallel(void)
Definition: parallel.c:159
int bu_terminate(int process)
Definition: kill.c:37
COMPLEX data[64]
Definition: fftest.c:34
#define DEPRECATED
Definition: common.h:303
#define __BEGIN_DECLS
Definition: common.h:73
void bu_nice_set(int newnice)
Definition: parallel.c:167
int bu_parallel_id(void)
Definition: parallel.c:152
void bu_semaphore_release(unsigned int i)
Definition: semaphore.c:218
size_t bu_avail_cpus(void)
Definition: parallel.c:193
#define MAX_PSW
Definition: parallel.h:48
void bu_parallel(void(*func)(int func_ncpu, void *func_data), int ncpu, void *data)
void bu_semaphore_free(void)
Definition: semaphore.c:144
#define __END_DECLS
Definition: common.h:74
jmp_buf bu_jmpbuf[MAX_PSW]
Definition: globals.c:84