hotspot/src/share/vm/prims/jvmtiImpl.cpp
changeset 46438 b093c3f1ab3d
parent 46329 53ccc37bda19
child 46630 75aa3e39d02c
equal deleted inserted replaced
46436:755e01cd0b9d 46438:b093c3f1ab3d
   972 }
   972 }
   973 
   973 
   974 JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL;
   974 JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL;
   975 JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL;
   975 JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL;
   976 
   976 
   977 volatile JvmtiDeferredEventQueue::QueueNode*
       
   978     JvmtiDeferredEventQueue::_pending_list = NULL;
       
   979 
       
   980 bool JvmtiDeferredEventQueue::has_events() {
   977 bool JvmtiDeferredEventQueue::has_events() {
   981   assert(Service_lock->owned_by_self(), "Must own Service_lock");
   978   assert(Service_lock->owned_by_self(), "Must own Service_lock");
   982   return _queue_head != NULL || _pending_list != NULL;
   979   return _queue_head != NULL;
   983 }
   980 }
   984 
   981 
   985 void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) {
   982 void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) {
   986   assert(Service_lock->owned_by_self(), "Must own Service_lock");
   983   assert(Service_lock->owned_by_self(), "Must own Service_lock");
   987 
       
   988   process_pending_events();
       
   989 
   984 
   990   // Events get added to the end of the queue (and are pulled off the front).
   985   // Events get added to the end of the queue (and are pulled off the front).
   991   QueueNode* node = new QueueNode(event);
   986   QueueNode* node = new QueueNode(event);
   992   if (_queue_tail == NULL) {
   987   if (_queue_tail == NULL) {
   993     _queue_tail = _queue_head = node;
   988     _queue_tail = _queue_head = node;
  1003 }
   998 }
  1004 
   999 
  1005 JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() {
  1000 JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() {
  1006   assert(Service_lock->owned_by_self(), "Must own Service_lock");
  1001   assert(Service_lock->owned_by_self(), "Must own Service_lock");
  1007 
  1002 
  1008   process_pending_events();
       
  1009 
       
  1010   assert(_queue_head != NULL, "Nothing to dequeue");
  1003   assert(_queue_head != NULL, "Nothing to dequeue");
  1011 
  1004 
  1012   if (_queue_head == NULL) {
  1005   if (_queue_head == NULL) {
  1013     // Just in case this happens in product; it shouldn't but let's not crash
  1006     // Just in case this happens in product; it shouldn't but let's not crash
  1014     return JvmtiDeferredEvent();
  1007     return JvmtiDeferredEvent();
  1025 
  1018 
  1026   JvmtiDeferredEvent event = node->event();
  1019   JvmtiDeferredEvent event = node->event();
  1027   delete node;
  1020   delete node;
  1028   return event;
  1021   return event;
  1029 }
  1022 }
  1030 
       
  1031 void JvmtiDeferredEventQueue::add_pending_event(
       
  1032     const JvmtiDeferredEvent& event) {
       
  1033 
       
  1034   QueueNode* node = new QueueNode(event);
       
  1035 
       
  1036   bool success = false;
       
  1037   QueueNode* prev_value = (QueueNode*)_pending_list;
       
  1038   do {
       
  1039     node->set_next(prev_value);
       
  1040     prev_value = (QueueNode*)Atomic::cmpxchg_ptr(
       
  1041         (void*)node, (volatile void*)&_pending_list, (void*)node->next());
       
  1042   } while (prev_value != node->next());
       
  1043 }
       
  1044 
       
  1045 // This method transfers any events that were added by someone NOT holding
       
  1046 // the lock into the mainline queue.
       
  1047 void JvmtiDeferredEventQueue::process_pending_events() {
       
  1048   assert(Service_lock->owned_by_self(), "Must own Service_lock");
       
  1049 
       
  1050   if (_pending_list != NULL) {
       
  1051     QueueNode* head =
       
  1052         (QueueNode*)Atomic::xchg_ptr(NULL, (volatile void*)&_pending_list);
       
  1053 
       
  1054     assert((_queue_head == NULL) == (_queue_tail == NULL),
       
  1055            "Inconsistent queue markers");
       
  1056 
       
  1057     if (head != NULL) {
       
  1058       // Since we've treated the pending list as a stack (with newer
       
  1059       // events at the beginning), we need to join the bottom of the stack
       
  1060       // with the 'tail' of the queue in order to get the events in the
       
  1061       // right order.  We do this by reversing the pending list and appending
       
  1062       // it to the queue.
       
  1063 
       
  1064       QueueNode* new_tail = head;
       
  1065       QueueNode* new_head = NULL;
       
  1066 
       
  1067       // This reverses the list
       
  1068       QueueNode* prev = new_tail;
       
  1069       QueueNode* node = new_tail->next();
       
  1070       new_tail->set_next(NULL);
       
  1071       while (node != NULL) {
       
  1072         QueueNode* next = node->next();
       
  1073         node->set_next(prev);
       
  1074         prev = node;
       
  1075         node = next;
       
  1076       }
       
  1077       new_head = prev;
       
  1078 
       
  1079       // Now append the new list to the queue
       
  1080       if (_queue_tail != NULL) {
       
  1081         _queue_tail->set_next(new_head);
       
  1082       } else { // _queue_head == NULL
       
  1083         _queue_head = new_head;
       
  1084       }
       
  1085       _queue_tail = new_tail;
       
  1086     }
       
  1087   }
       
  1088 }