1 /*
2 * Copyright (c) 2011, 2018, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
120 const void* current_id;
121 do {
122 current_id = OrderAccess::load_ptr_acquire(&_identity);
123 } while (current_id != NULL || Atomic::cmpxchg_ptr((void*)id, &_identity, (void*)current_id) != current_id);
124 }
125
126 bool JfrBuffer::try_acquire(const void* id) {
127 assert(id != NULL, "invariant");
128 const void* const current_id = OrderAccess::load_ptr_acquire(&_identity);
129 return current_id == NULL && Atomic::cmpxchg_ptr((void*)id, &_identity, (void*)current_id) == current_id;
130 }
131
132 void JfrBuffer::release() {
133 OrderAccess::release_store_ptr(&_identity, (void*)NULL);
134 }
135
136 void JfrBuffer::clear_identity() {
137 _identity = NULL;
138 }
139
140 #ifdef ASSERT
141 static bool validate_to(const JfrBuffer* const to, size_t size) {
142 assert(to != NULL, "invariant");
143 if (!JfrRecorder::is_shutting_down()) assert(to->acquired_by_self(), "invariant");
144 assert(to->free_size() >= size, "invariant");
145 return true;
146 }
147
148 static bool validate_concurrent_this(const JfrBuffer* const t, size_t size) {
149 assert(t->top() == MUTEX_CLAIM, "invariant");
150 return true;
151 }
152
153 static bool validate_this(const JfrBuffer* const t, size_t size) {
154 assert(t->top() + size <= t->pos(), "invariant");
155 return true;
156 }
157
158 bool JfrBuffer::acquired_by_self() const {
159 return identity() == Thread::current();
160 }
161 #endif // ASSERT
162
163 void JfrBuffer::move(JfrBuffer* const to, size_t size) {
164 assert(validate_to(to, size), "invariant");
165 assert(validate_this(this, size), "invariant");
166 const u1* current_top = top();
167 assert(current_top != NULL, "invariant");
168 memcpy(to->pos(), current_top, size);
169 to->set_pos(size);
170 to->release();
171 set_top(current_top + size);
172 }
173
174 void JfrBuffer::concurrent_move_and_reinitialize(JfrBuffer* const to, size_t size) {
175 assert(validate_to(to, size), "invariant");
176 const u1* current_top = concurrent_top();
177 assert(validate_concurrent_this(this, size), "invariant");
178 const size_t actual_size = MIN2(size, (size_t)(pos() - current_top));
179 assert(actual_size <= size, "invariant");
180 memcpy(to->pos(), current_top, actual_size);
181 to->set_pos(actual_size);
182 set_pos(start());
183 to->release();
184 set_concurrent_top(start());
185 }
186
187 // flags
188 enum FLAG {
189 RETIRED = 1,
190 TRANSIENT = 2,
191 LEASE = 4
192 };
193
194 bool JfrBuffer::transient() const {
195 return (u1)TRANSIENT == (_flags & (u1)TRANSIENT);
196 }
197
198 void JfrBuffer::set_transient() {
199 _flags |= (u1)TRANSIENT;
200 assert(transient(), "invariant");
201 }
202
203 void JfrBuffer::clear_transient() {
204 if (transient()) {
205 _flags ^= (u1)TRANSIENT;
206 }
207 assert(!transient(), "invariant");
|
1 /*
2 * Copyright (c) 2011, 2019, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
120 const void* current_id;
121 do {
122 current_id = OrderAccess::load_ptr_acquire(&_identity);
123 } while (current_id != NULL || Atomic::cmpxchg_ptr((void*)id, &_identity, (void*)current_id) != current_id);
124 }
125
126 bool JfrBuffer::try_acquire(const void* id) {
127 assert(id != NULL, "invariant");
128 const void* const current_id = OrderAccess::load_ptr_acquire(&_identity);
129 return current_id == NULL && Atomic::cmpxchg_ptr((void*)id, &_identity, (void*)current_id) == current_id;
130 }
131
132 void JfrBuffer::release() {
133 OrderAccess::release_store_ptr(&_identity, (void*)NULL);
134 }
135
136 void JfrBuffer::clear_identity() {
137 _identity = NULL;
138 }
139
140 bool JfrBuffer::acquired_by(const void* id) const {
141 return identity() == id;
142 }
143
144 bool JfrBuffer::acquired_by_self() const {
145 return acquired_by(Thread::current());
146 }
147
148 #ifdef ASSERT
149 static bool validate_to(const JfrBuffer* const to, size_t size) {
150 assert(to != NULL, "invariant");
151 if (!JfrRecorder::is_shutting_down()) assert(to->acquired_by_self(), "invariant");
152 assert(to->free_size() >= size, "invariant");
153 return true;
154 }
155
156 static bool validate_concurrent_this(const JfrBuffer* const t, size_t size) {
157 assert(t->top() == MUTEX_CLAIM, "invariant");
158 return true;
159 }
160
161 static bool validate_this(const JfrBuffer* const t, size_t size) {
162 assert(t->top() + size <= t->pos(), "invariant");
163 return true;
164 }
165 #endif // ASSERT
166
167 void JfrBuffer::move(JfrBuffer* const to, size_t size) {
168 assert(validate_to(to, size), "invariant");
169 assert(validate_this(this, size), "invariant");
170 const u1* current_top = top();
171 assert(current_top != NULL, "invariant");
172 memcpy(to->pos(), current_top, size);
173 to->set_pos(size);
174 to->release();
175 set_top(current_top + size);
176 }
177
178 void JfrBuffer::concurrent_move_and_reinitialize(JfrBuffer* const to, size_t size) {
179 assert(validate_to(to, size), "invariant");
180 const u1* current_top = concurrent_top();
181 assert(validate_concurrent_this(this, size), "invariant");
182 const size_t actual_size = MIN2(size, (size_t)(pos() - current_top));
183 assert(actual_size <= size, "invariant");
184 memcpy(to->pos(), current_top, actual_size);
185 to->set_pos(actual_size);
186 set_pos(start());
187 to->release();
188 set_concurrent_top(start());
189 }
190
191 enum FLAG {
192 RETIRED = 1,
193 TRANSIENT = 2,
194 LEASE = 4
195 };
196
197 bool JfrBuffer::transient() const {
198 return (u1)TRANSIENT == (_flags & (u1)TRANSIENT);
199 }
200
201 void JfrBuffer::set_transient() {
202 _flags |= (u1)TRANSIENT;
203 assert(transient(), "invariant");
204 }
205
206 void JfrBuffer::clear_transient() {
207 if (transient()) {
208 _flags ^= (u1)TRANSIENT;
209 }
210 assert(!transient(), "invariant");
|