comparison src/gpu/ptx/vm/gpu_ptx.cpp @ 13832:ab370d74a8eb

implemented GC locking for duration of a PTX kernel call
author Doug Simon <doug.simon@oracle.com>
date Thu, 30 Jan 2014 23:52:34 +0100
parents 49db2c1e3bee
children fe99bfb55626
comparison
equal deleted inserted replaced
13831:d6823d127f76 13832:ab370d74a8eb
27 #include "runtime/gpu.hpp" 27 #include "runtime/gpu.hpp"
28 #include "utilities/globalDefinitions.hpp" 28 #include "utilities/globalDefinitions.hpp"
29 #include "utilities/ostream.hpp" 29 #include "utilities/ostream.hpp"
30 #include "memory/allocation.hpp" 30 #include "memory/allocation.hpp"
31 #include "memory/allocation.inline.hpp" 31 #include "memory/allocation.inline.hpp"
32 #include "memory/gcLocker.inline.hpp"
32 #include "runtime/interfaceSupport.hpp" 33 #include "runtime/interfaceSupport.hpp"
33 #include "graal/graalEnv.hpp" 34 #include "graal/graalEnv.hpp"
34 #include "graal/graalCompiler.hpp" 35 #include "graal/graalCompiler.hpp"
35 #include "ptxKernelArguments.hpp" 36 #include "ptxKernelArguments.hpp"
36 37
402 oop* _pinned; // objects that have been pinned with cuMemHostRegister 403 oop* _pinned; // objects that have been pinned with cuMemHostRegister
403 int _pinned_length; // length of _pinned 404 int _pinned_length; // length of _pinned
404 gpu::Ptx::CUdeviceptr _ret_value; // pointer to slot in GPU memory holding the return value 405 gpu::Ptx::CUdeviceptr _ret_value; // pointer to slot in GPU memory holding the return value
405 int _ret_type_size; // size of the return type value 406 int _ret_type_size; // size of the return type value
406 bool _ret_is_object; // specifies if the return type is Object 407 bool _ret_is_object; // specifies if the return type is Object
408 bool _gc_locked;
407 409
408 bool check(int status, const char *action) { 410 bool check(int status, const char *action) {
409 if (status != GRAAL_CUDA_SUCCESS) { 411 if (status != GRAAL_CUDA_SUCCESS) {
410 Thread* THREAD = _thread; 412 Thread* THREAD = _thread;
411 char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, O_BUFLEN + 1); 413 char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, O_BUFLEN + 1);
423 } 425 }
424 return true; 426 return true;
425 } 427 }
426 428
427 public: 429 public:
428 PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread), 430 PtxCall(JavaThread* thread, address buffer, int buffer_size, oop* pinned, int encodedReturnTypeSize) : _thread(thread), _gc_locked(false),
429 _buffer(buffer), _buffer_size(buffer_size), _pinned(pinned), _pinned_length(0), _ret_value(0), _ret_is_object(encodedReturnTypeSize < 0) { 431 _buffer(buffer), _buffer_size(buffer_size), _pinned(pinned), _pinned_length(0), _ret_value(0), _ret_is_object(encodedReturnTypeSize < 0) {
430 _ret_type_size = _ret_is_object ? -encodedReturnTypeSize : encodedReturnTypeSize; 432 _ret_type_size = _ret_is_object ? -encodedReturnTypeSize : encodedReturnTypeSize;
431 } 433 }
432 434
433 bool is_object_return() { return _ret_is_object; } 435 bool is_object_return() { return _ret_is_object; }
443 445
444 void pin_objects(int count, int* objectOffsets) { 446 void pin_objects(int count, int* objectOffsets) {
445 if (count == 0) { 447 if (count == 0) {
446 return; 448 return;
447 } 449 }
450 // Once we start pinning objects, no GC must occur
451 // until the kernel has completed. This is a big
452 // hammer for ensuring we can safely pass objects
453 // to the GPU.
454 GC_locker::lock_critical(_thread);
455 _gc_locked = true;
456 if (TraceGPUInteraction) {
457 tty->print_cr("[CUDA] Locked GC");
458 }
459
448 for (int i = 0; i < count; i++) { 460 for (int i = 0; i < count; i++) {
449 int offset = objectOffsets[i]; 461 int offset = objectOffsets[i];
450 oop* argPtr = (oop*) (_buffer + offset); 462 oop* argPtr = (oop*) (_buffer + offset);
451 oop obj = *argPtr; 463 oop obj = *argPtr;
452 if (obj != NULL) { 464 if (obj != NULL) {
529 541
530 ~PtxCall() { 542 ~PtxCall() {
531 unpin_objects(); 543 unpin_objects();
532 free_return_value(); 544 free_return_value();
533 destroy_context(); 545 destroy_context();
546 if (_gc_locked) {
547 GC_locker::unlock_critical(_thread);
548 if (TraceGPUInteraction) {
549 tty->print_cr("[CUDA] Unlocked GC");
550 }
551 }
534 } 552 }
535 }; 553 };
536 554
537 GPU_VMENTRY(jlong, gpu::Ptx::get_execute_kernel_from_vm_address, (JNIEnv *env, jclass)) 555 GPU_VMENTRY(jlong, gpu::Ptx::get_execute_kernel_from_vm_address, (JNIEnv *env, jclass))
538 return (jlong) gpu::Ptx::execute_kernel_from_vm; 556 return (jlong) gpu::Ptx::execute_kernel_from_vm;
547 int encodedReturnTypeSize)) 565 int encodedReturnTypeSize))
548 if (kernel == 0L) { 566 if (kernel == 0L) {
549 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL); 567 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL);
550 return 0L; 568 return 0L;
551 } 569 }
552
553 #if 0
554 Universe::heap()->collect(GCCause::_jvmti_force_gc);
555 #endif
556 570
557 PtxCall call(thread, (address) buffer, bufferSize, (oop*) (address) pinnedObjects, encodedReturnTypeSize); 571 PtxCall call(thread, (address) buffer, bufferSize, (oop*) (address) pinnedObjects, encodedReturnTypeSize);
558 572
559 #define TRY(action) do { \ 573 #define TRY(action) do { \
560 action; \ 574 action; \