public void runExtreme()

in Extremem/src/main/java/com/amazon/corretto/benchmark/extremem/ServerThread.java [95:235]


  public void runExtreme() {
    while (true) {
      // If the simulation will have ended before we wake up, don't
      // even bother to sleep.
      if (next_release_time.compare(end_simulation_time) >= 0)
        break;

      AbsoluteTime now = next_release_time.sleep(this);
      now.garbageFootprint(this);

      // In an earlier implementation, termination of the thread was
      // determined by comparing next_release_time against
      // end_simulation_time. In the case that the thread falls
      // hopelessly behind schedule, the thread "never" terminates.
      if (now.compare(end_simulation_time) >= 0)
        break;

      Trace.msg(4, "Server ", label, ": attention: ",
                Integer.toString(attention));

      switch (attention) {
        case 0:
          // Statistically, the number of pending SalesTransaction
          // instances that accumulate on my sales_queue since the
          // last time I serviced this queue should be approximately
          // constant.   The greatest source of variance would be
          // contention with other server threads that might be
          // servicing the same queue.
          int transaction_count = 0;
          while (true) {
            SalesTransaction x = sales_queue.dequeue();
            if (x != null) {
              transaction_count++;
              // Note that either the customer or the product may be
              // decommissioned prior to transaction of the sale.  Our
              // simple implementation of transaction is not harmed by
              // either.  In the case that either of these entities is
              // decommissioned while transaction is pending, the
              // SalesTransaction object will force the entity to
              // remain alive until the transaction is performed.
              // Thereafter, the decommissioned object will be
              // eligible for garbage collection.  To simplify
              // bookkeeping, we account that the object has become
              // garbage at the moment it is decommissioned, even
              // though the garbage collector may have to wait for the
              // sale to be transacted before reclaiming it.
              Customer c = x.customer();
              c.transactSale(this, next_release_time, x);
              x.garbageFootprint(this);
            } else
              break;
          }
          Trace.msg(4, "Server ", label, ": processed sales transactions: ",
                    Integer.toString(transaction_count));
          history.logTransactions(this, next_release_time, transaction_count);
          break;
        case 1:
          // Statistically, the number of BrowsingHistory instances that
          // expire since the last time I serviced this queue should
          // be approximately constant.  The greatest source of
          // variance would be contention with other server threads
          // that might be servicing the same queue.
          int browsing_expirations = 0;
          while (true) {
            BrowsingHistory h;
            h = browsing_queue.pullIfExpired(next_release_time);
            if (h != null) {
              browsing_expirations++;
              Customer c = h.customer();
              c.retireOneSaveForLater(h);
              h.garbageFootprint(this);
            } else
              break;
          }
          Trace.msg(4, "Server ", label, ": browsing_expirations: ",
                    Integer.toString(browsing_expirations));
          history.logHistories(this, next_release_time, browsing_expirations);
          break;
        case 2:
          if (next_release_time.compare(customer_replacement_time) >= 0) {
            for (int i = config.CustomerReplacementCount(); i > 0; i--)
              all_customers.replaceRandomCustomer(this);

            customer_replacement_time.garbageFootprint(this);
            customer_replacement_time = (
              customer_replacement_time
              .addRelative(this, config.CustomerReplacementPeriod()));
            customer_replacement_time.changeLifeSpan(this,
                                                     LifeSpan.TransientShort);
            Trace.msg(4, "Server ", label, ": replaced ",
                      Integer.toString(config.CustomerReplacementCount()),
                      " customers");
            history.logCustomers(this, next_release_time,
                                 config.CustomerReplacementCount());
          } else {
            Trace.msg(4, "Server ", label, ": too early to replace customers");
            history.logDoNothings(this, next_release_time);
          }
          break;
        case 3:
          assert (3 + 1 == TotalAttentionPoints): "Bad TotalAttentionPoints";
          if (next_release_time.compare(product_replacement_time) >= 0) {
            for (int i = config.ProductReplacementCount(); i > 0; i--)
              all_products.replaceRandomProduct(this);
            product_replacement_time.garbageFootprint(this);
            product_replacement_time = (
              product_replacement_time
              .addRelative(this, config.ProductReplacementPeriod()));
            product_replacement_time.changeLifeSpan(this,
                                                    LifeSpan.TransientShort);
            Trace.msg(4, "Server ", label, ": replaced products: ",
                      Integer.toString(config.ProductReplacementCount()));
            history.logProducts(this, next_release_time,
                                config.ProductReplacementCount());
          } else {
            Trace.msg(4, "Server ", label, ": too early to replace products");
            history.logDoNothings(this, next_release_time);
          }
          break;
        default:
          assert (false): " Unhandled attention point in server thread";
      }
      if (attention-- == 0)
        attention = TotalAttentionPoints - 1;

      next_release_time.garbageFootprint(this);
      next_release_time = (
        next_release_time.addRelative(this, config.ServerPeriod()));
      next_release_time.changeLifeSpan(this, LifeSpan.TransientShort);
    }
    Trace.msg(2, "Server ", label, " terminating.  Time is up.");

    // We accumulate accumulator even if reporting individual threads
    accumulator.accumulate(history);
    if (config.ReportIndividualThreads())
      this.report(this);
    else {
      alloc_accumulator.foldInto(memoryLog());
      garbage_accumulator.foldInto(garbageLog());
    }
  }