1 /* 2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.nio; 27 28 import java.util.concurrent.TimeUnit; 29 import java.util.concurrent.atomic.AtomicLong; 30 import java.util.concurrent.locks.StampedLock; 31 32 import jdk.internal.misc.JavaNioAccess; 33 import jdk.internal.misc.JavaLangRefAccess; 34 import jdk.internal.misc.SharedSecrets; 35 import jdk.internal.misc.Unsafe; 36 import jdk.internal.misc.VM; 37 import jdk.internal.ref.CleanerFactory; 38 39 /** 40 * Access to bits, native and otherwise. 41 */ 42 43 class Bits { // package-private 44 45 private Bits() { } 46 47 48 // -- Swapping -- 49 50 static short swap(short x) { 51 return Short.reverseBytes(x); 52 } 53 54 static char swap(char x) { 55 return Character.reverseBytes(x); 56 } 57 58 static int swap(int x) { 59 return Integer.reverseBytes(x); 60 } 61 62 static long swap(long x) { 63 return Long.reverseBytes(x); 64 } 65 66 67 // -- get/put char -- 68 69 private static char makeChar(byte b1, byte b0) { 70 return (char)((b1 << 8) | (b0 & 0xff)); 71 } 72 73 static char getCharL(ByteBuffer bb, int bi) { 74 return makeChar(bb._get(bi + 1), 75 bb._get(bi )); 76 } 77 78 static char getCharL(long a) { 79 return makeChar(_get(a + 1), 80 _get(a )); 81 } 82 83 static char getCharB(ByteBuffer bb, int bi) { 84 return makeChar(bb._get(bi ), 85 bb._get(bi + 1)); 86 } 87 88 static char getCharB(long a) { 89 return makeChar(_get(a ), 90 _get(a + 1)); 91 } 92 93 static char getChar(ByteBuffer bb, int bi, boolean bigEndian) { 94 return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi); 95 } 96 97 static char getChar(long a, boolean bigEndian) { 98 return bigEndian ? getCharB(a) : getCharL(a); 99 } 100 101 private static byte char1(char x) { return (byte)(x >> 8); } 102 private static byte char0(char x) { return (byte)(x ); } 103 104 static void putCharL(ByteBuffer bb, int bi, char x) { 105 bb._put(bi , char0(x)); 106 bb._put(bi + 1, char1(x)); 107 } 108 109 static void putCharL(long a, char x) { 110 _put(a , char0(x)); 111 _put(a + 1, char1(x)); 112 } 113 114 static void putCharB(ByteBuffer bb, int bi, char x) { 115 bb._put(bi , char1(x)); 116 bb._put(bi + 1, char0(x)); 117 } 118 119 static void putCharB(long a, char x) { 120 _put(a , char1(x)); 121 _put(a + 1, char0(x)); 122 } 123 124 static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) { 125 if (bigEndian) 126 putCharB(bb, bi, x); 127 else 128 putCharL(bb, bi, x); 129 } 130 131 static void putChar(long a, char x, boolean bigEndian) { 132 if (bigEndian) 133 putCharB(a, x); 134 else 135 putCharL(a, x); 136 } 137 138 139 // -- get/put short -- 140 141 private static short makeShort(byte b1, byte b0) { 142 return (short)((b1 << 8) | (b0 & 0xff)); 143 } 144 145 static short getShortL(ByteBuffer bb, int bi) { 146 return makeShort(bb._get(bi + 1), 147 bb._get(bi )); 148 } 149 150 static short getShortL(long a) { 151 return makeShort(_get(a + 1), 152 _get(a )); 153 } 154 155 static short getShortB(ByteBuffer bb, int bi) { 156 return makeShort(bb._get(bi ), 157 bb._get(bi + 1)); 158 } 159 160 static short getShortB(long a) { 161 return makeShort(_get(a ), 162 _get(a + 1)); 163 } 164 165 static short getShort(ByteBuffer bb, int bi, boolean bigEndian) { 166 return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi); 167 } 168 169 static short getShort(long a, boolean bigEndian) { 170 return bigEndian ? getShortB(a) : getShortL(a); 171 } 172 173 private static byte short1(short x) { return (byte)(x >> 8); } 174 private static byte short0(short x) { return (byte)(x ); } 175 176 static void putShortL(ByteBuffer bb, int bi, short x) { 177 bb._put(bi , short0(x)); 178 bb._put(bi + 1, short1(x)); 179 } 180 181 static void putShortL(long a, short x) { 182 _put(a , short0(x)); 183 _put(a + 1, short1(x)); 184 } 185 186 static void putShortB(ByteBuffer bb, int bi, short x) { 187 bb._put(bi , short1(x)); 188 bb._put(bi + 1, short0(x)); 189 } 190 191 static void putShortB(long a, short x) { 192 _put(a , short1(x)); 193 _put(a + 1, short0(x)); 194 } 195 196 static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) { 197 if (bigEndian) 198 putShortB(bb, bi, x); 199 else 200 putShortL(bb, bi, x); 201 } 202 203 static void putShort(long a, short x, boolean bigEndian) { 204 if (bigEndian) 205 putShortB(a, x); 206 else 207 putShortL(a, x); 208 } 209 210 211 // -- get/put int -- 212 213 private static int makeInt(byte b3, byte b2, byte b1, byte b0) { 214 return (((b3 ) << 24) | 215 ((b2 & 0xff) << 16) | 216 ((b1 & 0xff) << 8) | 217 ((b0 & 0xff) )); 218 } 219 220 static int getIntL(ByteBuffer bb, int bi) { 221 return makeInt(bb._get(bi + 3), 222 bb._get(bi + 2), 223 bb._get(bi + 1), 224 bb._get(bi )); 225 } 226 227 static int getIntL(long a) { 228 return makeInt(_get(a + 3), 229 _get(a + 2), 230 _get(a + 1), 231 _get(a )); 232 } 233 234 static int getIntB(ByteBuffer bb, int bi) { 235 return makeInt(bb._get(bi ), 236 bb._get(bi + 1), 237 bb._get(bi + 2), 238 bb._get(bi + 3)); 239 } 240 241 static int getIntB(long a) { 242 return makeInt(_get(a ), 243 _get(a + 1), 244 _get(a + 2), 245 _get(a + 3)); 246 } 247 248 static int getInt(ByteBuffer bb, int bi, boolean bigEndian) { 249 return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ; 250 } 251 252 static int getInt(long a, boolean bigEndian) { 253 return bigEndian ? getIntB(a) : getIntL(a) ; 254 } 255 256 private static byte int3(int x) { return (byte)(x >> 24); } 257 private static byte int2(int x) { return (byte)(x >> 16); } 258 private static byte int1(int x) { return (byte)(x >> 8); } 259 private static byte int0(int x) { return (byte)(x ); } 260 261 static void putIntL(ByteBuffer bb, int bi, int x) { 262 bb._put(bi + 3, int3(x)); 263 bb._put(bi + 2, int2(x)); 264 bb._put(bi + 1, int1(x)); 265 bb._put(bi , int0(x)); 266 } 267 268 static void putIntL(long a, int x) { 269 _put(a + 3, int3(x)); 270 _put(a + 2, int2(x)); 271 _put(a + 1, int1(x)); 272 _put(a , int0(x)); 273 } 274 275 static void putIntB(ByteBuffer bb, int bi, int x) { 276 bb._put(bi , int3(x)); 277 bb._put(bi + 1, int2(x)); 278 bb._put(bi + 2, int1(x)); 279 bb._put(bi + 3, int0(x)); 280 } 281 282 static void putIntB(long a, int x) { 283 _put(a , int3(x)); 284 _put(a + 1, int2(x)); 285 _put(a + 2, int1(x)); 286 _put(a + 3, int0(x)); 287 } 288 289 static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) { 290 if (bigEndian) 291 putIntB(bb, bi, x); 292 else 293 putIntL(bb, bi, x); 294 } 295 296 static void putInt(long a, int x, boolean bigEndian) { 297 if (bigEndian) 298 putIntB(a, x); 299 else 300 putIntL(a, x); 301 } 302 303 304 // -- get/put long -- 305 306 private static long makeLong(byte b7, byte b6, byte b5, byte b4, 307 byte b3, byte b2, byte b1, byte b0) 308 { 309 return ((((long)b7 ) << 56) | 310 (((long)b6 & 0xff) << 48) | 311 (((long)b5 & 0xff) << 40) | 312 (((long)b4 & 0xff) << 32) | 313 (((long)b3 & 0xff) << 24) | 314 (((long)b2 & 0xff) << 16) | 315 (((long)b1 & 0xff) << 8) | 316 (((long)b0 & 0xff) )); 317 } 318 319 static long getLongL(ByteBuffer bb, int bi) { 320 return makeLong(bb._get(bi + 7), 321 bb._get(bi + 6), 322 bb._get(bi + 5), 323 bb._get(bi + 4), 324 bb._get(bi + 3), 325 bb._get(bi + 2), 326 bb._get(bi + 1), 327 bb._get(bi )); 328 } 329 330 static long getLongL(long a) { 331 return makeLong(_get(a + 7), 332 _get(a + 6), 333 _get(a + 5), 334 _get(a + 4), 335 _get(a + 3), 336 _get(a + 2), 337 _get(a + 1), 338 _get(a )); 339 } 340 341 static long getLongB(ByteBuffer bb, int bi) { 342 return makeLong(bb._get(bi ), 343 bb._get(bi + 1), 344 bb._get(bi + 2), 345 bb._get(bi + 3), 346 bb._get(bi + 4), 347 bb._get(bi + 5), 348 bb._get(bi + 6), 349 bb._get(bi + 7)); 350 } 351 352 static long getLongB(long a) { 353 return makeLong(_get(a ), 354 _get(a + 1), 355 _get(a + 2), 356 _get(a + 3), 357 _get(a + 4), 358 _get(a + 5), 359 _get(a + 6), 360 _get(a + 7)); 361 } 362 363 static long getLong(ByteBuffer bb, int bi, boolean bigEndian) { 364 return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi); 365 } 366 367 static long getLong(long a, boolean bigEndian) { 368 return bigEndian ? getLongB(a) : getLongL(a); 369 } 370 371 private static byte long7(long x) { return (byte)(x >> 56); } 372 private static byte long6(long x) { return (byte)(x >> 48); } 373 private static byte long5(long x) { return (byte)(x >> 40); } 374 private static byte long4(long x) { return (byte)(x >> 32); } 375 private static byte long3(long x) { return (byte)(x >> 24); } 376 private static byte long2(long x) { return (byte)(x >> 16); } 377 private static byte long1(long x) { return (byte)(x >> 8); } 378 private static byte long0(long x) { return (byte)(x ); } 379 380 static void putLongL(ByteBuffer bb, int bi, long x) { 381 bb._put(bi + 7, long7(x)); 382 bb._put(bi + 6, long6(x)); 383 bb._put(bi + 5, long5(x)); 384 bb._put(bi + 4, long4(x)); 385 bb._put(bi + 3, long3(x)); 386 bb._put(bi + 2, long2(x)); 387 bb._put(bi + 1, long1(x)); 388 bb._put(bi , long0(x)); 389 } 390 391 static void putLongL(long a, long x) { 392 _put(a + 7, long7(x)); 393 _put(a + 6, long6(x)); 394 _put(a + 5, long5(x)); 395 _put(a + 4, long4(x)); 396 _put(a + 3, long3(x)); 397 _put(a + 2, long2(x)); 398 _put(a + 1, long1(x)); 399 _put(a , long0(x)); 400 } 401 402 static void putLongB(ByteBuffer bb, int bi, long x) { 403 bb._put(bi , long7(x)); 404 bb._put(bi + 1, long6(x)); 405 bb._put(bi + 2, long5(x)); 406 bb._put(bi + 3, long4(x)); 407 bb._put(bi + 4, long3(x)); 408 bb._put(bi + 5, long2(x)); 409 bb._put(bi + 6, long1(x)); 410 bb._put(bi + 7, long0(x)); 411 } 412 413 static void putLongB(long a, long x) { 414 _put(a , long7(x)); 415 _put(a + 1, long6(x)); 416 _put(a + 2, long5(x)); 417 _put(a + 3, long4(x)); 418 _put(a + 4, long3(x)); 419 _put(a + 5, long2(x)); 420 _put(a + 6, long1(x)); 421 _put(a + 7, long0(x)); 422 } 423 424 static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) { 425 if (bigEndian) 426 putLongB(bb, bi, x); 427 else 428 putLongL(bb, bi, x); 429 } 430 431 static void putLong(long a, long x, boolean bigEndian) { 432 if (bigEndian) 433 putLongB(a, x); 434 else 435 putLongL(a, x); 436 } 437 438 439 // -- get/put float -- 440 441 static float getFloatL(ByteBuffer bb, int bi) { 442 return Float.intBitsToFloat(getIntL(bb, bi)); 443 } 444 445 static float getFloatL(long a) { 446 return Float.intBitsToFloat(getIntL(a)); 447 } 448 449 static float getFloatB(ByteBuffer bb, int bi) { 450 return Float.intBitsToFloat(getIntB(bb, bi)); 451 } 452 453 static float getFloatB(long a) { 454 return Float.intBitsToFloat(getIntB(a)); 455 } 456 457 static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) { 458 return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi); 459 } 460 461 static float getFloat(long a, boolean bigEndian) { 462 return bigEndian ? getFloatB(a) : getFloatL(a); 463 } 464 465 static void putFloatL(ByteBuffer bb, int bi, float x) { 466 putIntL(bb, bi, Float.floatToRawIntBits(x)); 467 } 468 469 static void putFloatL(long a, float x) { 470 putIntL(a, Float.floatToRawIntBits(x)); 471 } 472 473 static void putFloatB(ByteBuffer bb, int bi, float x) { 474 putIntB(bb, bi, Float.floatToRawIntBits(x)); 475 } 476 477 static void putFloatB(long a, float x) { 478 putIntB(a, Float.floatToRawIntBits(x)); 479 } 480 481 static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) { 482 if (bigEndian) 483 putFloatB(bb, bi, x); 484 else 485 putFloatL(bb, bi, x); 486 } 487 488 static void putFloat(long a, float x, boolean bigEndian) { 489 if (bigEndian) 490 putFloatB(a, x); 491 else 492 putFloatL(a, x); 493 } 494 495 496 // -- get/put double -- 497 498 static double getDoubleL(ByteBuffer bb, int bi) { 499 return Double.longBitsToDouble(getLongL(bb, bi)); 500 } 501 502 static double getDoubleL(long a) { 503 return Double.longBitsToDouble(getLongL(a)); 504 } 505 506 static double getDoubleB(ByteBuffer bb, int bi) { 507 return Double.longBitsToDouble(getLongB(bb, bi)); 508 } 509 510 static double getDoubleB(long a) { 511 return Double.longBitsToDouble(getLongB(a)); 512 } 513 514 static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) { 515 return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi); 516 } 517 518 static double getDouble(long a, boolean bigEndian) { 519 return bigEndian ? getDoubleB(a) : getDoubleL(a); 520 } 521 522 static void putDoubleL(ByteBuffer bb, int bi, double x) { 523 putLongL(bb, bi, Double.doubleToRawLongBits(x)); 524 } 525 526 static void putDoubleL(long a, double x) { 527 putLongL(a, Double.doubleToRawLongBits(x)); 528 } 529 530 static void putDoubleB(ByteBuffer bb, int bi, double x) { 531 putLongB(bb, bi, Double.doubleToRawLongBits(x)); 532 } 533 534 static void putDoubleB(long a, double x) { 535 putLongB(a, Double.doubleToRawLongBits(x)); 536 } 537 538 static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) { 539 if (bigEndian) 540 putDoubleB(bb, bi, x); 541 else 542 putDoubleL(bb, bi, x); 543 } 544 545 static void putDouble(long a, double x, boolean bigEndian) { 546 if (bigEndian) 547 putDoubleB(a, x); 548 else 549 putDoubleL(a, x); 550 } 551 552 553 // -- Unsafe access -- 554 555 private static final Unsafe unsafe = Unsafe.getUnsafe(); 556 557 private static byte _get(long a) { 558 return unsafe.getByte(a); 559 } 560 561 private static void _put(long a, byte b) { 562 unsafe.putByte(a, b); 563 } 564 565 static Unsafe unsafe() { 566 return unsafe; 567 } 568 569 570 // -- Processor and memory-system properties -- 571 572 private static final ByteOrder byteOrder 573 = unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; 574 575 static ByteOrder byteOrder() { 576 return byteOrder; 577 } 578 579 private static int pageSize = -1; 580 581 static int pageSize() { 582 if (pageSize == -1) 583 pageSize = unsafe().pageSize(); 584 return pageSize; 585 } 586 587 static int pageCount(long size) { 588 return (int)(size + (long)pageSize() - 1L) / pageSize(); 589 } 590 591 private static boolean unaligned = unsafe.unalignedAccess(); 592 593 static boolean unaligned() { 594 return unaligned; 595 } 596 597 598 // -- Direct memory management -- 599 600 // A user-settable upper limit on the maximum amount of allocatable 601 // direct buffer memory. This value may be changed during VM 602 // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". 603 // A change to maxMemory is published via memoryLimitSet volatile boolean 604 // flag changing state from false -> true, so maxMemory need not be volatile. 605 private static long maxMemory = VM.maxDirectMemory(); 606 private static volatile boolean memoryLimitSet; 607 608 private static final AtomicLong reservedMemory = new AtomicLong(); 609 private static final AtomicLong totalCapacity = new AtomicLong(); 610 private static final AtomicLong count = new AtomicLong(); 611 612 // A fair lock for direct memory allocator threads to queue after 1st optimistic 613 // reservation fails so that only a single thread at a time is retrying 614 // reservation while: 615 // - waiting for unreservation events until time out 616 // - followed by triggering reference discovery 617 // - followed by another round of waiting for unreservation events until time out 618 // ... before finally giving up with OutOfMemoryError. 619 private static final StampedLock reserveLock = new StampedLock(); 620 621 // A counter of unreservations incremented by unreservation threads, 622 // guarded by unreserveLock, but also read by reservation threads without 623 // holding unreserveLock, so it must be volatile. 624 private static volatile int unreserveCount; 625 626 // Last value of 'unreserveCount' observed by reservation threads, 627 // guarded by reserveLock. If 'lastUnreserveCount' and 'unreserveCount' 628 // differ, an unreservation event (or multiple events) is detected. 629 private static int lastUnreserveCount; 630 631 // the System.nanoTime() of the detection of last unreservation event 632 // by the reservation thread(s), guarded by reserveLock. 633 private static long lastUnreserveNanoTime; 634 635 // flag indicating if 'lastUnreserveNanoTime' has already been set, 636 // guarded by reserveLock. 637 private static boolean lastUnreserveNanoTimeSet; 638 639 // max. wait time for unreservation event before triggering GC and/or 640 // failing with OOME. 641 private static final long MAX_UNRESERVE_WAIT_NANOS = 642 TimeUnit.SECONDS.toNanos(1L); 643 644 // the duration of last successful waiting for unreservation 645 // event by reservation thread. starts with MAX_UNRESERVE_WAIT_NANOS / 4 646 // and is dynamically adjusted at each successful call to awaitUnreserveMemory() 647 // that actually waited for the event. 648 private static long lastSuccessfullUnreserveWaitNanos = 649 MAX_UNRESERVE_WAIT_NANOS / 4; 650 651 // monitor lock via which unreservation threads notify reservation threads 652 // about the unreservation events. 653 private static final Object unreserveLock = new Object(); 654 655 // These methods should be called whenever direct memory is allocated or 656 // freed. They allow the user to control the amount of direct memory 657 // which a process may access. All sizes are specified in bytes. 658 static void reserveMemory(long size, int cap) { 659 660 if (!memoryLimitSet && VM.initLevel() >= 1) { 661 maxMemory = VM.maxDirectMemory(); 662 memoryLimitSet = true; 663 } 664 665 JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess(); 666 667 // optimist! 668 long stamp = reserveLock.tryReadLock(); 669 if (stamp != 0L) try { 670 // retry reservation while helping the Cleaner thread process enqueued 671 // Cleanable(s) which includes the ones that free direct buffer memory 672 // until the queue drains out 673 do { 674 if (tryReserveMemory(size, cap)) { 675 return; 676 } 677 } while (jlra.cleanNextEnqueuedCleanable(CleanerFactory.cleaner())); 678 } finally { 679 reserveLock.unlockRead(stamp); 680 } 681 682 // reservation threads that don't succeed at first must queue so that 683 // only one of them at a time is triggering reference discovery and 684 // retrials with waiting on un-reservation events... 685 stamp = reserveLock.writeLock(); 686 try { 687 // retry reservation until there are no unreservation events 688 // detected for at least 4 times as much as we waited for last 689 // successful unreservation event but no more than 690 // MAX_UNRESERVE_WAIT_NANOS. 691 do { 692 if (tryReserveMemory(size, cap)) { 693 return; 694 } 695 } while (awaitUnreserveMemory(Math.min(MAX_UNRESERVE_WAIT_NANOS, 696 lastSuccessfullUnreserveWaitNanos * 4))); 697 698 // trigger reference discovery 699 System.gc(); 700 // GC stops the world and can last for a long time, 701 // so restart timing from 0. 702 lastUnreserveNanoTime = System.nanoTime(); 703 704 // retry reservation until there are no unreservation events 705 // detected for at least MAX_UNRESERVE_WAIT_NANOS. 706 do { 707 if (tryReserveMemory(size, cap)) { 708 return; 709 } 710 } while (awaitUnreserveMemory(MAX_UNRESERVE_WAIT_NANOS)); 711 712 // no luck 713 throw new OutOfMemoryError("Direct buffer memory"); 714 } finally { 715 reserveLock.unlockWrite(stamp); 716 } 717 } 718 719 private static boolean tryReserveMemory(long size, int cap) { 720 721 // -XX:MaxDirectMemorySize limits the total capacity rather than the 722 // actual memory usage, which will differ when buffers are page 723 // aligned. 724 long totalCap; 725 while (cap <= maxMemory - (totalCap = totalCapacity.get())) { 726 if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) { 727 reservedMemory.addAndGet(size); 728 count.incrementAndGet(); 729 return true; 730 } 731 } 732 733 return false; 734 } 735 736 private static boolean awaitUnreserveMemory(long timeoutNanos) { 737 assert reserveLock.isWriteLocked(); 738 739 // optimistic 1st try without lock 740 int c; 741 if ((c = unreserveCount) != lastUnreserveCount) { 742 lastUnreserveCount = c; 743 lastUnreserveNanoTime = System.nanoTime(); 744 lastUnreserveNanoTimeSet = true; 745 return true; 746 } 747 boolean interrupted = false; 748 try { 749 synchronized (unreserveLock) { 750 long nt = System.nanoTime(); 751 if (!lastUnreserveNanoTimeSet) { 752 lastUnreserveNanoTime = nt; 753 lastUnreserveNanoTimeSet = true; 754 } 755 long deadline = lastUnreserveNanoTime + timeoutNanos; 756 long waitUnreserve; 757 while ((c = unreserveCount) == lastUnreserveCount && 758 (waitUnreserve = deadline - nt) > 0L) { 759 interrupted |= waitNanos(unreserveLock, waitUnreserve); 760 nt = System.nanoTime(); 761 } 762 if (c == lastUnreserveCount) { 763 // time out 764 return false; 765 } else { 766 lastSuccessfullUnreserveWaitNanos = nt - lastUnreserveNanoTime; 767 lastUnreserveCount = c; 768 lastUnreserveNanoTime = nt; 769 return true; 770 } 771 } 772 } finally { 773 if (interrupted) { 774 Thread.currentThread().interrupt(); 775 } 776 } 777 } 778 779 private static boolean waitNanos(Object lock, long waitNanos) { 780 try { 781 long millis = TimeUnit.NANOSECONDS.toMillis(waitNanos); 782 int nanos = (int) (waitNanos - TimeUnit.MILLISECONDS.toNanos(millis)); 783 lock.wait(millis, nanos); 784 return false; 785 } catch (InterruptedException e) { 786 return true; 787 } 788 } 789 790 static void unreserveMemory(long size, int cap) { 791 synchronized (unreserveLock) { 792 long cnt = count.decrementAndGet(); 793 long reservedMem = reservedMemory.addAndGet(-size); 794 long totalCap = totalCapacity.addAndGet(-cap); 795 assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0; 796 unreserveCount++; 797 unreserveLock.notifyAll(); 798 } 799 } 800 801 // -- Monitoring of direct buffer usage -- 802 803 static { 804 // setup access to this package in SharedSecrets 805 SharedSecrets.setJavaNioAccess( 806 new JavaNioAccess() { 807 @Override 808 public JavaNioAccess.BufferPool getDirectBufferPool() { 809 return new JavaNioAccess.BufferPool() { 810 @Override 811 public String getName() { 812 return "direct"; 813 } 814 @Override 815 public long getCount() { 816 return Bits.count.get(); 817 } 818 @Override 819 public long getTotalCapacity() { 820 return Bits.totalCapacity.get(); 821 } 822 @Override 823 public long getMemoryUsed() { 824 return Bits.reservedMemory.get(); 825 } 826 }; 827 } 828 @Override 829 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) { 830 return new DirectByteBuffer(addr, cap, ob); 831 } 832 @Override 833 public void truncate(Buffer buf) { 834 buf.truncate(); 835 } 836 }); 837 } 838 839 // These numbers represent the point at which we have empirically 840 // determined that the average cost of a JNI call exceeds the expense 841 // of an element by element copy. These numbers may change over time. 842 static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; 843 static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; 844 }