equal
deleted
inserted
replaced
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "jfr/recorder/service/jfrPostBox.hpp" |
26 #include "jfr/recorder/service/jfrPostBox.hpp" |
27 #include "jfr/utilities/jfrTryLock.hpp" |
27 #include "jfr/utilities/jfrTryLock.hpp" |
28 #include "runtime/atomic.hpp" |
28 #include "runtime/atomic.hpp" |
29 #include "runtime/orderAccess.hpp" |
|
30 #include "runtime/thread.inline.hpp" |
29 #include "runtime/thread.inline.hpp" |
31 |
30 |
32 #define MSG_IS_SYNCHRONOUS ( (MSGBIT(MSG_ROTATE)) | \ |
31 #define MSG_IS_SYNCHRONOUS ( (MSGBIT(MSG_ROTATE)) | \ |
33 (MSGBIT(MSG_STOP)) | \ |
32 (MSGBIT(MSG_STOP)) | \ |
34 (MSGBIT(MSG_START)) | \ |
33 (MSGBIT(MSG_START)) | \ |
84 synchronous_post(the_message); |
83 synchronous_post(the_message); |
85 } |
84 } |
86 |
85 |
87 void JfrPostBox::deposit(int new_messages) { |
86 void JfrPostBox::deposit(int new_messages) { |
88 while (true) { |
87 while (true) { |
89 const int current_msgs = OrderAccess::load_acquire(&_messages); |
88 const int current_msgs = Atomic::load(&_messages); |
90 // OR the new message |
89 // OR the new message |
91 const int exchange_value = current_msgs | new_messages; |
90 const int exchange_value = current_msgs | new_messages; |
92 const int result = Atomic::cmpxchg(exchange_value, &_messages, current_msgs); |
91 const int result = Atomic::cmpxchg(exchange_value, &_messages, current_msgs); |
93 if (result == current_msgs) { |
92 if (result == current_msgs) { |
94 return; |
93 return; |
114 assert(!JfrMsg_lock->owned_by_self(), "should not hold JfrMsg_lock here!"); |
113 assert(!JfrMsg_lock->owned_by_self(), "should not hold JfrMsg_lock here!"); |
115 MonitorLocker msg_lock(JfrMsg_lock); |
114 MonitorLocker msg_lock(JfrMsg_lock); |
116 deposit(msg); |
115 deposit(msg); |
117 // serial_id is used to check when what we send in has been processed. |
116 // serial_id is used to check when what we send in has been processed. |
118 // _msg_read_serial is read under JfrMsg_lock protection. |
117 // _msg_read_serial is read under JfrMsg_lock protection. |
119 const uintptr_t serial_id = OrderAccess::load_acquire(&_msg_read_serial) + 1; |
118 const uintptr_t serial_id = Atomic::load(&_msg_read_serial) + 1; |
120 msg_lock.notify_all(); |
119 msg_lock.notify_all(); |
121 while (!is_message_processed(serial_id)) { |
120 while (!is_message_processed(serial_id)) { |
122 msg_lock.wait(); |
121 msg_lock.wait(); |
123 } |
122 } |
124 } |
123 } |
129 * that we are holding the JfrMsg_lock when checking |
128 * that we are holding the JfrMsg_lock when checking |
130 * completion status. |
129 * completion status. |
131 */ |
130 */ |
132 bool JfrPostBox::is_message_processed(uintptr_t serial_id) const { |
131 bool JfrPostBox::is_message_processed(uintptr_t serial_id) const { |
133 assert(JfrMsg_lock->owned_by_self(), "_msg_handled_serial must be read under JfrMsg_lock protection"); |
132 assert(JfrMsg_lock->owned_by_self(), "_msg_handled_serial must be read under JfrMsg_lock protection"); |
134 return serial_id <= OrderAccess::load_acquire(&_msg_handled_serial); |
133 return serial_id <= Atomic::load(&_msg_handled_serial); |
135 } |
134 } |
136 |
135 |
137 bool JfrPostBox::is_empty() const { |
136 bool JfrPostBox::is_empty() const { |
138 assert(JfrMsg_lock->owned_by_self(), "not holding JfrMsg_lock!"); |
137 assert(JfrMsg_lock->owned_by_self(), "not holding JfrMsg_lock!"); |
139 return OrderAccess::load_acquire(&_messages) == 0; |
138 return Atomic::load(&_messages) == 0; |
140 } |
139 } |
141 |
140 |
142 int JfrPostBox::collect() { |
141 int JfrPostBox::collect() { |
143 // get pending and reset to 0 |
142 // get pending and reset to 0 |
144 const int messages = Atomic::xchg(0, &_messages); |
143 const int messages = Atomic::xchg(0, &_messages); |