ConcurrencyUtils.java (10268B)
1 /* 2 * _______ _____ _____ _____ 3 * |__ __| | __ \ / ____| __ \ 4 * | | __ _ _ __ ___ ___ ___| | | | (___ | |__) | 5 * | |/ _` | '__/ __|/ _ \/ __| | | |\___ \| ___/ 6 * | | (_| | | \__ \ (_) \__ \ |__| |____) | | 7 * |_|\__,_|_| |___/\___/|___/_____/|_____/|_| 8 * 9 * ------------------------------------------------------------- 10 * 11 * TarsosDSP is developed by Joren Six at IPEM, University Ghent 12 * 13 * ------------------------------------------------------------- 14 * 15 * Info: http://0110.be/tag/TarsosDSP 16 * Github: https://github.com/JorenSix/TarsosDSP 17 * Releases: http://0110.be/releases/TarsosDSP/ 18 * 19 * TarsosDSP includes modified source code by various authors, 20 * for credits and info, see README. 21 * 22 */ 23 24 25 /* ***** BEGIN LICENSE BLOCK ***** 26 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 27 * 28 * The contents of this file are subject to the Mozilla Public License Version 29 * 1.1 (the "License"); you may not use this file except in compliance with 30 * the License. You may obtain a copy of the License at 31 * http://www.mozilla.org/MPL/ 32 * 33 * Software distributed under the License is distributed on an "AS IS" basis, 34 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 35 * for the specific language governing rights and limitations under the 36 * License. 37 * 38 * The Original Code is Parallel Colt. 39 * 40 * The Initial Developer of the Original Code is 41 * Piotr Wendykier, Emory University. 42 * Portions created by the Initial Developer are Copyright (C) 2007-2009 43 * the Initial Developer. All Rights Reserved. 44 * 45 * Alternatively, the contents of this file may be used under the terms of 46 * either the GNU General Public License Version 2 or later (the "GPL"), or 47 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 48 * in which case the provisions of the GPL or the LGPL are applicable instead 49 * of those above. If you wish to allow use of your version of this file only 50 * under the terms of either the GPL or the LGPL, and not to allow others to 51 * use your version of this file under the terms of the MPL, indicate your 52 * decision by deleting the provisions above and replace them with the notice 53 * and other provisions required by the GPL or the LGPL. If you do not delete 54 * the provisions above, a recipient may use your version of this file under 55 * the terms of any one of the MPL, the GPL or the LGPL. 56 * 57 * ***** END LICENSE BLOCK ***** */ 58 package be.tarsos.dsp.util; 59 60 import java.util.concurrent.ExecutionException; 61 import java.util.concurrent.ExecutorService; 62 import java.util.concurrent.Executors; 63 import java.util.concurrent.Future; 64 import java.util.concurrent.ThreadFactory; 65 66 /** 67 * Concurrency utilities. 68 * 69 * @author Piotr Wendykier (piotr.wendykier@gmail.com) 70 */ 71 public class ConcurrencyUtils { 72 /** 73 * Thread pool. 74 */ 75 private static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool(new CustomThreadFactory(new CustomExceptionHandler())); 76 77 private static int THREADS_BEGIN_N_1D_FFT_2THREADS = 8192; 78 79 private static int THREADS_BEGIN_N_1D_FFT_4THREADS = 65536; 80 81 private static int THREADS_BEGIN_N_2D = 65536; 82 83 private static int THREADS_BEGIN_N_3D = 65536; 84 85 private static int NTHREADS = prevPow2(getNumberOfProcessors()); 86 87 private ConcurrencyUtils() { 88 89 } 90 91 private static class CustomExceptionHandler implements Thread.UncaughtExceptionHandler { 92 public void uncaughtException(Thread t, Throwable e) { 93 e.printStackTrace(); 94 } 95 96 } 97 98 private static class CustomThreadFactory implements ThreadFactory { 99 private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory(); 100 101 private final Thread.UncaughtExceptionHandler handler; 102 103 CustomThreadFactory(Thread.UncaughtExceptionHandler handler) { 104 this.handler = handler; 105 } 106 107 public Thread newThread(Runnable r) { 108 Thread t = defaultFactory.newThread(r); 109 t.setUncaughtExceptionHandler(handler); 110 return t; 111 } 112 }; 113 114 /** 115 * Returns the number of available processors. 116 * 117 * @return number of available processors 118 */ 119 public static int getNumberOfProcessors() { 120 return Runtime.getRuntime().availableProcessors(); 121 } 122 123 /** 124 * Returns the current number of threads. 125 * 126 * @return the current number of threads. 127 */ 128 public static int getNumberOfThreads() { 129 return NTHREADS; 130 } 131 132 /** 133 * Sets the number of threads. If n is not a power-of-two number, then the 134 * number of threads is set to the closest power-of-two number less than n. 135 * 136 * @param n 137 */ 138 public static void setNumberOfThreads(int n) { 139 NTHREADS = prevPow2(n); 140 } 141 142 /** 143 * Returns the minimal size of 1D data for which two threads are used. 144 * 145 * @return the minimal size of 1D data for which two threads are used 146 */ 147 public static int getThreadsBeginN_1D_FFT_2Threads() { 148 return THREADS_BEGIN_N_1D_FFT_2THREADS; 149 } 150 151 /** 152 * Returns the minimal size of 1D data for which four threads are used. 153 * 154 * @return the minimal size of 1D data for which four threads are used 155 */ 156 public static int getThreadsBeginN_1D_FFT_4Threads() { 157 return THREADS_BEGIN_N_1D_FFT_4THREADS; 158 } 159 160 /** 161 * Returns the minimal size of 2D data for which threads are used. 162 * 163 * @return the minimal size of 2D data for which threads are used 164 */ 165 public static int getThreadsBeginN_2D() { 166 return THREADS_BEGIN_N_2D; 167 } 168 169 /** 170 * Returns the minimal size of 3D data for which threads are used. 171 * 172 * @return the minimal size of 3D data for which threads are used 173 */ 174 public static int getThreadsBeginN_3D() { 175 return THREADS_BEGIN_N_3D; 176 } 177 178 /** 179 * Sets the minimal size of 1D data for which two threads are used. 180 * 181 * @param n 182 * the minimal size of 1D data for which two threads are used 183 */ 184 public static void setThreadsBeginN_1D_FFT_2Threads(int n) { 185 if (n < 512) { 186 THREADS_BEGIN_N_1D_FFT_2THREADS = 512; 187 } else { 188 THREADS_BEGIN_N_1D_FFT_2THREADS = n; 189 } 190 } 191 192 /** 193 * Sets the minimal size of 1D data for which four threads are used. 194 * 195 * @param n 196 * the minimal size of 1D data for which four threads are used 197 */ 198 public static void setThreadsBeginN_1D_FFT_4Threads(int n) { 199 if (n < 512) { 200 THREADS_BEGIN_N_1D_FFT_4THREADS = 512; 201 } else { 202 THREADS_BEGIN_N_1D_FFT_4THREADS = n; 203 } 204 } 205 206 /** 207 * Sets the minimal size of 2D data for which threads are used. 208 * 209 * @param n 210 * the minimal size of 2D data for which threads are used 211 */ 212 public static void setThreadsBeginN_2D(int n) { 213 THREADS_BEGIN_N_2D = n; 214 } 215 216 /** 217 * Sets the minimal size of 3D data for which threads are used. 218 * 219 * @param n 220 * the minimal size of 3D data for which threads are used 221 */ 222 public static void setThreadsBeginN_3D(int n) { 223 THREADS_BEGIN_N_3D = n; 224 } 225 226 /** 227 * Resets the minimal size of 1D data for which two and four threads are 228 * used. 229 */ 230 public static void resetThreadsBeginN_FFT() { 231 THREADS_BEGIN_N_1D_FFT_2THREADS = 8192; 232 THREADS_BEGIN_N_1D_FFT_4THREADS = 65536; 233 } 234 235 /** 236 * Resets the minimal size of 2D and 3D data for which threads are used. 237 */ 238 public static void resetThreadsBeginN() { 239 THREADS_BEGIN_N_2D = 65536; 240 THREADS_BEGIN_N_3D = 65536; 241 } 242 243 /** 244 * Returns the closest power-of-two number greater than or equal to x. 245 * 246 * @param x 247 * @return the closest power-of-two number greater than or equal to x 248 */ 249 public static int nextPow2(int x) { 250 if (x < 1) 251 throw new IllegalArgumentException("x must be greater or equal 1"); 252 if ((x & (x - 1)) == 0) { 253 return x; // x is already a power-of-two number 254 } 255 x |= (x >>> 1); 256 x |= (x >>> 2); 257 x |= (x >>> 4); 258 x |= (x >>> 8); 259 x |= (x >>> 16); 260 x |= (x >>> 32); 261 return x + 1; 262 } 263 264 /** 265 * Returns the closest power-of-two number less than or equal to x. 266 * 267 * @param x 268 * @return the closest power-of-two number less then or equal to x 269 */ 270 public static int prevPow2(int x) { 271 if (x < 1) 272 throw new IllegalArgumentException("x must be greater or equal 1"); 273 return (int) Math.pow(2, Math.floor(Math.log(x) / Math.log(2))); 274 } 275 276 /** 277 * Checks if x is a power-of-two number. 278 * 279 * @param x 280 * @return true if x is a power-of-two number 281 */ 282 public static boolean isPowerOf2(int x) { 283 if (x <= 0) 284 return false; 285 else 286 return (x & (x - 1)) == 0; 287 } 288 289 /** 290 * Causes the currently executing thread to sleep (temporarily cease 291 * execution) for the specified number of milliseconds. 292 * 293 * @param millis 294 */ 295 public static void sleep(long millis) { 296 try { 297 Thread.sleep(5000); 298 } catch (InterruptedException e) { 299 e.printStackTrace(); 300 } 301 } 302 303 /** 304 * Submits a Runnable task for execution and returns a Future representing 305 * that task. 306 * 307 * @param task a Runnable task for execution 308 * @return a Future representing the task 309 */ 310 public static Future<?> submit(Runnable task) { 311 return THREAD_POOL.submit(task); 312 } 313 314 /** 315 * Waits for all threads to complete computation. 316 * 317 * @param futures 318 */ 319 public static void waitForCompletion(Future<?>[] futures) { 320 int size = futures.length; 321 try { 322 for (int j = 0; j < size; j++) { 323 futures[j].get(); 324 } 325 } catch (ExecutionException ex) { 326 ex.printStackTrace(); 327 } catch (InterruptedException e) { 328 e.printStackTrace(); 329 } 330 } 331 }