mirror of
https://github.com/corda/corda.git
synced 2025-02-26 19:25:18 +00:00
more bugfixes, mainly monitor-related
This commit is contained in:
parent
93748f2df9
commit
01d858e1bc
@ -13,7 +13,11 @@ public class TestExceptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
dangerous();
|
dangerous();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,13 @@ public class TestThreads implements Runnable {
|
|||||||
try {
|
try {
|
||||||
System.out.println("I'm running in a separate thread!");
|
System.out.println("I'm running in a separate thread!");
|
||||||
|
|
||||||
// final int arrayCount = 8;
|
final int arrayCount = 16;
|
||||||
// final int arraySize = 4;
|
final int arraySize = 4;
|
||||||
// System.out.println("Allocating and discarding " + arrayCount +
|
System.out.println("Allocating and discarding " + arrayCount +
|
||||||
// " arrays of " + arraySize + "MB each");
|
" arrays of " + arraySize + "MB each");
|
||||||
// for (; i < arrayCount; ++i) {
|
for (; i < arrayCount; ++i) {
|
||||||
// byte[] array = new byte[arraySize * 1024 * 1024];
|
byte[] array = new byte[arraySize * 1024 * 1024];
|
||||||
// }
|
}
|
||||||
|
|
||||||
long nap = 5;
|
long nap = 5;
|
||||||
System.out.println("sleeping for " + nap + " seconds");
|
System.out.println("sleeping for " + nap + " seconds");
|
||||||
|
@ -428,14 +428,6 @@ collect(Thread* t, Heap::CollectionType type)
|
|||||||
killZombies(t, m->rootThread);
|
killZombies(t, m->rootThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
removeMonitor(Thread* t, object o)
|
|
||||||
{
|
|
||||||
object p = hashMapRemove
|
|
||||||
(t, t->vm->monitorMap, o, objectHash, referenceEqual);
|
|
||||||
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
object
|
object
|
||||||
makeByteArray(Thread* t, const char* format, va_list a)
|
makeByteArray(Thread* t, const char* format, va_list a)
|
||||||
{
|
{
|
||||||
@ -606,7 +598,6 @@ Thread::dispose()
|
|||||||
|
|
||||||
if (allocator) {
|
if (allocator) {
|
||||||
allocator->free(this);
|
allocator->free(this);
|
||||||
allocator = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,6 +613,11 @@ exit(Thread* t)
|
|||||||
(t, finalizerTarget(t, f));
|
(t, finalizerTarget(t, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (object f = t->vm->tenuredFinalizers; f; f = finalizerNext(t, f)) {
|
||||||
|
reinterpret_cast<void (*)(Thread*, object)>(finalizerFinalize(t, f))
|
||||||
|
(t, finalizerTarget(t, f));
|
||||||
|
}
|
||||||
|
|
||||||
disposeAll(t, t->vm->rootThread);
|
disposeAll(t, t->vm->rootThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,13 +796,10 @@ hashMapFindNode(Thread* t, object map, object key,
|
|||||||
object array = hashMapArray(t, map);
|
object array = hashMapArray(t, map);
|
||||||
if (array) {
|
if (array) {
|
||||||
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
||||||
object n = arrayBody(t, array, index);
|
for (object n = arrayBody(t, array, index); n; n = tripleThird(t, n)) {
|
||||||
while (n) {
|
|
||||||
if (equal(t, key, tripleFirst(t, n))) {
|
if (equal(t, key, tripleFirst(t, n))) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = tripleThird(t, n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -818,34 +811,36 @@ hashMapResize(Thread* t, object map, uint32_t (*hash)(Thread*, object),
|
|||||||
{
|
{
|
||||||
PROTECT(t, map);
|
PROTECT(t, map);
|
||||||
|
|
||||||
|
object newArray = 0;
|
||||||
|
|
||||||
|
if (size) {
|
||||||
object oldArray = hashMapArray(t, map);
|
object oldArray = hashMapArray(t, map);
|
||||||
unsigned oldLength = (oldArray ? arrayLength(t, oldArray) : 0);
|
|
||||||
PROTECT(t, oldArray);
|
PROTECT(t, oldArray);
|
||||||
|
|
||||||
unsigned newLength = nextPowerOfTwo(size);
|
unsigned newLength = nextPowerOfTwo(size);
|
||||||
object newArray = makeArray(t, newLength, true);
|
newArray = makeArray(t, newLength, true);
|
||||||
|
|
||||||
if (oldArray) {
|
if (oldArray) {
|
||||||
for (unsigned i = 0; i < oldLength; ++i) {
|
for (unsigned i = 0; i < arrayLength(t, oldArray); ++i) {
|
||||||
object next;
|
object next;
|
||||||
for (object p = arrayBody(t, oldArray, i); p; p = next) {
|
for (object p = arrayBody(t, oldArray, i); p; p = next) {
|
||||||
next = tripleThird(t, p);
|
next = tripleThird(t, p);
|
||||||
|
|
||||||
object key = tripleFirst(t, p);
|
object key = tripleFirst(t, p);
|
||||||
unsigned index = hash(t, key) & (newLength - 1);
|
unsigned index = hash(t, key) & (newLength - 1);
|
||||||
object n = arrayBody(t, newArray, index);
|
|
||||||
|
|
||||||
set(t, tripleThird(t, p), n);
|
set(t, tripleThird(t, p), arrayBody(t, newArray, index));
|
||||||
set(t, arrayBody(t, newArray, index), p);
|
set(t, arrayBody(t, newArray, index), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set(t, hashMapArray(t, map), newArray);
|
set(t, hashMapArray(t, map), newArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hashMapInsert(Thread* t, object map, object key, object value,
|
hashMapInsert2(Thread* t, object map, object key, object value, uint32_t h,
|
||||||
uint32_t (*hash)(Thread*, object))
|
uint32_t (*hash)(Thread*, object))
|
||||||
{
|
{
|
||||||
object array = hashMapArray(t, map);
|
object array = hashMapArray(t, map);
|
||||||
@ -862,7 +857,7 @@ hashMapInsert(Thread* t, object map, object key, object value,
|
|||||||
array = hashMapArray(t, map);
|
array = hashMapArray(t, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
unsigned index = h & (arrayLength(t, array) - 1);
|
||||||
object n = arrayBody(t, array, index);
|
object n = arrayBody(t, array, index);
|
||||||
|
|
||||||
n = makeTriple(t, key, value, n);
|
n = makeTriple(t, key, value, n);
|
||||||
@ -870,39 +865,48 @@ hashMapInsert(Thread* t, object map, object key, object value,
|
|||||||
set(t, arrayBody(t, array, index), n);
|
set(t, arrayBody(t, array, index), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hashMapInsert(Thread* t, object map, object key, object value,
|
||||||
|
uint32_t (*hash)(Thread*, object))
|
||||||
|
{
|
||||||
|
hashMapInsert2(t, map, key, value, hash(t, key), hash);
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
hashMapRemove(Thread* t, object map, object key,
|
hashMapRemove2(Thread* t, object map, object key, uint32_t h,
|
||||||
uint32_t (*hash)(Thread*, object),
|
uint32_t (*hash)(Thread*, object),
|
||||||
bool (*equal)(Thread*, object, object))
|
bool (*equal)(Thread*, object, object))
|
||||||
{
|
{
|
||||||
object array = hashMapArray(t, map);
|
object array = hashMapArray(t, map);
|
||||||
object o = 0;
|
object o = 0;
|
||||||
if (array) {
|
if (array) {
|
||||||
unsigned index = hash(t, key) & (arrayLength(t, array) - 1);
|
unsigned index = h & (arrayLength(t, array) - 1);
|
||||||
object n = arrayBody(t, array, index);
|
for (object* n = &arrayBody(t, array, index); *n;) {
|
||||||
object p = 0;
|
if (equal(t, key, tripleFirst(t, *n))) {
|
||||||
while (n) {
|
o = tripleSecond(t, *n);
|
||||||
if (equal(t, key, tripleFirst(t, n))) {
|
set(t, *n, tripleThird(t, *n));
|
||||||
o = tripleSecond(t, n);
|
-- hashMapSize(t, map);
|
||||||
if (p) {
|
|
||||||
set(t, tripleThird(t, p), tripleThird(t, n));
|
|
||||||
} else {
|
} else {
|
||||||
set(t, arrayBody(t, array, index), tripleThird(t, n));
|
n = &tripleThird(t, *n);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p = n;
|
|
||||||
n = tripleThird(t, n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hashMapSize(t, map) <= arrayLength(t, array) / 3) {
|
if (hashMapSize(t, map) <= arrayLength(t, array) / 3) {
|
||||||
hashMapResize(t, map, hash, arrayLength(t, array) / 2);
|
hashMapResize(t, map, hash, arrayLength(t, array) / 2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
hashMapRemove(Thread* t, object map, object key,
|
||||||
|
uint32_t (*hash)(Thread*, object),
|
||||||
|
bool (*equal)(Thread*, object, object))
|
||||||
|
{
|
||||||
|
return hashMapRemove2(t, map, key, hash(t, key), hash, equal);
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
makeTrace(Thread* t, int frame)
|
makeTrace(Thread* t, int frame)
|
||||||
{
|
{
|
||||||
@ -986,6 +990,23 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
|
|||||||
(t, target, reinterpret_cast<void*>(finalize), t->vm->finalizers);
|
(t, target, reinterpret_cast<void*>(finalize), t->vm->finalizers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
removeMonitor(Thread* t, object o)
|
||||||
|
{
|
||||||
|
object p = hashMapRemove2
|
||||||
|
(t, t->vm->monitorMap, o, objectHash(t, o), referenceHash, referenceEqual);
|
||||||
|
|
||||||
|
assert(t, p);
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "dispose monitor %p for object %x\n",
|
||||||
|
static_cast<System::Monitor*>(pointerValue(t, p)),
|
||||||
|
objectHash(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
|
static_cast<System::Monitor*>(pointerValue(t, p))->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
System::Monitor*
|
System::Monitor*
|
||||||
objectMonitor(Thread* t, object o)
|
objectMonitor(Thread* t, object o)
|
||||||
{
|
{
|
||||||
@ -993,7 +1014,7 @@ objectMonitor(Thread* t, object o)
|
|||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
if (DebugMonitors) {
|
if (DebugMonitors) {
|
||||||
fprintf(stderr, "found monitor %p for object 0x%x\n",
|
fprintf(stderr, "found monitor %p for object %x\n",
|
||||||
static_cast<System::Monitor*>(pointerValue(t, p)),
|
static_cast<System::Monitor*>(pointerValue(t, p)),
|
||||||
objectHash(t, o));
|
objectHash(t, o));
|
||||||
}
|
}
|
||||||
@ -1015,7 +1036,7 @@ objectMonitor(Thread* t, object o)
|
|||||||
t->vm->weakReferences = wr;
|
t->vm->weakReferences = wr;
|
||||||
|
|
||||||
if (DebugMonitors) {
|
if (DebugMonitors) {
|
||||||
fprintf(stderr, "made monitor %p for object 0x%x\n",
|
fprintf(stderr, "made monitor %p for object %x\n",
|
||||||
m,
|
m,
|
||||||
objectHash(t, o));
|
objectHash(t, o));
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace vm {
|
|||||||
const bool Verbose = false;
|
const bool Verbose = false;
|
||||||
const bool DebugRun = false;
|
const bool DebugRun = false;
|
||||||
const bool DebugStack = false;
|
const bool DebugStack = false;
|
||||||
const bool DebugMonitors = false;
|
const bool DebugMonitors = true;
|
||||||
|
|
||||||
const uintptr_t HashTakenMark = 1;
|
const uintptr_t HashTakenMark = 1;
|
||||||
const uintptr_t ExtendedMark = 2;
|
const uintptr_t ExtendedMark = 2;
|
||||||
@ -1831,6 +1831,12 @@ inline void
|
|||||||
acquire(Thread* t, object o)
|
acquire(Thread* t, object o)
|
||||||
{
|
{
|
||||||
System::Monitor* m = objectMonitor(t, o);
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "thread %p acquires %p for %x\n",
|
||||||
|
t, m, objectHash(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
if (not m->tryAcquire(t)) {
|
if (not m->tryAcquire(t)) {
|
||||||
ENTER(t, Thread::IdleState);
|
ENTER(t, Thread::IdleState);
|
||||||
m->acquire(t);
|
m->acquire(t);
|
||||||
@ -1840,25 +1846,49 @@ acquire(Thread* t, object o)
|
|||||||
inline void
|
inline void
|
||||||
release(Thread* t, object o)
|
release(Thread* t, object o)
|
||||||
{
|
{
|
||||||
objectMonitor(t, o)->release(t);
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "thread %p releases %p for %x\n",
|
||||||
|
t, m, objectHash(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
|
m->release(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
wait(Thread* t, object o, int64_t milliseconds)
|
wait(Thread* t, object o, int64_t milliseconds)
|
||||||
{
|
{
|
||||||
System::Monitor* m = objectMonitor(t, o);
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "thread %p waits " LLD " millis on %p for %x\n",
|
||||||
|
t, milliseconds, m, objectHash(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
if (m->owner() == t) {
|
if (m->owner() == t) {
|
||||||
ENTER(t, Thread::IdleState);
|
ENTER(t, Thread::IdleState);
|
||||||
m->wait(t, milliseconds);
|
m->wait(t, milliseconds);
|
||||||
} else {
|
} else {
|
||||||
t->exception = makeIllegalMonitorStateException(t);
|
t->exception = makeIllegalMonitorStateException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "thread %p wakes up on %p for %x\n",
|
||||||
|
t, m, objectHash(t, o));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
notify(Thread* t, object o)
|
notify(Thread* t, object o)
|
||||||
{
|
{
|
||||||
System::Monitor* m = objectMonitor(t, o);
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "thread %p notifies on %p for %x\n",
|
||||||
|
t, m, objectHash(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
if (m->owner() == t) {
|
if (m->owner() == t) {
|
||||||
m->notify(t);
|
m->notify(t);
|
||||||
} else {
|
} else {
|
||||||
@ -1870,6 +1900,12 @@ inline void
|
|||||||
notifyAll(Thread* t, object o)
|
notifyAll(Thread* t, object o)
|
||||||
{
|
{
|
||||||
System::Monitor* m = objectMonitor(t, o);
|
System::Monitor* m = objectMonitor(t, o);
|
||||||
|
|
||||||
|
if (DebugMonitors) {
|
||||||
|
fprintf(stderr, "thread %p notifies all on %p for %x\n",
|
||||||
|
t, m, objectHash(t, o));
|
||||||
|
}
|
||||||
|
|
||||||
if (m->owner() == t) {
|
if (m->owner() == t) {
|
||||||
m->notifyAll(t);
|
m->notifyAll(t);
|
||||||
} else {
|
} else {
|
||||||
|
@ -139,7 +139,9 @@ class System: public vm::System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
|
if (r) {
|
||||||
r->dispose();
|
r->dispose();
|
||||||
|
}
|
||||||
s->free(this);
|
s->free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +198,9 @@ class System: public vm::System {
|
|||||||
|
|
||||||
virtual void wait(void* context, int64_t time) {
|
virtual void wait(void* context, int64_t time) {
|
||||||
if (this->context == context) {
|
if (this->context == context) {
|
||||||
|
unsigned depth = this->depth;
|
||||||
|
this->depth = 0;
|
||||||
|
this->context = 0;
|
||||||
if (time) {
|
if (time) {
|
||||||
int64_t then = now() + time;
|
int64_t then = now() + time;
|
||||||
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 };
|
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 };
|
||||||
@ -205,6 +210,8 @@ class System: public vm::System {
|
|||||||
int rv = pthread_cond_wait(&condition, &mutex);
|
int rv = pthread_cond_wait(&condition, &mutex);
|
||||||
assert(s, rv == 0);
|
assert(s, rv == 0);
|
||||||
}
|
}
|
||||||
|
this->context = context;
|
||||||
|
this->depth = depth;
|
||||||
} else {
|
} else {
|
||||||
vm::abort(s);
|
vm::abort(s);
|
||||||
}
|
}
|
||||||
@ -233,6 +240,7 @@ class System: public vm::System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
|
assert(s, context == 0);
|
||||||
pthread_mutex_destroy(&mutex);
|
pthread_mutex_destroy(&mutex);
|
||||||
pthread_cond_destroy(&condition);
|
pthread_cond_destroy(&condition);
|
||||||
s->free(this);
|
s->free(this);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user