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