1 /* |
1 /* |
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
2958 if (res == NULL) { |
2958 if (res == NULL) { |
2959 warning("NUMA page allocation failed"); |
2959 warning("NUMA page allocation failed"); |
2960 } |
2960 } |
2961 if( Verbose && PrintMiscellaneous ) { |
2961 if( Verbose && PrintMiscellaneous ) { |
2962 reserveTimer.stop(); |
2962 reserveTimer.stop(); |
2963 tty->print_cr("reserve_memory of %Ix bytes took %ld ms (%ld ticks)", bytes, |
2963 tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes, |
2964 reserveTimer.milliseconds(), reserveTimer.ticks()); |
2964 reserveTimer.milliseconds(), reserveTimer.ticks()); |
2965 } |
2965 } |
2966 } |
2966 } |
2967 assert(res == NULL || addr == NULL || addr == res, |
2967 assert(res == NULL || addr == NULL || addr == res, |
2968 "Unexpected address from reserve."); |
2968 "Unexpected address from reserve."); |
4317 hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, |
4317 hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, |
4318 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
4318 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
4319 if (hFile == NULL) { |
4319 if (hFile == NULL) { |
4320 if (PrintMiscellaneous && Verbose) { |
4320 if (PrintMiscellaneous && Verbose) { |
4321 DWORD err = GetLastError(); |
4321 DWORD err = GetLastError(); |
4322 tty->print_cr("CreateFile() failed: GetLastError->%ld."); |
4322 tty->print_cr("CreateFile() failed: GetLastError->%ld.", err); |
4323 } |
4323 } |
4324 return NULL; |
4324 return NULL; |
4325 } |
4325 } |
4326 |
4326 |
4327 if (allow_exec) { |
4327 if (allow_exec) { |
4367 HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, |
4367 HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, |
4368 NULL /*file_name*/); |
4368 NULL /*file_name*/); |
4369 if (hMap == NULL) { |
4369 if (hMap == NULL) { |
4370 if (PrintMiscellaneous && Verbose) { |
4370 if (PrintMiscellaneous && Verbose) { |
4371 DWORD err = GetLastError(); |
4371 DWORD err = GetLastError(); |
4372 tty->print_cr("CreateFileMapping() failed: GetLastError->%ld."); |
4372 tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err); |
4373 } |
4373 } |
4374 CloseHandle(hFile); |
4374 CloseHandle(hFile); |
4375 return NULL; |
4375 return NULL; |
4376 } |
4376 } |
4377 |
4377 |
4577 Millis -= prd ; |
4577 Millis -= prd ; |
4578 } |
4578 } |
4579 } |
4579 } |
4580 v = _Event ; |
4580 v = _Event ; |
4581 _Event = 0 ; |
4581 _Event = 0 ; |
|
4582 // see comment at end of os::PlatformEvent::park() below: |
4582 OrderAccess::fence() ; |
4583 OrderAccess::fence() ; |
4583 // If we encounter a nearly simultanous timeout expiry and unpark() |
4584 // If we encounter a nearly simultanous timeout expiry and unpark() |
4584 // we return OS_OK indicating we awoke via unpark(). |
4585 // we return OS_OK indicating we awoke via unpark(). |
4585 // Implementor's license -- returning OS_TIMEOUT would be equally valid, however. |
4586 // Implementor's license -- returning OS_TIMEOUT would be equally valid, however. |
4586 return (v >= 0) ? OS_OK : OS_TIMEOUT ; |
4587 return (v >= 0) ? OS_OK : OS_TIMEOUT ; |
4614 guarantee (_Event >= 0, "invariant") ; |
4615 guarantee (_Event >= 0, "invariant") ; |
4615 } |
4616 } |
4616 |
4617 |
4617 void os::PlatformEvent::unpark() { |
4618 void os::PlatformEvent::unpark() { |
4618 guarantee (_ParkHandle != NULL, "Invariant") ; |
4619 guarantee (_ParkHandle != NULL, "Invariant") ; |
4619 int v ; |
4620 |
4620 for (;;) { |
4621 // Transitions for _Event: |
4621 v = _Event ; // Increment _Event if it's < 1. |
4622 // 0 :=> 1 |
4622 if (v > 0) { |
4623 // 1 :=> 1 |
4623 // If it's already signaled just return. |
4624 // -1 :=> either 0 or 1; must signal target thread |
4624 // The LD of _Event could have reordered or be satisfied |
4625 // That is, we can safely transition _Event from -1 to either |
4625 // by a read-aside from this processor's write buffer. |
4626 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
4626 // To avoid problems execute a barrier and then |
4627 // unpark() calls. |
4627 // ratify the value. A degenerate CAS() would also work. |
4628 // See also: "Semaphores in Plan 9" by Mullender & Cox |
4628 // Viz., CAS (v+0, &_Event, v) == v). |
4629 // |
4629 OrderAccess::fence() ; |
4630 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
4630 if (_Event == v) return ; |
4631 // that it will take two back-to-back park() calls for the owning |
4631 continue ; |
4632 // thread to block. This has the benefit of forcing a spurious return |
4632 } |
4633 // from the first park() call after an unpark() call which will help |
4633 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; |
4634 // shake out uses of park() and unpark() without condition variables. |
4634 } |
4635 |
4635 if (v < 0) { |
4636 if (Atomic::xchg(1, &_Event) >= 0) return; |
4636 ::SetEvent (_ParkHandle) ; |
4637 |
4637 } |
4638 ::SetEvent(_ParkHandle); |
4638 } |
4639 } |
4639 |
4640 |
4640 |
4641 |
4641 // JSR166 |
4642 // JSR166 |
4642 // ------------------------------------------------------- |
4643 // ------------------------------------------------------- |