Index: src/libbu/CMakeLists.txt =================================================================== --- src/libbu/CMakeLists.txt (revision 70477) +++ src/libbu/CMakeLists.txt (working copy) @@ -94,6 +94,7 @@ mread.c observer.c opt.c + parallel_cpp11thread.cpp parallel.c parse.c path.c @@ -125,7 +126,7 @@ ) BRLCAD_ADDLIB(libbu "${LIBBU_SOURCES}" "${CMAKE_THREAD_LIBS_INIT};${DL_LIBRARY};${WINSOCK_LIB};${PSAPI_LIB};${BSON_LIBRARIES};${UUID_LIBRARIES};${REGEX_LIBRARY};${M_LIBRARY}") -set_target_properties(libbu PROPERTIES VERSION 20.0.1 SOVERSION 20) +set_target_properties(libbu PROPERTIES VERSION 20.0.1 SOVERSION 20 CXX_STANDARD 11) BRLCAD_ADDDATA(fix.6r vfont) BRLCAD_ADDDATA(nonie.r.12 vfont) Index: src/libbu/parallel.c =================================================================== --- src/libbu/parallel.c (revision 70477) +++ src/libbu/parallel.c (working copy) @@ -132,6 +132,9 @@ }; +void parallel_cpp(void (*func)(size_t, void *), size_t ncpu, void *arg); + + int bu_parallel_id(void) { @@ -461,6 +464,20 @@ /* do the work anyways */ (*func)(0, arg); +#elif HAVE_THREAD_LOCAL + + if (!func) + return; /* nothing to do */ + + if (ncpu == 1) { + return func(ncpu, arg); + } else if (ncpu > MAX_PSW) { + bu_log("WARNING: bu_parallel() ncpu(%zd) > MAX_PSW(%d), adjusting ncpu\n", ncpu, MAX_PSW); + ncpu = MAX_PSW; + } + + parallel_cpp(func, ncpu, arg); + #else struct thread_data *thread_context; Index: src/libbu/parallel_cpp11thread.cpp =================================================================== --- src/libbu/parallel_cpp11thread.cpp (nonexistent) +++ src/libbu/parallel_cpp11thread.cpp (working copy) @@ -0,0 +1,60 @@ +/* P A R A L L E L _ C P P 1 1 T H R E A D . C P P + * BRL-CAD + * + * Copyright (c) 2013-2016 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ + +#include "common.h" + +#include +#include +#include + +void parallel_cpp(void (*func)(int, void *), size_t ncpu, void *arg) +{ + std::vector threads; + + if (!ncpu) { + ncpu = std::thread::hardware_concurrency(); + + /* If ncpu is 0 now, then the hardware either doesn't support + * threads, or they aren't known to the implementation. + * Revert to single threading. + */ + if (!ncpu) + return func(ncpu, arg); + } + + /* Create and run threads. */ + for (size_t i = 0; i < ncpu; ++i) + threads.emplace_back(func, ncpu, arg); + + /* Wait for the parallel task to complete. */ + for (size_t i = 0; i < threads.size(); ++i) + threads[i].join(); +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ +