@SuppressWarnings("unchecked") public ConcurrentChunkedFIFO(int chunkSize, Maker<T> maker, boolean needSize) { this(chunkSize, null, null, needSize); int numThreads = GaloisRuntime.getRuntime().getMaxThreads(); current = new Worklist[numThreads * CACHE_MULTIPLE]; next = new Worklist[numThreads * CACHE_MULTIPLE]; for (int i = 0; i < numThreads; i++) { current[getIndex(i)] = maker.make(); next[getIndex(i)] = maker.make(); } }
/** * Creates a mappable over integers in a range. * * @param start starting integer * @param end ending integer (exclusive) * @return a mappable over [start, end) */ public static Mappable<Integer> range(int start, int end) { int chunkSize = 2 * GaloisRuntime.getRuntime().getMaxThreads(); return range(start, end, chunkSize); }
/** * Creates a mappable view from a list. Behavior is undefined if the backing list * is modified during iteration. * * @param <T> type of elements of the list * @param list list that this mappable is a view of * @return a mappable view of the given list */ public static <T> Mappable<T> fromList(final List<T> list) { final int size = list.size(); final int chunkSize = 2 * GaloisRuntime.getRuntime().getMaxThreads(); final AtomicInteger cur = new AtomicInteger(); return new Mappable<T>() { @Override public void mapInternal(LambdaVoid<T> body, MapInternalContext ctx) { for (int i = cur.getAndAdd(chunkSize); i < size; i = cur.getAndAdd(chunkSize)) { for (int j = 0; j < chunkSize; j++) { int index = i + j; if (index >= size) break; while (true) { try { T item = list.get(index); ctx.begin(); body.call(item); ctx.commit(item); break; } catch (IterationAbortException _) { ctx.abort(); } } } } } @Override public <A1> void mapInternal(Lambda2Void<T, A1> body, MapInternalContext ctx, A1 arg1) { for (int i = cur.getAndAdd(chunkSize); i < size; i = cur.getAndAdd(chunkSize)) { for (int j = 0; j < chunkSize; j++) { int index = i + j; if (index >= size) break; while (true) { try { T item = list.get(index); ctx.begin(); body.call(item, arg1); ctx.commit(item); break; } catch (IterationAbortException _) { ctx.abort(); } } } } } @Override public <A1, A2> void mapInternal(Lambda3Void<T, A1, A2> body, MapInternalContext ctx, A1 arg1, A2 arg2) { for (int i = cur.getAndAdd(chunkSize); i < size; i = cur.getAndAdd(chunkSize)) { for (int j = 0; j < chunkSize; j++) { int index = i + j; if (index >= size) break; while (true) { try { T item = list.get(index); ctx.begin(); body.call(item, arg1, arg2); ctx.commit(item); break; } catch (IterationAbortException _) { ctx.abort(); } } } } } @Override public final void map(LambdaVoid<T> body) { map(body, MethodFlag.ALL); } @Override public void map(LambdaVoid<T> body, byte flags) { for (int i = 0; i < size; i++) { body.call(list.get(i)); } } @Override public final <A1> void map(Lambda2Void<T, A1> body, A1 arg1) { map(body, arg1, MethodFlag.ALL); } @Override public <A1> void map(Lambda2Void<T, A1> body, A1 arg1, byte flags) { for (int i = 0; i < size; i++) { body.call(list.get(i), arg1); } } @Override public final <A1, A2> void map(Lambda3Void<T, A1, A2> body, A1 arg1, A2 arg2) { map(body, arg1, arg2, MethodFlag.ALL); } @Override public <A1, A2> void map(Lambda3Void<T, A1, A2> body, A1 arg1, A2 arg2, byte flags) { for (int i = 0; i < size; i++) { body.call(list.get(i), arg1, arg2); } } @Override public void mapInternalDone() { cur.set(0); } }; }