Beispiel #1
0
 private void sleep() {
   try {
     Thread.sleep(1);
   } catch (InterruptedException e) {
     e.printStackTrace();
   }
 }
Beispiel #2
0
 /**
  * @return if <0, then this pipe should be stopped. If ==0, it should not wait. If >0, if it
  *     should wait
  */
 int execute() {
   if (!lock.tryAcquire()) return 1; // currently being accessed
   Thread myThread = Thread.currentThread();
   int threadIndex = -1;
   for (int i = 0; i < threads.length; i++) {
     if (threads[i] == null) {
       threads[i] = myThread;
       threadIndex = i;
       break;
     }
     if (myThread != threads[i]) continue;
     threadIndex = i;
     break;
   }
   Signal signal;
   if (threadIndex < 0) {
     signal = dummySignal;
   } else {
     SignalImpl s = signals[threadIndex];
     s.threadIndex = threadIndex;
     s.signaled = false;
     signal = s;
   }
   boolean hasData;
   try {
     hasData = poll(signal, null);
   } finally {
     signal.signal();
     if (threadIndex < 0) lock.release();
   }
   return 0;
 }
Beispiel #3
0
 @Override
 public void run() {
   try {
     while (started) {
       int result = execute();
       if (result < 0) break;
       if (result > 0) {
         if (sleep > 0) {
           Thread.sleep(sleep);
           sleptTime += sleep;
         } else if (sleep < 0) Thread.yield();
       } else if (adding) {
         Thread.sleep(1);
       } else {
         if (sleep > 0) {
           incrementTime++;
           if (incrementTime % 1_000_000 == 0) {
             toSleepTime += sleep;
             if (sleptTime < toSleepTime) {
               sleptTime += sleep;
               Thread.sleep(sleep);
             }
           }
         }
       }
     }
   } catch (InterruptedException e) {
     if (started) {
       if (listener == null) logger.warn("polling", e);
       else listener.exceptionThrown(e);
     }
   } catch (Exception e) {
     if (listener == null) logger.error("polling", e);
     else listener.exceptionThrown(e);
   }
 }
Beispiel #4
0
 @Override
 public synchronized Receptor<T> takeReceptor() {
   if (!freeReceptors.isEmpty()) {
     ReceptorImpl impl = (ReceptorImpl) freeReceptors.remove(0);
     impl.skips = 0;
     return impl;
   }
   int length = inputs.length() + 1;
   final AtomicReferenceArray<T> inputs = new AtomicReferenceArray<>(length);
   this.inputs = inputs;
   final List<ReceptorImpl> newReuseReceptors = new ArrayList<>(length);
   for (int i = 0; i < length; i++) {
     newReuseReceptors.add(new ReceptorImpl(i));
   }
   executor.execute(
       () -> {
         long lastTime = System.currentTimeMillis();
         try {
           boolean empty = false;
           while (!empty && started) {
             empty = true;
             for (int i = 0; i < outputs.length(); i++) {
               T result = outputs.get(i);
               if (result == null) continue;
               Thread.sleep(1);
               empty = false;
               if (lastTime + 30_000 < System.currentTimeMillis()) {
                 lastTime = System.currentTimeMillis();
                 logger.error(
                     "unable to set receptors for " + producer + " i=" + i + " result=" + result);
                 if (pool != null) logger.warn("pool=" + pool.producer);
               }
               break;
             }
           }
         } catch (InterruptedException e) {
           logger.warn("takeReceptor", e);
         } finally {
           reuseReceptors = newReuseReceptors;
           outputs = inputs;
         }
       });
   return new ReceptorImpl(length - 1);
 }
Beispiel #5
0
 /**
  * Look for data from all the inputs
  *
  * @return true if data was consumed
  */
 private boolean poll(Signal signal, Signal parent) {
   AtomicReferenceArray<T> o = outputs;
   for (int i = 0; i < o.length(); i++) {
     T input = o.getAndSet(i, null);
     if (input == null) continue;
     long seq = ++sequence;
     if (parent != null) parent.signal();
     S product = producer.execute(input, reuseReceptors.get(i), signal);
     signal.signal();
     if (!consume(product, seq, 0)) {
       Thread.yield();
       if (!consume(product, seq, 0))
         logger.info(
             "failed to consume product (" + product + ") from producer (" + producer + ")");
     }
     producer.complete(product);
     return product != null;
   }
   return false;
 }
Beispiel #6
0
  public void start() {
    inputs = new AtomicReferenceArray<>(0);
    outputs = inputs;
    freeReceptors = new CopyOnWriteArrayList<>();
    sequence = 0;
    finalSequence = 0;
    finalProduct = null;
    reuseReceptors = new ArrayList<>(0);
    executor = Executors.newSingleThreadExecutor();

    started = true;
    if (poolSize > 0) {
      group = new ThreadGroup("FatPipe");
      group.setMaxPriority(Thread.MAX_PRIORITY);
    }
    signals = new SignalImpl[ARBITARY_THREADS + poolSize];
    threads = new Thread[ARBITARY_THREADS + poolSize];
    startTime = System.currentTimeMillis();
    sleptTime = 0;
    toSleepTime = 0;

    for (int i = 0; i < poolSize; i++) {
      Thread t = new Thread(group, this, name + "-" + i);
      t.setDaemon(true);
      threads[i] = t;
      t.start();
      if (sleep == 0) t.setPriority(Thread.MAX_PRIORITY);
      else if (sleep < 0) t.setPriority(Thread.NORM_PRIORITY);
      else t.setPriority(Thread.MIN_PRIORITY);
    }
    for (int i = 0; i < signals.length; i++) {
      signals[i] = new SignalImpl(lock);
    }
    if (pool != null) pool.add(this);
    lock.release();
  }
Beispiel #7
-1
  /**
   * @param product
   * @param sequence
   * @return false if there is an error
   */
  boolean consume(S product, long sequence, long sleep) {
    if (product == null) return true;

    // make copies
    Consumer<S>[] consumers = this.consumers;
    AtomicLongArray outUse = this.outUse;
    long[] consumerSeqs = this.consumerSeqs;

    if (outUse.length() != consumers.length) return false;
    for (int j = 0; j < consumers.length; j++) {
      if (!consumers[j].isConsuming()) continue;
      long time = System.nanoTime();
      if (!outUse.compareAndSet(j, 0, time)) continue;
      try {
        if (sequence <= consumerSeqs[j]) {
          outUse.lazySet(j, 0);
          if (outUse != this.outUse) resetConsumer(consumers[j]);
          break;
        }
        consumerSeqs[j] = sequence;
        consumers[j].consume(product, time);
        if (sleep > 0) Thread.sleep(sleep);
        outUse.lazySet(j, 0);
        if (outUse != this.outUse) {
          resetConsumer(consumers[j]);
          break;
        }
      } catch (Exception e) {
        if (listener == null) logger.error("consume", e);
        else listener.exceptionThrown(e);
      }
    }
    finishConsuming(product, sequence);
    return true;
  }