mirror of
https://github.com/corda/corda.git
synced 2025-01-23 12:58:35 +00:00
use atomic operations in MyHeap::mark to avoid need for mutex
This commit is contained in:
parent
6475beda83
commit
fdde34694c
@ -325,6 +325,14 @@ markBit(uintptr_t* map, unsigned i)
|
|||||||
map[wordOf(i)] |= static_cast<uintptr_t>(1) << bitOf(i);
|
map[wordOf(i)] |= static_cast<uintptr_t>(1) << bitOf(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
markBitAtomic(uintptr_t* map, unsigned i)
|
||||||
|
{
|
||||||
|
uintptr_t* p = map + wordOf(i);
|
||||||
|
uintptr_t v = static_cast<uintptr_t>(1) << bitOf(i);
|
||||||
|
while (not __sync_bool_compare_and_swap(p, *p, *p | v)) { }
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
clearBit(uintptr_t* map, unsigned i)
|
clearBit(uintptr_t* map, unsigned i)
|
||||||
{
|
{
|
||||||
|
25
src/heap.cpp
25
src/heap.cpp
@ -303,6 +303,13 @@ class Segment {
|
|||||||
if (child) child->set(p, v);
|
if (child) child->set(p, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markAtomic(void* p) {
|
||||||
|
assert(segment->context, bitsPerRecord == 1);
|
||||||
|
markBitAtomic(data, indexOf(p));
|
||||||
|
assert(segment->context, getBit(data, indexOf(p)));
|
||||||
|
if (child) child->markAtomic(p);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned get(void* p) {
|
unsigned get(void* p) {
|
||||||
return getBits(data, bitsPerRecord, indexOf(p));
|
return getBits(data, bitsPerRecord, indexOf(p));
|
||||||
}
|
}
|
||||||
@ -1012,11 +1019,15 @@ update2(Context* c, void* o, bool* needsVisit)
|
|||||||
void
|
void
|
||||||
markDirty(Context* c, Fixie* f)
|
markDirty(Context* c, Fixie* f)
|
||||||
{
|
{
|
||||||
|
if (not f->dirty) {
|
||||||
|
ACQUIRE(c->lock);
|
||||||
|
|
||||||
if (not f->dirty) {
|
if (not f->dirty) {
|
||||||
f->dirty = true;
|
f->dirty = true;
|
||||||
f->move(c, &(c->dirtyTenuredFixies));
|
f->move(c, &(c->dirtyTenuredFixies));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
markClean(Context* c, Fixie* f)
|
markClean(Context* c, Fixie* f)
|
||||||
@ -1784,7 +1795,7 @@ class MyHeap: public Heap {
|
|||||||
Fixie(&c, sizeInWords, objectMask, 0, true))->body();
|
Fixie(&c, sizeInWords, objectMask, 0, true))->body();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool needsMark(void* p) {
|
bool needsMark(void* p) {
|
||||||
assert(&c, c.client->isFixed(p) or (not immortalHeapContains(&c, p)));
|
assert(&c, c.client->isFixed(p) or (not immortalHeapContains(&c, p)));
|
||||||
|
|
||||||
if (c.client->isFixed(p)) {
|
if (c.client->isFixed(p)) {
|
||||||
@ -1794,11 +1805,6 @@ class MyHeap: public Heap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool needsMark(void* p, unsigned offset) {
|
|
||||||
return needsMark(p) and targetNeedsMark
|
|
||||||
(mask(*(static_cast<void**>(p) + offset)));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool targetNeedsMark(void* target) {
|
bool targetNeedsMark(void* target) {
|
||||||
return target
|
return target
|
||||||
and not c.gen2.contains(target)
|
and not c.gen2.contains(target)
|
||||||
@ -1809,6 +1815,7 @@ class MyHeap: public Heap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void mark(void* p, unsigned offset, unsigned count) {
|
virtual void mark(void* p, unsigned offset, unsigned count) {
|
||||||
|
if (needsMark(p)) {
|
||||||
if (c.client->isFixed(p)) {
|
if (c.client->isFixed(p)) {
|
||||||
Fixie* f = fixie(p);
|
Fixie* f = fixie(p);
|
||||||
assert(&c, offset == 0 or f->hasMask);
|
assert(&c, offset == 0 or f->hasMask);
|
||||||
@ -1823,7 +1830,8 @@ class MyHeap: public Heap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dirty = true;
|
dirty = true;
|
||||||
markBit(f->mask(), offset + i);
|
markBitAtomic(f->mask(), offset + i);
|
||||||
|
assert(&c, getBit(f->mask(), offset + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1840,7 +1848,8 @@ class MyHeap: public Heap {
|
|||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
void** target = static_cast<void**>(p) + offset + i;
|
void** target = static_cast<void**>(p) + offset + i;
|
||||||
if (targetNeedsMark(mask(*target))) {
|
if (targetNeedsMark(mask(*target))) {
|
||||||
map->set(target);
|
map->markAtomic(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,6 @@ class Heap: public Allocator {
|
|||||||
virtual void* allocateImmortalFixed(Allocator* allocator,
|
virtual void* allocateImmortalFixed(Allocator* allocator,
|
||||||
unsigned sizeInWords, bool objectMask,
|
unsigned sizeInWords, bool objectMask,
|
||||||
unsigned* totalInBytes) = 0;
|
unsigned* totalInBytes) = 0;
|
||||||
virtual bool needsMark(void* p) = 0;
|
|
||||||
virtual bool needsMark(void* p, unsigned offset) = 0;
|
|
||||||
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
||||||
virtual void pad(void* p) = 0;
|
virtual void pad(void* p) = 0;
|
||||||
virtual void* follow(void* p) = 0;
|
virtual void* follow(void* p) = 0;
|
||||||
|
@ -1584,20 +1584,14 @@ allocate(Thread* t, unsigned sizeInBytes, bool objectMask)
|
|||||||
inline void
|
inline void
|
||||||
mark(Thread* t, object o, unsigned offset, unsigned count)
|
mark(Thread* t, object o, unsigned offset, unsigned count)
|
||||||
{
|
{
|
||||||
if (t->m->heap->needsMark(o)) {
|
|
||||||
ACQUIRE_RAW(t, t->m->heapLock);
|
|
||||||
t->m->heap->mark(o, offset / BytesPerWord, count);
|
t->m->heap->mark(o, offset / BytesPerWord, count);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
mark(Thread* t, object o, unsigned offset)
|
mark(Thread* t, object o, unsigned offset)
|
||||||
{
|
{
|
||||||
if (t->m->heap->needsMark(o, offset / BytesPerWord)) {
|
|
||||||
ACQUIRE_RAW(t, t->m->heapLock);
|
|
||||||
t->m->heap->mark(o, offset / BytesPerWord, 1);
|
t->m->heap->mark(o, offset / BytesPerWord, 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
set(Thread* t, object target, unsigned offset, object value)
|
set(Thread* t, object target, unsigned offset, object value)
|
||||||
|
Loading…
Reference in New Issue
Block a user