< prev index next >
src/share/vm/gc/g1/dirtyCardQueue.cpp
Print this page
@@ -30,10 +30,76 @@
#include "runtime/atomic.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
+// Represents a set of free small integer ids.
+class FreeIdSet : public CHeapObj<mtGC> {
+ enum {
+ end_of_list = UINT_MAX,
+ claimed = UINT_MAX - 1
+ };
+
+ uint _size;
+ Monitor* _mon;
+
+ uint* _ids;
+ uint _hd;
+ uint _waiters;
+ uint _claimed;
+
+public:
+ FreeIdSet(uint size, Monitor* mon);
+ ~FreeIdSet();
+
+ // Returns an unclaimed parallel id (waiting for one to be released if
+ // necessary).
+ uint claim_par_id();
+
+ void release_par_id(uint id);
+};
+
+FreeIdSet::FreeIdSet(uint size, Monitor* mon) :
+ _size(size), _mon(mon), _hd(0), _waiters(0), _claimed(0)
+{
+ guarantee(size != 0, "must be");
+ _ids = NEW_C_HEAP_ARRAY(uint, size, mtGC);
+ for (uint i = 0; i < size - 1; i++) {
+ _ids[i] = i+1;
+ }
+ _ids[size-1] = end_of_list; // end of list.
+}
+
+FreeIdSet::~FreeIdSet() {
+ FREE_C_HEAP_ARRAY(uint, _ids);
+}
+
+uint FreeIdSet::claim_par_id() {
+ MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
+ while (_hd == end_of_list) {
+ _waiters++;
+ _mon->wait(Mutex::_no_safepoint_check_flag);
+ _waiters--;
+ }
+ uint res = _hd;
+ _hd = _ids[res];
+ _ids[res] = claimed; // For debugging.
+ _claimed++;
+ return res;
+}
+
+void FreeIdSet::release_par_id(uint id) {
+ MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
+ assert(_ids[id] == claimed, "Precondition.");
+ _ids[id] = _hd;
+ _hd = id;
+ _claimed--;
+ if (_waiters > 0) {
+ _mon->notify_all();
+ }
+}
+
DirtyCardQueue::DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent) :
// Dirty card queues are always active, so we create them with their
// active field set to true.
PtrQueue(qset, permanent, true /* active */)
{ }
@@ -101,28 +167,31 @@
Monitor* cbl_mon,
Mutex* fl_lock,
int process_completed_threshold,
int max_completed_queue,
Mutex* lock,
- DirtyCardQueueSet* fl_owner) {
+ DirtyCardQueueSet* fl_owner,
+ bool init_free_ids) {
_mut_process_closure = cl;
PtrQueueSet::initialize(cbl_mon,
fl_lock,
process_completed_threshold,
max_completed_queue,
fl_owner);
set_buffer_size(G1UpdateBufferSize);
_shared_dirty_card_queue.set_lock(lock);
+ if (init_free_ids) {
_free_ids = new FreeIdSet(num_par_ids(), _cbl_mon);
+ }
}
void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
t->dirty_card_queue().handle_zero_index();
}
bool DirtyCardQueueSet::mut_process_buffer(void** buf) {
-
+ guarantee(_free_ids != NULL, "must be");
// Used to determine if we had already claimed a par_id
// before entering this method.
bool already_claimed = false;
// We grab the current JavaThread.
< prev index next >