public void reserveInsist(MemoryConsumer consumer, int requestMB) { if (requestMB > totalBudgetMB) throw new NotEnoughBudgetException(); long waitStart = 0; while (true) { try { reserve(consumer, requestMB); if (debug && waitStart > 0) logger.debug(consumer + " waited " + (System.currentTimeMillis() - waitStart) + " ms on the " + requestMB + " MB request"); return; } catch (NotEnoughBudgetException ex) { // retry } if (waitStart == 0) waitStart = System.currentTimeMillis(); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new NotEnoughBudgetException(e); } } } }
private void tryFreeUp(int gap) { // note don't hold lock when calling consumer.freeUp(), that method holding lock for itself and may cause deadlock for (ConsumerEntry entry : booking.values()) { int mb = entry.consumer.freeUp(gap); if (mb > 0) { lock.lock(); try { updateBookingWithDelta(entry.consumer, -mb); } finally { lock.unlock(); } gap -= mb; if (gap <= 0) break; } } if (gap > 0) throw new NotEnoughBudgetException(); if (debug) { if (getSystemAvailMB() < getRemainingBudgetMB()) { logger.debug("Remaining budget is " + getRemainingBudgetMB() + " MB free, but system only has " + getSystemAvailMB() + " MB free. If this persists, some memory calculation must be wrong."); } } }
public void reserveInsist(MemoryConsumer consumer, int requestMB) { if (requestMB > totalBudgetMB) throw new NotEnoughBudgetException(); long waitStart = 0; while (true) { try { reserve(consumer, requestMB); if (debug && waitStart > 0) logger.debug(consumer + " waited " + (System.currentTimeMillis() - waitStart) + " ms on the " + requestMB + " MB request"); return; } catch (NotEnoughBudgetException ex) { // retry } if (waitStart == 0) waitStart = System.currentTimeMillis(); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new NotEnoughBudgetException(e); } } } }
private void tryFreeUp(int gap) { // note don't hold lock when calling consumer.freeUp(), that method holding lock for itself and may cause deadlock for (ConsumerEntry entry : booking.values()) { int mb = entry.consumer.freeUp(gap); if (mb > 0) { lock.lock(); try { updateBookingWithDelta(entry.consumer, -mb); } finally { lock.unlock(); } gap -= mb; if (gap <= 0) break; } } if (gap > 0) throw new NotEnoughBudgetException(); if (debug) { if (getSystemAvailMB() < getRemainingBudgetMB()) { logger.debug("Remaining budget is " + getRemainingBudgetMB() + " MB free, but system only has " + getSystemAvailMB() + " MB free. If this persists, some memory calculation must be wrong."); } } }
/** reserve without wait, fail with NotEnoughBudgetException immediately if no mem */ public void reserve(MemoryConsumer consumer, int requestMB) { if (totalBudgetMB == 0 && requestMB > 0) throw new NotEnoughBudgetException(); boolean ok = false; while (!ok) { int gap = calculateGap(consumer, requestMB); if (gap > 0) { // to void deadlock, don't hold lock when invoking consumer.freeUp() tryFreeUp(gap); } ok = updateBooking(consumer, requestMB); } }
/** reserve without wait, fail with NotEnoughBudgetException immediately if no mem */ public void reserve(MemoryConsumer consumer, int requestMB) { if (totalBudgetMB == 0 && requestMB > 0) throw new NotEnoughBudgetException(); boolean ok = false; while (!ok) { int gap = calculateGap(consumer, requestMB); if (gap > 0) { // to void deadlock, don't hold lock when invoking consumer.freeUp() tryFreeUp(gap); } ok = updateBooking(consumer, requestMB); } }