1 /* 2 * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "precompiled.hpp" 25 26 #include "gc/shenandoah/shenandoahHeap.inline.hpp" 27 #include "gc/shenandoah/shenandoahThreadLocalData.hpp" 28 #include "gc/shenandoah/shenandoahWorkGroup.hpp" 29 #include "gc/shenandoah/shenandoahTaskqueue.hpp" 30 31 #include "logging/log.hpp" 32 33 ShenandoahWorkerScope::ShenandoahWorkerScope(WorkGang* workers, uint nworkers, const char* msg, bool check) : 34 _workers(workers) { 35 assert(msg != NULL, "Missing message"); 36 37 _n_workers = _workers->update_active_workers(nworkers); 38 assert(_n_workers <= nworkers, "Must be"); 39 40 log_info(gc, task)("Using %u of %u workers for %s", 41 _n_workers, ShenandoahHeap::heap()->max_workers(), msg); 42 43 if (check) { 44 ShenandoahHeap::heap()->assert_gc_workers(_n_workers); 45 } 46 } 47 48 ShenandoahWorkerScope::~ShenandoahWorkerScope() { 49 assert(_workers->active_workers() == _n_workers, 50 "Active workers can not be changed within this scope"); 51 } 52 53 ShenandoahPushWorkerScope::ShenandoahPushWorkerScope(WorkGang* workers, uint nworkers, bool check) : 54 _old_workers(workers->active_workers()), 55 _workers(workers) { 56 _n_workers = _workers->update_active_workers(nworkers); 57 assert(_n_workers <= nworkers, "Must be"); 58 59 // bypass concurrent/parallel protocol check for non-regular paths, e.g. verifier, etc. 60 if (check) { 61 ShenandoahHeap::heap()->assert_gc_workers(_n_workers); 62 } 63 } 64 65 ShenandoahPushWorkerScope::~ShenandoahPushWorkerScope() { 66 assert(_workers->active_workers() == _n_workers, 67 "Active workers can not be changed within this scope"); 68 // Restore old worker value 69 uint nworkers = _workers->update_active_workers(_old_workers); 70 assert(nworkers == _old_workers, "Must be able to restore"); 71 } 72 73 ShenandoahPushWorkerQueuesScope::ShenandoahPushWorkerQueuesScope(WorkGang* workers, ShenandoahObjToScanQueueSet* queues, uint nworkers, bool check) : 74 ShenandoahPushWorkerScope(workers, nworkers, check), _queues(queues) { 75 _queues->reserve(_n_workers); 76 } 77 78 ShenandoahPushWorkerQueuesScope::~ShenandoahPushWorkerQueuesScope() { 79 // Restore old worker value 80 _queues->reserve(_old_workers); 81 } 82 83 AbstractGangWorker* ShenandoahWorkGang::install_worker(uint which) { 84 AbstractGangWorker* worker = WorkGang::install_worker(which); 85 ShenandoahThreadLocalData::create(worker); 86 if (_initialize_gclab) { 87 ShenandoahThreadLocalData::initialize_gclab(worker); 88 } 89 return worker; 90 }