// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.concurrent; import com.yahoo.concurrent.ThreadLocalDirectory.ObservableUpdater; import com.yahoo.concurrent.ThreadLocalDirectory.Updater; /** * Only for use along with ThreadLocalDirectory. A thread local data container * instance. The class is visible to avoid indirection through the internal * {@link ThreadLocal} in ThreadLocalDirectory if possible, but has no user * available methods. * * @param the structure to insert produced data into * @param type of produced data to insert from each participating thread * @author Steinar Knutsen */ public final class LocalInstance { /** * The current generation of data produced from a single thread, where * generation is the period between two subsequent calls to * ThreadLocalDirectory.fetch(). */ private AGGREGATOR current; // see comment on setRegistered(boolean) for locking explanation private boolean isRegistered = false; private final Object lock = new Object(); LocalInstance(Updater updater) { current = updater.createGenerationInstance(null); } boolean update(SAMPLE x, Updater updater) { synchronized (lock) { current = updater.update(current, x); return isRegistered; } } AGGREGATOR getAndReset(Updater updater) { AGGREGATOR previous; synchronized (lock) { previous = current; current = updater.createGenerationInstance(previous); setRegistered(false); } return previous; } AGGREGATOR copyCurrent(ObservableUpdater updater) { AGGREGATOR view; synchronized (lock) { view = updater.copy(current); } return view; } // This is either set by the putting thread or the fetching thread. If // it is set by the putting thread, then there is no memory barrier, // because it is only _read_ in the putting thread. If it is set by the // fetching thread, then the memory barrier is this.lock. This // roundabout way is to avoid creating many-to-many memory barrier and // locking relationships. void setRegistered(boolean isRegistered) { this.isRegistered = isRegistered; } }