cannam@127: /* cannam@127: * Copyright (c) 2003, 2007-14 Matteo Frigo cannam@127: * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology cannam@127: * cannam@127: * This program is free software; you can redistribute it and/or modify cannam@127: * it under the terms of the GNU General Public License as published by cannam@127: * the Free Software Foundation; either version 2 of the License, or cannam@127: * (at your option) any later version. cannam@127: * cannam@127: * This program is distributed in the hope that it will be useful, cannam@127: * but WITHOUT ANY WARRANTY; without even the implied warranty of cannam@127: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the cannam@127: * GNU General Public License for more details. cannam@127: * cannam@127: * You should have received a copy of the GNU General Public License cannam@127: * along with this program; if not, write to the Free Software cannam@127: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA cannam@127: * cannam@127: */ cannam@127: cannam@127: /* openmp.c: thread spawning via OpenMP */ cannam@127: cannam@127: #include "threads.h" cannam@127: cannam@127: #if !defined(_OPENMP) cannam@127: #error OpenMP enabled but not using an OpenMP compiler cannam@127: #endif cannam@127: cannam@127: int X(ithreads_init)(void) cannam@127: { cannam@127: return 0; /* no error */ cannam@127: } cannam@127: cannam@127: /* Distribute a loop from 0 to loopmax-1 over nthreads threads. cannam@127: proc(d) is called to execute a block of iterations from d->min cannam@127: to d->max-1. d->thr_num indicate the number of the thread cannam@127: that is executing proc (from 0 to nthreads-1), and d->data is cannam@127: the same as the data parameter passed to X(spawn_loop). cannam@127: cannam@127: This function returns only after all the threads have completed. */ cannam@127: void X(spawn_loop)(int loopmax, int nthr, spawn_function proc, void *data) cannam@127: { cannam@127: int block_size; cannam@127: spawn_data d; cannam@127: int i; cannam@127: cannam@127: A(loopmax >= 0); cannam@127: A(nthr > 0); cannam@127: A(proc); cannam@127: cannam@127: if (!loopmax) return; cannam@127: cannam@127: /* Choose the block size and number of threads in order to (1) cannam@127: minimize the critical path and (2) use the fewest threads that cannam@127: achieve the same critical path (to minimize overhead). cannam@127: e.g. if loopmax is 5 and nthr is 4, we should use only 3 cannam@127: threads with block sizes of 2, 2, and 1. */ cannam@127: block_size = (loopmax + nthr - 1) / nthr; cannam@127: nthr = (loopmax + block_size - 1) / block_size; cannam@127: cannam@127: THREAD_ON; /* prevent debugging mode from failing under threads */ cannam@127: #pragma omp parallel for private(d) cannam@127: for (i = 0; i < nthr; ++i) { cannam@127: d.max = (d.min = i * block_size) + block_size; cannam@127: if (d.max > loopmax) cannam@127: d.max = loopmax; cannam@127: d.thr_num = i; cannam@127: d.data = data; cannam@127: proc(&d); cannam@127: } cannam@127: THREAD_OFF; /* prevent debugging mode from failing under threads */ cannam@127: } cannam@127: cannam@127: void X(threads_cleanup)(void) cannam@127: { cannam@127: } cannam@127: cannam@127: /* FIXME [Matteo Frigo 2015-05-25] What does "thread-safe" cannam@127: mean for openmp? */ cannam@127: void X(threads_register_planner_hooks)(void) cannam@127: { cannam@127: }